quot.c revision 144841
117721Speter/* 217721Speter * Copyright (C) 1991, 1994 Wolfgang Solfrank. 317721Speter * Copyright (C) 1991, 1994 TooLs GmbH. 417721Speter * All rights reserved. 517721Speter * 617721Speter * Redistribution and use in source and binary forms, with or without 717721Speter * modification, are permitted provided that the following conditions 817721Speter * are met: 917721Speter * 1. Redistributions of source code must retain the above copyright 1017721Speter * notice, this list of conditions and the following disclaimer. 1117721Speter * 2. Redistributions in binary form must reproduce the above copyright 1217721Speter * notice, this list of conditions and the following disclaimer in the 1317721Speter * documentation and/or other materials provided with the distribution. 1417721Speter * 3. All advertising materials mentioning features or use of this software 1525839Speter * must display the following acknowledgement: 1617721Speter * This product includes software developed by TooLs GmbH. 1725839Speter * 4. The name of TooLs GmbH may not be used to endorse or promote products 1825839Speter * derived from this software without specific prior written permission. 1925839Speter * 2025839Speter * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 2125839Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2225839Speter * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2325839Speter * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2425839Speter * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2525839Speter * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2617721Speter * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2717721Speter * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2817721Speter * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 2917721Speter * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3017721Speter */ 3117721Speter 3217721Speter#include <sys/cdefs.h> 3325839Speter__FBSDID("$FreeBSD: head/usr.sbin/quot/quot.c 144841 2005-04-09 14:59:10Z stefanf $"); 3425839Speter 3525839Speter#include <sys/param.h> 3625839Speter#include <sys/stdint.h> 3717721Speter#include <sys/mount.h> 3817721Speter#include <sys/disklabel.h> 3917721Speter#include <sys/time.h> 4017721Speter#include <ufs/ufs/dinode.h> 4117721Speter#include <ufs/ffs/fs.h> 4217721Speter 4317721Speter#include <err.h> 4417721Speter#include <fcntl.h> 4517721Speter#include <fstab.h> 4625839Speter#include <errno.h> 4717721Speter#include <paths.h> 4825839Speter#include <pwd.h> 4917721Speter#include <stdio.h> 5017721Speter#include <stdlib.h> 5117721Speter#include <string.h> 5217721Speter#include <unistd.h> 5325839Speter 5425839Speter/* some flags of what to do: */ 5517721Speterstatic char estimate; 5617721Speterstatic char count; 5717721Speterstatic char unused; 5817721Speterstatic void (*func)(int, struct fs *, char *); 5917721Speterstatic long blocksize; 6017721Speterstatic char *header; 6117721Speterstatic int headerlen; 6217721Speter 6317721Speterstatic union dinode *get_inode(int, struct fs *, ino_t); 6425839Speterstatic int virtualblocks(struct fs *, union dinode *); 6517721Speterstatic int isfree(struct fs *, union dinode *); 6617721Speterstatic void inituser(void); 6725839Speterstatic void usrrehash(void); 6825839Speterstatic struct user *user(uid_t); 6917721Speterstatic int cmpusers(const void *, const void *); 7017721Speterstatic void uses(uid_t, daddr_t, time_t); 7117721Speterstatic void initfsizes(void); 7217721Speterstatic void dofsizes(int, struct fs *, char *); 7317721Speterstatic void douser(int, struct fs *, char *); 7417721Speterstatic void donames(int, struct fs *, char *); 7517721Speterstatic void usage(void); 7617721Speterstatic void quot(char *, char *); 7725839Speter 7817721Speter/* 7925839Speter * Original BSD quot doesn't round to number of frags/blocks, 8025839Speter * doesn't account for indirection blocks and gets it totally 8117721Speter * wrong if the size is a multiple of the blocksize. 8217721Speter * The new code always counts the number of 512 byte blocks 8317721Speter * instead of the number of kilobytes and converts them to 8425839Speter * kByte when done (on request). 8525839Speter * 8617721Speter * Due to the size of modern disks, we must cast intermediate 8717721Speter * values to 64 bits to prevent potential overflows. 8817721Speter */ 8917721Speter#ifdef COMPAT 9017721Speter#define SIZE(n) (n) 9117721Speter#else 9217721Speter#define SIZE(n) ((int)(((quad_t)(n) * 512 + blocksize - 1)/blocksize)) 9325839Speter#endif 9417721Speter 9517721Speter#define INOCNT(fs) ((fs)->fs_ipg) 9625839Speter#define INOSZ(fs) \ 9717721Speter (((fs)->fs_magic == FS_UFS1_MAGIC ? sizeof(struct ufs1_dinode) : \ 9825839Speter sizeof(struct ufs2_dinode)) * INOCNT(fs)) 9925839Speter 10025839Speterunion dinode { 10117721Speter struct ufs1_dinode dp1; 10217721Speter struct ufs2_dinode dp2; 10317721Speter}; 10417721Speter#define DIP(fs, dp, field) \ 10517721Speter (((fs)->fs_magic == FS_UFS1_MAGIC) ? \ 10625839Speter (dp)->dp1.field : (dp)->dp2.field) 10725839Speter 10817721Speterstatic union dinode * 10917721Speterget_inode(fd,super,ino) 11017721Speter int fd; 11117721Speter struct fs *super; 11217721Speter ino_t ino; 11317721Speter{ 11417721Speter static caddr_t ipbuf; 11517721Speter static ino_t last; 11617721Speter 11717721Speter if (fd < 0) { /* flush cache */ 11817721Speter if (ipbuf) { 11917721Speter free(ipbuf); 12025839Speter ipbuf = 0; 12125839Speter } 12217721Speter return 0; 12317721Speter } 12417721Speter 12525839Speter if (!ipbuf || ino < last || ino >= last + INOCNT(super)) { 12617721Speter if (!ipbuf 12725839Speter && !(ipbuf = malloc(INOSZ(super)))) 12825839Speter errx(1, "allocate inodes"); 12925839Speter last = (ino / INOCNT(super)) * INOCNT(super); 13025839Speter if (lseek(fd, (off_t)ino_to_fsba(super, last) << super->fs_fshift, 0) < (off_t)0 13125839Speter || read(fd, ipbuf, INOSZ(super)) != (ssize_t)INOSZ(super)) 13217721Speter err(1, "read inodes"); 13317721Speter } 13417721Speter 13517721Speter if (super->fs_magic == FS_UFS1_MAGIC) 13617721Speter return ((union dinode *) 13717721Speter &((struct ufs1_dinode *)ipbuf)[ino % INOCNT(super)]); 13817721Speter return ((union dinode *) 13917721Speter &((struct ufs2_dinode *)ipbuf)[ino % INOCNT(super)]); 14017721Speter} 14117721Speter 14217721Speter#ifdef COMPAT 14317721Speter#define actualblocks(fs, dp) (DIP(fs, dp, di_blocks) / 2) 14417721Speter#else 14517721Speter#define actualblocks(fs, dp) DIP(fs, dp, di_blocks) 14617721Speter#endif 14717721Speter 14825839Speterstatic int virtualblocks(super, dp) 14917721Speter struct fs *super; 15025839Speter union dinode *dp; 15117721Speter{ 15217721Speter register off_t nblk, sz; 15317721Speter 15417721Speter sz = DIP(super, dp, di_size); 15517721Speter#ifdef COMPAT 15617721Speter if (lblkno(super,sz) >= NDADDR) { 15717721Speter nblk = blkroundup(super,sz); 15817721Speter if (sz == nblk) 15917721Speter nblk += super->fs_bsize; 16017721Speter } 16117721Speter 16217721Speter return sz / 1024; 16317721Speter 16417721Speter#else /* COMPAT */ 16517721Speter 16617721Speter if (lblkno(super,sz) >= NDADDR) { 16717721Speter nblk = blkroundup(super,sz); 16817721Speter sz = lblkno(super,nblk); 16917721Speter sz = (sz - NDADDR + NINDIR(super) - 1) / NINDIR(super); 17017721Speter while (sz > 0) { 17117721Speter nblk += sz * super->fs_bsize; 17217721Speter /* sz - 1 rounded up */ 17325839Speter sz = (sz - 1 + NINDIR(super) - 1) / NINDIR(super); 17417721Speter } 17517721Speter } else 17617721Speter nblk = fragroundup(super,sz); 17717721Speter 17817721Speter return nblk / 512; 17917721Speter#endif /* COMPAT */ 18017721Speter} 18117721Speter 18217721Speterstatic int 18325839Speterisfree(super, dp) 18425839Speter struct fs *super; 18517721Speter union dinode *dp; 18625839Speter{ 18717721Speter#ifdef COMPAT 18825839Speter return (DIP(super, dp, di_mode) & IFMT) == 0; 18925839Speter#else /* COMPAT */ 19017721Speter 19117721Speter switch (DIP(super, dp, di_mode) & IFMT) { 19217721Speter case IFIFO: 19317721Speter case IFLNK: /* should check FASTSYMLINK? */ 19417721Speter case IFDIR: 19525839Speter case IFREG: 19617721Speter return 0; 19717721Speter default: 19825839Speter return 1; 19925839Speter } 20025839Speter#endif 20125839Speter} 20226801Speter 20326801Speterstatic struct user { 20426801Speter uid_t uid; 20526801Speter char *name; 20626801Speter daddr_t space; 20726801Speter long count; 20826801Speter daddr_t spc30; 20926801Speter daddr_t spc60; 21026801Speter daddr_t spc90; 21126801Speter} *users; 21226801Speterstatic int nusers; 21326801Speter 21426801Speterstatic void 21526801Speterinituser() 21626801Speter{ 21726801Speter register int i; 21826801Speter register struct user *usr; 21926801Speter 22026801Speter if (!nusers) { 22126801Speter nusers = 8; 22226801Speter if (!(users = 22326801Speter (struct user *)calloc(nusers,sizeof(struct user)))) 22426801Speter errx(1, "allocate users"); 22526801Speter } else { 22626801Speter for (usr = users, i = nusers; --i >= 0; usr++) { 22726801Speter usr->space = usr->spc30 = usr->spc60 = usr->spc90 = 0; 22826801Speter usr->count = 0; 22926801Speter } 23026801Speter } 23126801Speter} 23226801Speter 23326801Speterstatic void 23426801Speterusrrehash() 23526801Speter{ 23626801Speter register int i; 23726801Speter register struct user *usr, *usrn; 23826801Speter struct user *svusr; 23926801Speter 24026801Speter svusr = users; 24126801Speter nusers <<= 1; 24226801Speter if (!(users = (struct user *)calloc(nusers,sizeof(struct user)))) 24326801Speter errx(1, "allocate users"); 24426801Speter for (usr = svusr, i = nusers >> 1; --i >= 0; usr++) { 24526801Speter for (usrn = users + (usr->uid&(nusers - 1)); usrn->name; 24626801Speter usrn--) { 24726801Speter if (usrn <= users) 24826801Speter usrn = users + nusers; 24926801Speter } 25026801Speter *usrn = *usr; 25126801Speter } 25226801Speter} 25326801Speter 25426801Speterstatic struct user * 25526801Speteruser(uid) 25626801Speter uid_t uid; 25726801Speter{ 25826801Speter register struct user *usr; 25926801Speter register int i; 26026801Speter struct passwd *pwd; 26126801Speter 26226801Speter while (1) { 26326801Speter for (usr = users + (uid&(nusers - 1)), i = nusers; --i >= 0; 26426801Speter usr--) { 26526801Speter if (!usr->name) { 26626801Speter usr->uid = uid; 26726801Speter 26826801Speter if (!(pwd = getpwuid(uid))) { 26926801Speter if ((usr->name = (char *)malloc(7))) 27026801Speter sprintf(usr->name,"#%d",uid); 27126801Speter } else { 27226801Speter if ((usr->name = (char *) 27326801Speter malloc(strlen(pwd->pw_name) + 1))) 27426801Speter strcpy(usr->name,pwd->pw_name); 27526801Speter } 27626801Speter if (!usr->name) 27726801Speter errx(1, "allocate users"); 27826801Speter 27926801Speter return usr; 28026801Speter 28126801Speter } else if (usr->uid == uid) 28225839Speter return usr; 28325839Speter 28425839Speter if (usr <= users) 28525839Speter usr = users + nusers; 28625839Speter } 28725839Speter usrrehash(); 28825839Speter } 28925839Speter} 29025839Speter 29125839Speterstatic int 29225839Spetercmpusers(v1,v2) 29325839Speter const void *v1, *v2; 29425839Speter{ 29525839Speter const struct user *u1, *u2; 29625839Speter u1 = (const struct user *)v1; 29725839Speter u2 = (const struct user *)v2; 29825839Speter 29925839Speter return u2->space - u1->space; 30025839Speter} 30125839Speter 30225839Speter#define sortusers(users) (qsort((users),nusers,sizeof(struct user), \ 30325839Speter cmpusers)) 30425839Speter 30525839Speterstatic void 30625839Speteruses(uid,blks,act) 30725839Speter uid_t uid; 30825839Speter daddr_t blks; 30925839Speter time_t act; 31025839Speter{ 31125839Speter static time_t today; 31225839Speter register struct user *usr; 31325839Speter 31425839Speter if (!today) 31525839Speter time(&today); 31625839Speter 31725839Speter usr = user(uid); 31825839Speter usr->count++; 31925839Speter usr->space += blks; 32025839Speter 32125839Speter if (today - act > 90L * 24L * 60L * 60L) 32225839Speter usr->spc90 += blks; 32325839Speter if (today - act > 60L * 24L * 60L * 60L) 32425839Speter usr->spc60 += blks; 32525839Speter if (today - act > 30L * 24L * 60L * 60L) 32625839Speter usr->spc30 += blks; 32725839Speter} 32825839Speter 32925839Speter#ifdef COMPAT 33025839Speter#define FSZCNT 500 33125839Speter#else 33225839Speter#define FSZCNT 512 33325839Speter#endif 33425839Speterstruct fsizes { 33525839Speter struct fsizes *fsz_next; 33625839Speter daddr_t fsz_first, fsz_last; 33725839Speter ino_t fsz_count[FSZCNT]; 33825839Speter daddr_t fsz_sz[FSZCNT]; 33925839Speter} *fsizes; 34025839Speter 34125839Speterstatic void 34225839Speterinitfsizes() 34325839Speter{ 34425839Speter register struct fsizes *fp; 34525839Speter register int i; 34625839Speter 34725839Speter for (fp = fsizes; fp; fp = fp->fsz_next) { 34825839Speter for (i = FSZCNT; --i >= 0;) { 34925839Speter fp->fsz_count[i] = 0; 35025839Speter fp->fsz_sz[i] = 0; 35125839Speter } 35225839Speter } 35325839Speter} 35425839Speter 35525839Speterstatic void 35625839Speterdofsizes(fd, super, name) 35725839Speter int fd; 35825839Speter struct fs *super; 35925839Speter char *name; 36025839Speter{ 36125839Speter ino_t inode, maxino; 36225839Speter union dinode *dp; 36325839Speter daddr_t sz, ksz; 36425839Speter struct fsizes *fp, **fsp; 36525839Speter register int i; 36625839Speter 36725839Speter maxino = super->fs_ncg * super->fs_ipg - 1; 36825839Speter#ifdef COMPAT 36925839Speter if (!(fsizes = (struct fsizes *)malloc(sizeof(struct fsizes)))) 37025839Speter errx(1, "allocate fsize structure"); 37125839Speter#endif /* COMPAT */ 37225839Speter for (inode = 0; inode < maxino; inode++) { 37325839Speter errno = 0; 37425839Speter if ((dp = get_inode(fd,super,inode)) 37525839Speter#ifdef COMPAT 37625839Speter && ((DIP(super, dp, di_mode) & IFMT) == IFREG 37725839Speter || (DIP(super, dp, di_mode) & IFMT) == IFDIR) 37825839Speter#else /* COMPAT */ 37925839Speter && !isfree(super, dp) 38025839Speter#endif /* COMPAT */ 38125839Speter ) { 38225839Speter sz = estimate ? virtualblocks(super, dp) : 38325839Speter actualblocks(super, dp); 38425839Speter#ifdef COMPAT 38525839Speter if (sz >= FSZCNT) { 38625839Speter fsizes->fsz_count[FSZCNT-1]++; 38725839Speter fsizes->fsz_sz[FSZCNT-1] += sz; 38825839Speter } else { 38925839Speter fsizes->fsz_count[sz]++; 39025839Speter fsizes->fsz_sz[sz] += sz; 39125839Speter } 39225839Speter#else /* COMPAT */ 39325839Speter ksz = SIZE(sz); 39425839Speter for (fsp = &fsizes; (fp = *fsp); fsp = &fp->fsz_next) { 39525839Speter if (ksz < fp->fsz_last) 39625839Speter break; 39725839Speter } 39825839Speter if (!fp || ksz < fp->fsz_first) { 39925839Speter if (!(fp = (struct fsizes *) 40025839Speter malloc(sizeof(struct fsizes)))) 40125839Speter errx(1, "allocate fsize structure"); 40225839Speter fp->fsz_next = *fsp; 40325839Speter *fsp = fp; 40425839Speter fp->fsz_first = (ksz / FSZCNT) * FSZCNT; 40525839Speter fp->fsz_last = fp->fsz_first + FSZCNT; 40625839Speter for (i = FSZCNT; --i >= 0;) { 40725839Speter fp->fsz_count[i] = 0; 40825839Speter fp->fsz_sz[i] = 0; 40925839Speter } 41025839Speter } 41125839Speter fp->fsz_count[ksz % FSZCNT]++; 41225839Speter fp->fsz_sz[ksz % FSZCNT] += sz; 41325839Speter#endif /* COMPAT */ 41425839Speter } else if (errno) { 41525839Speter err(1, "%s", name); 41625839Speter } 41725839Speter } 41825839Speter sz = 0; 41925839Speter for (fp = fsizes; fp; fp = fp->fsz_next) { 42025839Speter for (i = 0; i < FSZCNT; i++) { 42125839Speter if (fp->fsz_count[i]) 42225839Speter printf("%jd\t%jd\t%d\n", 42325839Speter (intmax_t)(fp->fsz_first + i), 42425839Speter (intmax_t)fp->fsz_count[i], 42525839Speter SIZE(sz += fp->fsz_sz[i])); 42625839Speter } 42725839Speter } 42825839Speter} 42925839Speter 43025839Speterstatic void 43125839Speterdouser(fd, super, name) 43225839Speter int fd; 43325839Speter struct fs *super; 43425839Speter char *name; 43525839Speter{ 43625839Speter ino_t inode, maxino; 43725839Speter struct user *usr, *usrs; 43825839Speter union dinode *dp; 43925839Speter register int n; 44025839Speter 44125839Speter maxino = super->fs_ncg * super->fs_ipg - 1; 44225839Speter for (inode = 0; inode < maxino; inode++) { 44325839Speter errno = 0; 44425839Speter if ((dp = get_inode(fd,super,inode)) 44525839Speter && !isfree(super, dp)) 44625839Speter uses(DIP(super, dp, di_uid), 44725839Speter estimate ? virtualblocks(super, dp) : 44825839Speter actualblocks(super, dp), 44925839Speter DIP(super, dp, di_atime)); 45025839Speter else if (errno) { 45125839Speter err(1, "%s", name); 45225839Speter } 45325839Speter } 45425839Speter if (!(usrs = (struct user *)malloc(nusers * sizeof(struct user)))) 45525839Speter errx(1, "allocate users"); 45625839Speter bcopy(users,usrs,nusers * sizeof(struct user)); 45725839Speter sortusers(usrs); 45825839Speter for (usr = usrs, n = nusers; --n >= 0 && usr->count; usr++) { 45925839Speter printf("%5d",SIZE(usr->space)); 46025839Speter if (count) 46125839Speter printf("\t%5ld",usr->count); 46225839Speter printf("\t%-8s",usr->name); 46325839Speter if (unused) 46425839Speter printf("\t%5d\t%5d\t%5d", 46525839Speter SIZE(usr->spc30), 46625839Speter SIZE(usr->spc60), 46725839Speter SIZE(usr->spc90)); 46825839Speter printf("\n"); 46925839Speter } 47025839Speter free(usrs); 47125839Speter} 47225839Speter 47325839Speterstatic void 47425839Speterdonames(fd, super, name) 47525839Speter int fd; 47625839Speter struct fs *super; 47725839Speter char *name; 47825839Speter{ 47925839Speter int c; 48025839Speter ino_t inode; 48125839Speter ino_t maxino; 48225839Speter union dinode *dp; 48325839Speter 48425839Speter maxino = super->fs_ncg * super->fs_ipg - 1; 48525839Speter /* first skip the name of the filesystem */ 48625839Speter while ((c = getchar()) != EOF && (c < '0' || c > '9')) 48725839Speter while ((c = getchar()) != EOF && c != '\n'); 48825839Speter ungetc(c,stdin); 48925839Speter while (scanf("%u",&inode) == 1) { 49025839Speter if (inode > maxino) { 49125839Speter warnx("illegal inode %d",inode); 49225839Speter return; 49325839Speter } 49425839Speter errno = 0; 49525839Speter if ((dp = get_inode(fd,super,inode)) 49625839Speter && !isfree(super, dp)) { 49725839Speter printf("%s\t",user(DIP(super, dp, di_uid))->name); 49825839Speter /* now skip whitespace */ 49925839Speter while ((c = getchar()) == ' ' || c == '\t'); 50025839Speter /* and print out the remainder of the input line */ 50125839Speter while (c != EOF && c != '\n') { 50225839Speter putchar(c); 50325839Speter c = getchar(); 50425839Speter } 50525839Speter putchar('\n'); 50625839Speter } else { 50725839Speter if (errno) { 50825839Speter err(1, "%s", name); 50925839Speter } 51025839Speter /* skip this line */ 51125839Speter while ((c = getchar()) != EOF && c != '\n'); 51225839Speter } 51325839Speter if (c == EOF) 51425839Speter break; 51525839Speter } 51625839Speter} 51725839Speter 51825839Speterstatic void 51925839Speterusage() 52025839Speter{ 52125839Speter#ifdef COMPAT 52225839Speter fprintf(stderr,"usage: quot [-nfcvha] [filesystem ...]\n"); 52325839Speter#else /* COMPAT */ 52425839Speter fprintf(stderr,"usage: quot [-acfhknv] [filesystem ...]\n"); 52525839Speter#endif /* COMPAT */ 52625839Speter exit(1); 52725839Speter} 52825839Speter 52925839Speter/* 53025839Speter * Possible superblock locations ordered from most to least likely. 53125839Speter */ 53225839Speterstatic int sblock_try[] = SBLOCKSEARCH; 53325839Speterstatic char superblock[SBLOCKSIZE]; 53425839Speter 53525839Spetervoid 53625839Speterquot(name,mp) 53725839Speter char *name, *mp; 53825839Speter{ 53925839Speter int i, fd; 54025839Speter struct fs *fs; 54125839Speter 54225839Speter get_inode(-1, NULL, 0); /* flush cache */ 54325839Speter inituser(); 54425839Speter initfsizes(); 54525839Speter if ((fd = open(name,0)) < 0) { 54625839Speter warn("%s", name); 54725839Speter close(fd); 54825839Speter return; 54925839Speter } 55025839Speter for (i = 0; sblock_try[i] != -1; i++) { 55125839Speter if (lseek(fd, sblock_try[i], 0) != sblock_try[i]) { 55225839Speter close(fd); 55325839Speter return; 554 } 555 if (read(fd, superblock, SBLOCKSIZE) != SBLOCKSIZE) { 556 close(fd); 557 return; 558 } 559 fs = (struct fs *)superblock; 560 if ((fs->fs_magic == FS_UFS1_MAGIC || 561 (fs->fs_magic == FS_UFS2_MAGIC && 562 fs->fs_sblockloc == sblock_try[i])) && 563 fs->fs_bsize <= MAXBSIZE && 564 fs->fs_bsize >= sizeof(struct fs)) 565 break; 566 } 567 if (sblock_try[i] == -1) { 568 warnx("%s: not a BSD filesystem",name); 569 close(fd); 570 return; 571 } 572 printf("%s:",name); 573 if (mp) 574 printf(" (%s)",mp); 575 putchar('\n'); 576 (*func)(fd, fs, name); 577 close(fd); 578} 579 580int 581main(argc,argv) 582 int argc; 583 char **argv; 584{ 585 char all = 0; 586 struct statfs *mp; 587 struct fstab *fs; 588 char dev[MNAMELEN + 1]; 589 char *nm; 590 int cnt; 591 592 func = douser; 593#ifndef COMPAT 594 header = getbsize(&headerlen,&blocksize); 595#endif 596 while (--argc > 0 && **++argv == '-') { 597 while (*++*argv) { 598 switch (**argv) { 599 case 'n': 600 func = donames; 601 break; 602 case 'c': 603 func = dofsizes; 604 break; 605 case 'a': 606 all = 1; 607 break; 608 case 'f': 609 count = 1; 610 break; 611 case 'h': 612 estimate = 1; 613 break; 614#ifndef COMPAT 615 case 'k': 616 blocksize = 1024; 617 break; 618#endif /* COMPAT */ 619 case 'v': 620 unused = 1; 621 break; 622 default: 623 usage(); 624 } 625 } 626 } 627 if (all) { 628 cnt = getmntinfo(&mp,MNT_NOWAIT); 629 for (; --cnt >= 0; mp++) { 630 if (!strncmp(mp->f_fstypename, "ufs", MFSNAMELEN)) { 631 if ((nm = strrchr(mp->f_mntfromname,'/'))) { 632 sprintf(dev,"%s%s",_PATH_DEV,nm + 1); 633 nm = dev; 634 } else 635 nm = mp->f_mntfromname; 636 quot(nm,mp->f_mntonname); 637 } 638 } 639 } 640 while (--argc >= 0) { 641 if ((fs = getfsfile(*argv)) != NULL) 642 quot(fs->fs_spec, 0); 643 else 644 quot(*argv,0); 645 argv++; 646 } 647 return 0; 648} 649