quot.c revision 30262
1290931Srodrigc/* 2290931Srodrigc * Copyright (C) 1991, 1994 Wolfgang Solfrank. 3290931Srodrigc * Copyright (C) 1991, 1994 TooLs GmbH. 4290931Srodrigc * All rights reserved. 5290931Srodrigc * 6290931Srodrigc * Redistribution and use in source and binary forms, with or without 7290931Srodrigc * modification, are permitted provided that the following conditions 8290931Srodrigc * are met: 9290931Srodrigc * 1. Redistributions of source code must retain the above copyright 10290931Srodrigc * notice, this list of conditions and the following disclaimer. 11290931Srodrigc * 2. Redistributions in binary form must reproduce the above copyright 12290931Srodrigc * notice, this list of conditions and the following disclaimer in the 13290931Srodrigc * documentation and/or other materials provided with the distribution. 14290931Srodrigc * 3. All advertising materials mentioning features or use of this software 15290931Srodrigc * must display the following acknowledgement: 16290931Srodrigc * This product includes software developed by TooLs GmbH. 17290931Srodrigc * 4. The name of TooLs GmbH may not be used to endorse or promote products 18290931Srodrigc * derived from this software without specific prior written permission. 19290931Srodrigc * 20290937Srodrigc * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 21290931Srodrigc * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 22290931Srodrigc * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 23290931Srodrigc * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24290931Srodrigc * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25290931Srodrigc * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26290931Srodrigc * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27290931Srodrigc * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28290931Srodrigc * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29290931Srodrigc * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30290931Srodrigc */ 31290931Srodrigc 32290931Srodrigc#ifndef lint 33290931Srodrigcstatic const char rcsid[] = 34290931Srodrigc "$Id: quot.c,v 1.6 1997/08/13 12:09:48 jkh Exp $"; 35290931Srodrigc#endif /* not lint */ 36290931Srodrigc 37290931Srodrigc#include <sys/param.h> 38290931Srodrigc#include <sys/mount.h> 39290931Srodrigc#include <sys/time.h> 40290931Srodrigc#include <ufs/ffs/fs.h> 41290931Srodrigc#include <ufs/ufs/quota.h> 42290931Srodrigc#include <ufs/ufs/inode.h> 43290931Srodrigc 44290931Srodrigc#include <err.h> 45290931Srodrigc#include <fcntl.h> 46290931Srodrigc#include <errno.h> 47290931Srodrigc#include <pwd.h> 48290931Srodrigc#include <stdio.h> 49290931Srodrigc#include <stdlib.h> 50290931Srodrigc#include <string.h> 51290931Srodrigc#include <unistd.h> 52290931Srodrigc 53290931Srodrigc/* some flags of what to do: */ 54290931Srodrigcstatic char estimate; 55290931Srodrigcstatic char count; 56290931Srodrigcstatic char unused; 57290931Srodrigcstatic void (*func)(); 58290931Srodrigcstatic long blocksize; 59290931Srodrigcstatic char *header; 60290931Srodrigcstatic int headerlen; 61290931Srodrigc 62290931Srodrigc/* 63290931Srodrigc * Original BSD quot doesn't round to number of frags/blocks, 64290931Srodrigc * doesn't account for indirection blocks and gets it totally 65290931Srodrigc * wrong if the size is a multiple of the blocksize. 66290931Srodrigc * The new code always counts the number of 512 byte blocks 67290931Srodrigc * instead of the number of kilobytes and converts them to 68290931Srodrigc * kByte when done (on request). 69290931Srodrigc */ 70290931Srodrigc#ifdef COMPAT 71290931Srodrigc#define SIZE(n) (n) 72290931Srodrigc#else 73290931Srodrigc#define SIZE(n) (((n) * 512 + blocksize - 1)/blocksize) 74290931Srodrigc#endif 75290931Srodrigc 76290931Srodrigc#define INOCNT(fs) ((fs)->fs_ipg) 77290931Srodrigc#define INOSZ(fs) (sizeof(struct dinode) * INOCNT(fs)) 78290931Srodrigc 79290931Srodrigcstatic struct dinode * 80290931Srodrigcget_inode(fd,super,ino) 81290931Srodrigc struct fs *super; 82290931Srodrigc ino_t ino; 83290931Srodrigc{ 84290931Srodrigc static struct dinode *ip; 85290931Srodrigc static ino_t last; 86290931Srodrigc 87290931Srodrigc if (fd < 0) { /* flush cache */ 88290931Srodrigc if (ip) { 89290931Srodrigc free(ip); 90290931Srodrigc ip = 0; 91290931Srodrigc } 92290931Srodrigc return 0; 93290931Srodrigc } 94290931Srodrigc 95290931Srodrigc if (!ip || ino < last || ino >= last + INOCNT(super)) { 96290931Srodrigc if (!ip 97290931Srodrigc && !(ip = (struct dinode *)malloc(INOSZ(super)))) 98290931Srodrigc errx(1, "allocate inodes"); 99290931Srodrigc last = (ino / INOCNT(super)) * INOCNT(super); 100290931Srodrigc if (lseek(fd, (off_t)ino_to_fsba(super, last) << super->fs_fshift, 0) < (off_t)0 101290931Srodrigc || read(fd,ip,INOSZ(super)) != INOSZ(super)) 102290931Srodrigc err(1, "read inodes"); 103290931Srodrigc } 104290931Srodrigc 105290931Srodrigc return ip + ino % INOCNT(super); 106290931Srodrigc} 107290931Srodrigc 108290931Srodrigc#ifdef COMPAT 109290931Srodrigc#define actualblocks(super,ip) ((ip)->di_blocks/2) 110290931Srodrigc#else 111290931Srodrigc#define actualblocks(super,ip) ((ip)->di_blocks) 112290931Srodrigc#endif 113290931Srodrigc 114290931Srodrigcstatic int virtualblocks(super,ip) 115290931Srodrigc struct fs *super; 116290931Srodrigc struct dinode *ip; 117290931Srodrigc{ 118290931Srodrigc register off_t nblk, sz; 119290931Srodrigc 120290931Srodrigc sz = ip->di_size; 121290931Srodrigc#ifdef COMPAT 122290931Srodrigc if (lblkno(super,sz) >= NDADDR) { 123290931Srodrigc nblk = blkroundup(super,sz); 124290931Srodrigc if (sz == nblk) 125290931Srodrigc nblk += super->fs_bsize; 126290931Srodrigc } 127290931Srodrigc 128290931Srodrigc return sz / 1024; 129290931Srodrigc 130290931Srodrigc#else /* COMPAT */ 131290931Srodrigc 132290931Srodrigc if (lblkno(super,sz) >= NDADDR) { 133290931Srodrigc nblk = blkroundup(super,sz); 134290931Srodrigc sz = lblkno(super,nblk); 135290931Srodrigc sz = (sz - NDADDR + NINDIR(super) - 1) / NINDIR(super); 136290931Srodrigc while (sz > 0) { 137290931Srodrigc nblk += sz * super->fs_bsize; 138290931Srodrigc /* sz - 1 rounded up */ 139290931Srodrigc sz = (sz - 1 + NINDIR(super) - 1) / NINDIR(super); 140290931Srodrigc } 141290931Srodrigc } else 142290931Srodrigc nblk = fragroundup(super,sz); 143290931Srodrigc 144290931Srodrigc return nblk / 512; 145290931Srodrigc#endif /* COMPAT */ 146290931Srodrigc} 147290931Srodrigc 148290931Srodrigcstatic int 149290931Srodrigcisfree(ip) 150290931Srodrigc struct dinode *ip; 151290931Srodrigc{ 152290931Srodrigc#ifdef COMPAT 153290931Srodrigc return (ip->di_mode&IFMT) == 0; 154290931Srodrigc#else /* COMPAT */ 155290931Srodrigc 156290931Srodrigc switch (ip->di_mode&IFMT) { 157290931Srodrigc case IFIFO: 158290931Srodrigc case IFLNK: /* should check FASTSYMLINK? */ 159290931Srodrigc case IFDIR: 160290931Srodrigc case IFREG: 161290931Srodrigc return 0; 162290931Srodrigc default: 163290931Srodrigc return 1; 164290931Srodrigc } 165290931Srodrigc#endif 166290931Srodrigc} 167290931Srodrigc 168290931Srodrigcstatic struct user { 169290931Srodrigc uid_t uid; 170290931Srodrigc char *name; 171290931Srodrigc daddr_t space; 172290931Srodrigc long count; 173290931Srodrigc daddr_t spc30; 174290931Srodrigc daddr_t spc60; 175290931Srodrigc daddr_t spc90; 176290931Srodrigc} *users; 177290931Srodrigcstatic int nusers; 178290931Srodrigc 179290931Srodrigcstatic void 180290931Srodrigcinituser() 181290931Srodrigc{ 182290931Srodrigc register i; 183290931Srodrigc register struct user *usr; 184290931Srodrigc 185290931Srodrigc if (!nusers) { 186290931Srodrigc nusers = 8; 187290931Srodrigc if (!(users = 188290931Srodrigc (struct user *)calloc(nusers,sizeof(struct user)))) 189290931Srodrigc errx(1, "allocate users"); 190290931Srodrigc } else { 191290931Srodrigc for (usr = users, i = nusers; --i >= 0; usr++) { 192290931Srodrigc usr->space = usr->spc30 = usr->spc60 = usr->spc90 = 0; 193290931Srodrigc usr->count = 0; 194290931Srodrigc } 195290931Srodrigc } 196290931Srodrigc} 197290931Srodrigc 198290931Srodrigcstatic void 199290931Srodrigcusrrehash() 200290931Srodrigc{ 201290931Srodrigc register i; 202290931Srodrigc register struct user *usr, *usrn; 203290931Srodrigc struct user *svusr; 204290931Srodrigc 205290931Srodrigc svusr = users; 206290931Srodrigc nusers <<= 1; 207290931Srodrigc if (!(users = (struct user *)calloc(nusers,sizeof(struct user)))) 208290931Srodrigc errx(1, "allocate users"); 209290931Srodrigc for (usr = svusr, i = nusers >> 1; --i >= 0; usr++) { 210290931Srodrigc for (usrn = users + (usr->uid&(nusers - 1)); usrn->name; 211290931Srodrigc usrn--) { 212290931Srodrigc if (usrn <= users) 213290931Srodrigc usrn = users + nusers; 214290931Srodrigc } 215290931Srodrigc *usrn = *usr; 216290931Srodrigc } 217290931Srodrigc} 218290931Srodrigc 219290931Srodrigcstatic struct user * 220290931Srodrigcuser(uid) 221290931Srodrigc uid_t uid; 222290931Srodrigc{ 223290931Srodrigc register struct user *usr; 224290931Srodrigc register i; 225290931Srodrigc struct passwd *pwd; 226290931Srodrigc 227290931Srodrigc while (1) { 228290931Srodrigc for (usr = users + (uid&(nusers - 1)), i = nusers; --i >= 0; 229290931Srodrigc usr--) { 230290931Srodrigc if (!usr->name) { 231290931Srodrigc usr->uid = uid; 232290931Srodrigc 233290931Srodrigc if (!(pwd = getpwuid(uid))) { 234290931Srodrigc if ((usr->name = (char *)malloc(7))) 235290931Srodrigc sprintf(usr->name,"#%d",uid); 236290931Srodrigc } else { 237290931Srodrigc if ((usr->name = (char *) 238290931Srodrigc malloc(strlen(pwd->pw_name) + 1))) 239290931Srodrigc strcpy(usr->name,pwd->pw_name); 240290931Srodrigc } 241290931Srodrigc if (!usr->name) 242290931Srodrigc errx(1, "allocate users"); 243290931Srodrigc 244290931Srodrigc return usr; 245290931Srodrigc 246290931Srodrigc } else if (usr->uid == uid) 247290931Srodrigc return usr; 248290931Srodrigc 249290931Srodrigc if (usr <= users) 250290931Srodrigc usr = users + nusers; 251290931Srodrigc } 252290931Srodrigc usrrehash(); 253290931Srodrigc } 254290931Srodrigc} 255290931Srodrigc 256290931Srodrigcstatic int 257290931Srodrigccmpusers(u1,u2) 258290931Srodrigc struct user *u1, *u2; 259290931Srodrigc{ 260290931Srodrigc return u2->space - u1->space; 261290931Srodrigc} 262290931Srodrigc 263290931Srodrigc#define sortusers(users) (qsort((users),nusers,sizeof(struct user), \ 264290931Srodrigc cmpusers)) 265290931Srodrigc 266290931Srodrigcstatic void 267290931Srodrigcuses(uid,blks,act) 268290931Srodrigc uid_t uid; 269290931Srodrigc daddr_t blks; 270290931Srodrigc time_t act; 271290931Srodrigc{ 272290931Srodrigc static time_t today; 273290931Srodrigc register struct user *usr; 274290931Srodrigc 275290931Srodrigc if (!today) 276290931Srodrigc time(&today); 277290931Srodrigc 278290931Srodrigc usr = user(uid); 279290931Srodrigc usr->count++; 280290931Srodrigc usr->space += blks; 281290931Srodrigc 282290931Srodrigc if (today - act > 90L * 24L * 60L * 60L) 283290931Srodrigc usr->spc90 += blks; 284290931Srodrigc if (today - act > 60L * 24L * 60L * 60L) 285290931Srodrigc usr->spc60 += blks; 286290931Srodrigc if (today - act > 30L * 24L * 60L * 60L) 287290931Srodrigc usr->spc30 += blks; 288290931Srodrigc} 289290931Srodrigc 290290931Srodrigc#ifdef COMPAT 291290931Srodrigc#define FSZCNT 500 292290931Srodrigc#else 293290931Srodrigc#define FSZCNT 512 294290931Srodrigc#endif 295290931Srodrigcstruct fsizes { 296290931Srodrigc struct fsizes *fsz_next; 297290931Srodrigc daddr_t fsz_first, fsz_last; 298290931Srodrigc ino_t fsz_count[FSZCNT]; 299290931Srodrigc daddr_t fsz_sz[FSZCNT]; 300290931Srodrigc} *fsizes; 301290931Srodrigc 302290931Srodrigcstatic void 303290931Srodrigcinitfsizes() 304290931Srodrigc{ 305290931Srodrigc register struct fsizes *fp; 306290931Srodrigc register i; 307290931Srodrigc 308290931Srodrigc for (fp = fsizes; fp; fp = fp->fsz_next) { 309290931Srodrigc for (i = FSZCNT; --i >= 0;) { 310290931Srodrigc fp->fsz_count[i] = 0; 311290931Srodrigc fp->fsz_sz[i] = 0; 312290931Srodrigc } 313290931Srodrigc } 314290931Srodrigc} 315290931Srodrigc 316290931Srodrigcstatic void 317290931Srodrigcdofsizes(fd,super,name) 318290931Srodrigc struct fs *super; 319290931Srodrigc char *name; 320290931Srodrigc{ 321290931Srodrigc ino_t inode, maxino; 322290931Srodrigc struct dinode *ip; 323290931Srodrigc daddr_t sz, ksz; 324290931Srodrigc struct fsizes *fp, **fsp; 325290931Srodrigc register i; 326290931Srodrigc 327290931Srodrigc maxino = super->fs_ncg * super->fs_ipg - 1; 328290931Srodrigc#ifdef COMPAT 329290931Srodrigc if (!(fsizes = (struct fsizes *)malloc(sizeof(struct fsizes)))) 330290931Srodrigc errx(1, "alloc fsize structure"); 331290931Srodrigc#endif /* COMPAT */ 332290931Srodrigc for (inode = 0; inode < maxino; inode++) { 333290931Srodrigc errno = 0; 334290931Srodrigc if ((ip = get_inode(fd,super,inode)) 335290931Srodrigc#ifdef COMPAT 336290931Srodrigc && ((ip->di_mode&IFMT) == IFREG 337290931Srodrigc || (ip->di_mode&IFMT) == IFDIR) 338290931Srodrigc#else /* COMPAT */ 339290931Srodrigc && !isfree(ip) 340290931Srodrigc#endif /* COMPAT */ 341290931Srodrigc ) { 342290931Srodrigc sz = estimate ? virtualblocks(super,ip) : 343290931Srodrigc actualblocks(super,ip); 344290931Srodrigc#ifdef COMPAT 345290931Srodrigc if (sz >= FSZCNT) { 346290931Srodrigc fsizes->fsz_count[FSZCNT-1]++; 347290931Srodrigc fsizes->fsz_sz[FSZCNT-1] += sz; 348290931Srodrigc } else { 349290931Srodrigc fsizes->fsz_count[sz]++; 350290931Srodrigc fsizes->fsz_sz[sz] += sz; 351290931Srodrigc } 352290931Srodrigc#else /* COMPAT */ 353290931Srodrigc ksz = SIZE(sz); 354290931Srodrigc for (fsp = &fsizes; (fp = *fsp); fsp = &fp->fsz_next) { 355290931Srodrigc if (ksz < fp->fsz_last) 356290931Srodrigc break; 357290931Srodrigc } 358290931Srodrigc if (!fp || ksz < fp->fsz_first) { 359290931Srodrigc if (!(fp = (struct fsizes *) 360290931Srodrigc malloc(sizeof(struct fsizes)))) 361290931Srodrigc errx(1, "alloc fsize structure"); 362290931Srodrigc fp->fsz_next = *fsp; 363290931Srodrigc *fsp = fp; 364290931Srodrigc fp->fsz_first = (ksz / FSZCNT) * FSZCNT; 365290931Srodrigc fp->fsz_last = fp->fsz_first + FSZCNT; 366290931Srodrigc for (i = FSZCNT; --i >= 0;) { 367290931Srodrigc fp->fsz_count[i] = 0; 368290931Srodrigc fp->fsz_sz[i] = 0; 369290931Srodrigc } 370290931Srodrigc } 371290931Srodrigc fp->fsz_count[ksz % FSZCNT]++; 372290931Srodrigc fp->fsz_sz[ksz % FSZCNT] += sz; 373290931Srodrigc#endif /* COMPAT */ 374290931Srodrigc } else if (errno) { 375290931Srodrigc err(1, "%s", name); 376290931Srodrigc } 377290931Srodrigc } 378290931Srodrigc sz = 0; 379290931Srodrigc for (fp = fsizes; fp; fp = fp->fsz_next) { 380290931Srodrigc for (i = 0; i < FSZCNT; i++) { 381290931Srodrigc if (fp->fsz_count[i]) 382290931Srodrigc printf("%d\t%d\t%d\n",fp->fsz_first + i, 383290931Srodrigc fp->fsz_count[i], 384290931Srodrigc SIZE(sz += fp->fsz_sz[i])); 385290931Srodrigc } 386290931Srodrigc } 387290931Srodrigc} 388290931Srodrigc 389290931Srodrigcstatic void 390290931Srodrigcdouser(fd,super,name) 391290931Srodrigc struct fs *super; 392290931Srodrigc char *name; 393290931Srodrigc{ 394290931Srodrigc ino_t inode, maxino; 395290931Srodrigc struct user *usr, *usrs; 396290931Srodrigc struct dinode *ip; 397290931Srodrigc register n; 398290931Srodrigc 399290931Srodrigc maxino = super->fs_ncg * super->fs_ipg - 1; 400290931Srodrigc for (inode = 0; inode < maxino; inode++) { 401290931Srodrigc errno = 0; 402290931Srodrigc if ((ip = get_inode(fd,super,inode)) 403290931Srodrigc && !isfree(ip)) 404290931Srodrigc uses(ip->di_uid, 405290931Srodrigc estimate ? virtualblocks(super,ip) : 406290931Srodrigc actualblocks(super,ip), 407290931Srodrigc ip->di_atime); 408290931Srodrigc else if (errno) { 409290931Srodrigc err(1, "%s", name); 410290931Srodrigc } 411290931Srodrigc } 412290931Srodrigc if (!(usrs = (struct user *)malloc(nusers * sizeof(struct user)))) 413290931Srodrigc errx(1, "allocate users"); 414290931Srodrigc bcopy(users,usrs,nusers * sizeof(struct user)); 415290931Srodrigc sortusers(usrs); 416290931Srodrigc for (usr = usrs, n = nusers; --n >= 0 && usr->count; usr++) { 417290931Srodrigc printf("%5d",SIZE(usr->space)); 418290931Srodrigc if (count) 419290931Srodrigc printf("\t%5d",usr->count); 420290931Srodrigc printf("\t%-8s",usr->name); 421290931Srodrigc if (unused) 422290931Srodrigc printf("\t%5d\t%5d\t%5d", 423290931Srodrigc SIZE(usr->spc30), 424290931Srodrigc SIZE(usr->spc60), 425290931Srodrigc SIZE(usr->spc90)); 426290931Srodrigc printf("\n"); 427290931Srodrigc } 428290931Srodrigc free(usrs); 429290931Srodrigc} 430290931Srodrigc 431290931Srodrigcstatic void 432290931Srodrigcdonames(fd,super,name) 433290931Srodrigc struct fs *super; 434290931Srodrigc char *name; 435290931Srodrigc{ 436290931Srodrigc int c; 437290931Srodrigc ino_t inode, inode1; 438290931Srodrigc ino_t maxino; 439290931Srodrigc struct dinode *ip; 440290931Srodrigc 441290931Srodrigc maxino = super->fs_ncg * super->fs_ipg - 1; 442290931Srodrigc /* first skip the name of the filesystem */ 443290931Srodrigc while ((c = getchar()) != EOF && (c < '0' || c > '9')) 444290931Srodrigc while ((c = getchar()) != EOF && c != '\n'); 445290931Srodrigc ungetc(c,stdin); 446290931Srodrigc inode1 = -1; 447290931Srodrigc while (scanf("%d",&inode) == 1) { 448290931Srodrigc if (inode < 0 || inode > maxino) { 449290931Srodrigc warnx("illegal inode %d",inode); 450290931Srodrigc return; 451290931Srodrigc } 452290931Srodrigc errno = 0; 453290931Srodrigc if ((ip = get_inode(fd,super,inode)) 454290931Srodrigc && !isfree(ip)) { 455290931Srodrigc printf("%s\t",user(ip->di_uid)->name); 456290931Srodrigc /* now skip whitespace */ 457290931Srodrigc while ((c = getchar()) == ' ' || c == '\t'); 458290931Srodrigc /* and print out the remainder of the input line */ 459290931Srodrigc while (c != EOF && c != '\n') { 460290931Srodrigc putchar(c); 461290931Srodrigc c = getchar(); 462290931Srodrigc } 463290931Srodrigc putchar('\n'); 464290931Srodrigc inode1 = inode; 465290931Srodrigc } else { 466290931Srodrigc if (errno) { 467290931Srodrigc err(1, "%s", name); 468290931Srodrigc } 469290931Srodrigc /* skip this line */ 470290931Srodrigc while ((c = getchar()) != EOF && c != '\n'); 471290931Srodrigc } 472290931Srodrigc if (c == EOF) 473290931Srodrigc break; 474290931Srodrigc } 475290931Srodrigc} 476290931Srodrigc 477290931Srodrigcstatic void 478290931Srodrigcusage() 479290931Srodrigc{ 480290931Srodrigc#ifdef COMPAT 481290931Srodrigc fprintf(stderr,"usage: quot [-nfcvha] [filesystem ...]\n"); 482290931Srodrigc#else /* COMPAT */ 483290931Srodrigc fprintf(stderr,"usage: quot [-acfhknv] [ filesystem ... ]\n"); 484290931Srodrigc#endif /* COMPAT */ 485290931Srodrigc exit(1); 486290931Srodrigc} 487290931Srodrigc 488290931Srodrigcstatic char superblock[SBSIZE]; 489290931Srodrigc 490290931Srodrigcvoid 491290931Srodrigcquot(name,mp) 492290931Srodrigc char *name, *mp; 493290931Srodrigc{ 494290931Srodrigc int fd; 495290931Srodrigc 496290931Srodrigc get_inode(-1); /* flush cache */ 497290931Srodrigc inituser(); 498290931Srodrigc initfsizes(); 499290931Srodrigc if ((fd = open(name,0)) < 0 500290931Srodrigc || lseek(fd,SBOFF,0) != SBOFF 501290931Srodrigc || read(fd,superblock,SBSIZE) != SBSIZE) { 502290931Srodrigc warn("%s", name); 503290931Srodrigc close(fd); 504290931Srodrigc return; 505290931Srodrigc } 506290931Srodrigc if (((struct fs *)superblock)->fs_magic != FS_MAGIC) { 507290931Srodrigc warnx("%s: not a BSD filesystem",name); 508290931Srodrigc close(fd); 509290931Srodrigc return; 510290931Srodrigc } 511290931Srodrigc printf("%s:",name); 512290931Srodrigc if (mp) 513290931Srodrigc printf(" (%s)",mp); 514290931Srodrigc putchar('\n'); 515290931Srodrigc (*func)(fd,superblock,name); 516290931Srodrigc close(fd); 517290931Srodrigc} 518290931Srodrigc 519290931Srodrigcint 520290931Srodrigcmain(argc,argv) 521290931Srodrigc char **argv; 522290931Srodrigc{ 523290931Srodrigc char all = 0; 524290931Srodrigc struct statfs *mp; 525290931Srodrigc struct vfsconf *vfsp; 526290931Srodrigc char dev[MNAMELEN + 1]; 527290931Srodrigc char *nm; 528290931Srodrigc int cnt; 529290931Srodrigc 530290931Srodrigc func = douser; 531290931Srodrigc#ifndef COMPAT 532290931Srodrigc header = getbsize(&headerlen,&blocksize); 533290931Srodrigc#endif 534290931Srodrigc while (--argc > 0 && **++argv == '-') { 535290931Srodrigc while (*++*argv) { 536290931Srodrigc switch (**argv) { 537290931Srodrigc case 'n': 538290931Srodrigc func = donames; 539290931Srodrigc break; 540290931Srodrigc case 'c': 541290931Srodrigc func = dofsizes; 542290931Srodrigc break; 543290931Srodrigc case 'a': 544290931Srodrigc all = 1; 545290931Srodrigc break; 546290931Srodrigc case 'f': 547290931Srodrigc count = 1; 548290931Srodrigc break; 549290931Srodrigc case 'h': 550290931Srodrigc estimate = 1; 551290931Srodrigc break; 552290931Srodrigc#ifndef COMPAT 553290931Srodrigc case 'k': 554290931Srodrigc blocksize = 1024; 555290931Srodrigc break; 556290931Srodrigc#endif /* COMPAT */ 557290931Srodrigc case 'v': 558290931Srodrigc unused = 1; 559290931Srodrigc break; 560290931Srodrigc default: 561290931Srodrigc usage(); 562290931Srodrigc } 563290931Srodrigc } 564290931Srodrigc } 565290931Srodrigc if (all) { 566290931Srodrigc cnt = getmntinfo(&mp,MNT_NOWAIT); 567290931Srodrigc vfsp = getvfsbyname("ufs"); 568290931Srodrigc if (vfsp == NULL) 569290931Srodrigc errx(1, "cannot find ufs/ffs filesystem type!"); 570290931Srodrigc for (; --cnt >= 0; mp++) { 571290931Srodrigc if (mp->f_type == vfsp->vfc_index) { 572290931Srodrigc if ((nm = strrchr(mp->f_mntfromname,'/'))) { 573290931Srodrigc sprintf(dev,"/dev/r%s",nm + 1); 574290931Srodrigc nm = dev; 575290931Srodrigc } else 576290931Srodrigc nm = mp->f_mntfromname; 577290931Srodrigc quot(nm,mp->f_mntonname); 578290931Srodrigc } 579290931Srodrigc } 580290931Srodrigc } 581290931Srodrigc while (--argc >= 0) 582290931Srodrigc quot(*argv++,0); 583290931Srodrigc return 0; 584290931Srodrigc} 585290931Srodrigc