quot.c revision 74071
112032Speter/* 212032Speter * Copyright (C) 1991, 1994 Wolfgang Solfrank. 312032Speter * Copyright (C) 1991, 1994 TooLs GmbH. 412032Speter * All rights reserved. 512032Speter * 612032Speter * Redistribution and use in source and binary forms, with or without 712032Speter * modification, are permitted provided that the following conditions 812032Speter * are met: 912032Speter * 1. Redistributions of source code must retain the above copyright 1012032Speter * notice, this list of conditions and the following disclaimer. 1112032Speter * 2. Redistributions in binary form must reproduce the above copyright 1212032Speter * notice, this list of conditions and the following disclaimer in the 1312032Speter * documentation and/or other materials provided with the distribution. 1412032Speter * 3. All advertising materials mentioning features or use of this software 1512032Speter * must display the following acknowledgement: 1612032Speter * This product includes software developed by TooLs GmbH. 1712032Speter * 4. The name of TooLs GmbH may not be used to endorse or promote products 1812032Speter * derived from this software without specific prior written permission. 1912032Speter * 2012032Speter * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR 2112032Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2212032Speter * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2312032Speter * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2412032Speter * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2512032Speter * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2612032Speter * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2712032Speter * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2812032Speter * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 2912032Speter * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3012032Speter */ 3112032Speter 3212032Speter#ifndef lint 3330262Scharnierstatic const char rcsid[] = 3450479Speter "$FreeBSD: head/usr.sbin/quot/quot.c 74071 2001-03-10 12:12:47Z ps $"; 3512032Speter#endif /* not lint */ 3612032Speter 3712032Speter#include <sys/param.h> 3812032Speter#include <sys/mount.h> 3912032Speter#include <sys/time.h> 4012032Speter#include <ufs/ffs/fs.h> 4112032Speter#include <ufs/ufs/quota.h> 4212032Speter#include <ufs/ufs/inode.h> 4312032Speter 4430262Scharnier#include <err.h> 4530262Scharnier#include <fcntl.h> 4674071Sps#include <fstab.h> 4730262Scharnier#include <errno.h> 4869793Sobrien#include <paths.h> 4930262Scharnier#include <pwd.h> 5012032Speter#include <stdio.h> 5112032Speter#include <stdlib.h> 5212032Speter#include <string.h> 5330262Scharnier#include <unistd.h> 5412032Speter 5512032Speter/* some flags of what to do: */ 5612032Speterstatic char estimate; 5712032Speterstatic char count; 5812032Speterstatic char unused; 5930262Scharnierstatic void (*func)(); 6012032Speterstatic long blocksize; 6112032Speterstatic char *header; 6212032Speterstatic int headerlen; 6312032Speter 6412032Speter/* 6512032Speter * Original BSD quot doesn't round to number of frags/blocks, 6612032Speter * doesn't account for indirection blocks and gets it totally 6712032Speter * wrong if the size is a multiple of the blocksize. 6812032Speter * The new code always counts the number of 512 byte blocks 6912032Speter * instead of the number of kilobytes and converts them to 7012032Speter * kByte when done (on request). 7141727Sdillon * 7241727Sdillon * Due to the size of modern disks, we must cast intermediate 7341727Sdillon * values to 64 bits to prevent potential overflows. 7412032Speter */ 7512032Speter#ifdef COMPAT 7612032Speter#define SIZE(n) (n) 7712032Speter#else 7841727Sdillon#define SIZE(n) ((int)(((quad_t)(n) * 512 + blocksize - 1)/blocksize)) 7912032Speter#endif 8012032Speter 8112032Speter#define INOCNT(fs) ((fs)->fs_ipg) 8212032Speter#define INOSZ(fs) (sizeof(struct dinode) * INOCNT(fs)) 8312032Speter 8430262Scharnierstatic struct dinode * 8530262Scharnierget_inode(fd,super,ino) 8612032Speter struct fs *super; 8712032Speter ino_t ino; 8812032Speter{ 8912032Speter static struct dinode *ip; 9012032Speter static ino_t last; 9112032Speter 9212032Speter if (fd < 0) { /* flush cache */ 9312032Speter if (ip) { 9412032Speter free(ip); 9512032Speter ip = 0; 9612032Speter } 9712032Speter return 0; 9812032Speter } 9912032Speter 10012032Speter if (!ip || ino < last || ino >= last + INOCNT(super)) { 10112032Speter if (!ip 10230262Scharnier && !(ip = (struct dinode *)malloc(INOSZ(super)))) 10330262Scharnier errx(1, "allocate inodes"); 10412032Speter last = (ino / INOCNT(super)) * INOCNT(super); 10528160Sjkh if (lseek(fd, (off_t)ino_to_fsba(super, last) << super->fs_fshift, 0) < (off_t)0 10630262Scharnier || read(fd,ip,INOSZ(super)) != INOSZ(super)) 10730262Scharnier err(1, "read inodes"); 10812032Speter } 10912032Speter 11012032Speter return ip + ino % INOCNT(super); 11112032Speter} 11212032Speter 11312032Speter#ifdef COMPAT 11412032Speter#define actualblocks(super,ip) ((ip)->di_blocks/2) 11512032Speter#else 11612032Speter#define actualblocks(super,ip) ((ip)->di_blocks) 11712032Speter#endif 11812032Speter 11930262Scharnierstatic int virtualblocks(super,ip) 12012032Speter struct fs *super; 12112032Speter struct dinode *ip; 12212032Speter{ 12312032Speter register off_t nblk, sz; 12412032Speter 12512032Speter sz = ip->di_size; 12612032Speter#ifdef COMPAT 12712032Speter if (lblkno(super,sz) >= NDADDR) { 12812032Speter nblk = blkroundup(super,sz); 12912032Speter if (sz == nblk) 13012032Speter nblk += super->fs_bsize; 13112032Speter } 13212032Speter 13312032Speter return sz / 1024; 13412032Speter 13512032Speter#else /* COMPAT */ 13612032Speter 13712032Speter if (lblkno(super,sz) >= NDADDR) { 13812032Speter nblk = blkroundup(super,sz); 13912032Speter sz = lblkno(super,nblk); 14012032Speter sz = (sz - NDADDR + NINDIR(super) - 1) / NINDIR(super); 14112032Speter while (sz > 0) { 14212032Speter nblk += sz * super->fs_bsize; 14312032Speter /* sz - 1 rounded up */ 14412032Speter sz = (sz - 1 + NINDIR(super) - 1) / NINDIR(super); 14512032Speter } 14612032Speter } else 14712032Speter nblk = fragroundup(super,sz); 14812032Speter 14912032Speter return nblk / 512; 15012032Speter#endif /* COMPAT */ 15112032Speter} 15212032Speter 15330262Scharnierstatic int 15430262Scharnierisfree(ip) 15512032Speter struct dinode *ip; 15612032Speter{ 15712032Speter#ifdef COMPAT 15812032Speter return (ip->di_mode&IFMT) == 0; 15912032Speter#else /* COMPAT */ 16012032Speter 16112032Speter switch (ip->di_mode&IFMT) { 16212032Speter case IFIFO: 16312032Speter case IFLNK: /* should check FASTSYMLINK? */ 16412032Speter case IFDIR: 16512032Speter case IFREG: 16612032Speter return 0; 16712032Speter default: 16812032Speter return 1; 16912032Speter } 17012032Speter#endif 17112032Speter} 17212032Speter 17312032Speterstatic struct user { 17412032Speter uid_t uid; 17512032Speter char *name; 17612032Speter daddr_t space; 17712032Speter long count; 17812032Speter daddr_t spc30; 17912032Speter daddr_t spc60; 18012032Speter daddr_t spc90; 18112032Speter} *users; 18212032Speterstatic int nusers; 18312032Speter 18430262Scharnierstatic void 18530262Scharnierinituser() 18612032Speter{ 18712032Speter register i; 18812032Speter register struct user *usr; 18912032Speter 19012032Speter if (!nusers) { 19112032Speter nusers = 8; 19212032Speter if (!(users = 19330262Scharnier (struct user *)calloc(nusers,sizeof(struct user)))) 19430262Scharnier errx(1, "allocate users"); 19512032Speter } else { 19612032Speter for (usr = users, i = nusers; --i >= 0; usr++) { 19712032Speter usr->space = usr->spc30 = usr->spc60 = usr->spc90 = 0; 19812032Speter usr->count = 0; 19912032Speter } 20012032Speter } 20112032Speter} 20212032Speter 20330262Scharnierstatic void 20430262Scharnierusrrehash() 20512032Speter{ 20612032Speter register i; 20712032Speter register struct user *usr, *usrn; 20812032Speter struct user *svusr; 20912032Speter 21012032Speter svusr = users; 21112032Speter nusers <<= 1; 21230262Scharnier if (!(users = (struct user *)calloc(nusers,sizeof(struct user)))) 21330262Scharnier errx(1, "allocate users"); 21412032Speter for (usr = svusr, i = nusers >> 1; --i >= 0; usr++) { 21512032Speter for (usrn = users + (usr->uid&(nusers - 1)); usrn->name; 21612032Speter usrn--) { 21712032Speter if (usrn <= users) 21812032Speter usrn = users + nusers; 21912032Speter } 22012032Speter *usrn = *usr; 22112032Speter } 22212032Speter} 22312032Speter 22430262Scharnierstatic struct user * 22530262Scharnieruser(uid) 22612032Speter uid_t uid; 22712032Speter{ 22812032Speter register struct user *usr; 22912032Speter register i; 23012032Speter struct passwd *pwd; 23112032Speter 23212032Speter while (1) { 23312032Speter for (usr = users + (uid&(nusers - 1)), i = nusers; --i >= 0; 23412032Speter usr--) { 23512032Speter if (!usr->name) { 23612032Speter usr->uid = uid; 23712032Speter 23812032Speter if (!(pwd = getpwuid(uid))) { 23930262Scharnier if ((usr->name = (char *)malloc(7))) 24012032Speter sprintf(usr->name,"#%d",uid); 24112032Speter } else { 24230262Scharnier if ((usr->name = (char *) 24330262Scharnier malloc(strlen(pwd->pw_name) + 1))) 24412032Speter strcpy(usr->name,pwd->pw_name); 24512032Speter } 24630262Scharnier if (!usr->name) 24730262Scharnier errx(1, "allocate users"); 24812032Speter 24912032Speter return usr; 25012032Speter 25112032Speter } else if (usr->uid == uid) 25212032Speter return usr; 25312032Speter 25412032Speter if (usr <= users) 25512032Speter usr = users + nusers; 25612032Speter } 25712032Speter usrrehash(); 25812032Speter } 25912032Speter} 26012032Speter 26130262Scharnierstatic int 26230262Scharniercmpusers(u1,u2) 26312032Speter struct user *u1, *u2; 26412032Speter{ 26512032Speter return u2->space - u1->space; 26612032Speter} 26712032Speter 26812032Speter#define sortusers(users) (qsort((users),nusers,sizeof(struct user), \ 26912032Speter cmpusers)) 27012032Speter 27130262Scharnierstatic void 27230262Scharnieruses(uid,blks,act) 27312032Speter uid_t uid; 27412032Speter daddr_t blks; 27512032Speter time_t act; 27612032Speter{ 27712032Speter static time_t today; 27812032Speter register struct user *usr; 27912032Speter 28012032Speter if (!today) 28112032Speter time(&today); 28212032Speter 28312032Speter usr = user(uid); 28412032Speter usr->count++; 28512032Speter usr->space += blks; 28612032Speter 28712032Speter if (today - act > 90L * 24L * 60L * 60L) 28812032Speter usr->spc90 += blks; 28912032Speter if (today - act > 60L * 24L * 60L * 60L) 29012032Speter usr->spc60 += blks; 29112032Speter if (today - act > 30L * 24L * 60L * 60L) 29212032Speter usr->spc30 += blks; 29312032Speter} 29412032Speter 29512032Speter#ifdef COMPAT 29612032Speter#define FSZCNT 500 29712032Speter#else 29812032Speter#define FSZCNT 512 29912032Speter#endif 30012032Speterstruct fsizes { 30112032Speter struct fsizes *fsz_next; 30212032Speter daddr_t fsz_first, fsz_last; 30312032Speter ino_t fsz_count[FSZCNT]; 30412032Speter daddr_t fsz_sz[FSZCNT]; 30512032Speter} *fsizes; 30612032Speter 30730262Scharnierstatic void 30830262Scharnierinitfsizes() 30912032Speter{ 31012032Speter register struct fsizes *fp; 31112032Speter register i; 31212032Speter 31312032Speter for (fp = fsizes; fp; fp = fp->fsz_next) { 31412032Speter for (i = FSZCNT; --i >= 0;) { 31512032Speter fp->fsz_count[i] = 0; 31612032Speter fp->fsz_sz[i] = 0; 31712032Speter } 31812032Speter } 31912032Speter} 32012032Speter 32130262Scharnierstatic void 32230262Scharnierdofsizes(fd,super,name) 32312032Speter struct fs *super; 32412032Speter char *name; 32512032Speter{ 32612032Speter ino_t inode, maxino; 32712032Speter struct dinode *ip; 32812032Speter daddr_t sz, ksz; 32912032Speter struct fsizes *fp, **fsp; 33012032Speter register i; 33112032Speter 33212032Speter maxino = super->fs_ncg * super->fs_ipg - 1; 33312032Speter#ifdef COMPAT 33430262Scharnier if (!(fsizes = (struct fsizes *)malloc(sizeof(struct fsizes)))) 33553764Scharnier errx(1, "allocate fsize structure"); 33612032Speter#endif /* COMPAT */ 33712032Speter for (inode = 0; inode < maxino; inode++) { 33812032Speter errno = 0; 33912032Speter if ((ip = get_inode(fd,super,inode)) 34012032Speter#ifdef COMPAT 34112032Speter && ((ip->di_mode&IFMT) == IFREG 34212032Speter || (ip->di_mode&IFMT) == IFDIR) 34312032Speter#else /* COMPAT */ 34412032Speter && !isfree(ip) 34512032Speter#endif /* COMPAT */ 34612032Speter ) { 34712032Speter sz = estimate ? virtualblocks(super,ip) : 34812032Speter actualblocks(super,ip); 34912032Speter#ifdef COMPAT 35012032Speter if (sz >= FSZCNT) { 35112032Speter fsizes->fsz_count[FSZCNT-1]++; 35212032Speter fsizes->fsz_sz[FSZCNT-1] += sz; 35312032Speter } else { 35412032Speter fsizes->fsz_count[sz]++; 35512032Speter fsizes->fsz_sz[sz] += sz; 35612032Speter } 35712032Speter#else /* COMPAT */ 35812032Speter ksz = SIZE(sz); 35930262Scharnier for (fsp = &fsizes; (fp = *fsp); fsp = &fp->fsz_next) { 36012032Speter if (ksz < fp->fsz_last) 36112032Speter break; 36212032Speter } 36312032Speter if (!fp || ksz < fp->fsz_first) { 36412032Speter if (!(fp = (struct fsizes *) 36530262Scharnier malloc(sizeof(struct fsizes)))) 36653764Scharnier errx(1, "allocate fsize structure"); 36712032Speter fp->fsz_next = *fsp; 36812032Speter *fsp = fp; 36912032Speter fp->fsz_first = (ksz / FSZCNT) * FSZCNT; 37012032Speter fp->fsz_last = fp->fsz_first + FSZCNT; 37112032Speter for (i = FSZCNT; --i >= 0;) { 37212032Speter fp->fsz_count[i] = 0; 37312032Speter fp->fsz_sz[i] = 0; 37412032Speter } 37512032Speter } 37612032Speter fp->fsz_count[ksz % FSZCNT]++; 37712032Speter fp->fsz_sz[ksz % FSZCNT] += sz; 37812032Speter#endif /* COMPAT */ 37912032Speter } else if (errno) { 38030262Scharnier err(1, "%s", name); 38112032Speter } 38212032Speter } 38312032Speter sz = 0; 38412032Speter for (fp = fsizes; fp; fp = fp->fsz_next) { 38512032Speter for (i = 0; i < FSZCNT; i++) { 38612032Speter if (fp->fsz_count[i]) 38712032Speter printf("%d\t%d\t%d\n",fp->fsz_first + i, 38812032Speter fp->fsz_count[i], 38912032Speter SIZE(sz += fp->fsz_sz[i])); 39012032Speter } 39112032Speter } 39212032Speter} 39312032Speter 39430262Scharnierstatic void 39530262Scharnierdouser(fd,super,name) 39612032Speter struct fs *super; 39712032Speter char *name; 39812032Speter{ 39912032Speter ino_t inode, maxino; 40012032Speter struct user *usr, *usrs; 40112032Speter struct dinode *ip; 40212032Speter register n; 40312032Speter 40412032Speter maxino = super->fs_ncg * super->fs_ipg - 1; 40512032Speter for (inode = 0; inode < maxino; inode++) { 40612032Speter errno = 0; 40712032Speter if ((ip = get_inode(fd,super,inode)) 40812032Speter && !isfree(ip)) 40912032Speter uses(ip->di_uid, 41012032Speter estimate ? virtualblocks(super,ip) : 41112032Speter actualblocks(super,ip), 41212032Speter ip->di_atime); 41312032Speter else if (errno) { 41430262Scharnier err(1, "%s", name); 41512032Speter } 41612032Speter } 41730262Scharnier if (!(usrs = (struct user *)malloc(nusers * sizeof(struct user)))) 41830262Scharnier errx(1, "allocate users"); 41912032Speter bcopy(users,usrs,nusers * sizeof(struct user)); 42012032Speter sortusers(usrs); 42112032Speter for (usr = usrs, n = nusers; --n >= 0 && usr->count; usr++) { 42212032Speter printf("%5d",SIZE(usr->space)); 42312032Speter if (count) 42412032Speter printf("\t%5d",usr->count); 42512032Speter printf("\t%-8s",usr->name); 42612032Speter if (unused) 42712032Speter printf("\t%5d\t%5d\t%5d", 42812032Speter SIZE(usr->spc30), 42912032Speter SIZE(usr->spc60), 43012032Speter SIZE(usr->spc90)); 43112032Speter printf("\n"); 43212032Speter } 43312032Speter free(usrs); 43412032Speter} 43512032Speter 43630262Scharnierstatic void 43730262Scharnierdonames(fd,super,name) 43812032Speter struct fs *super; 43912032Speter char *name; 44012032Speter{ 44112032Speter int c; 44212032Speter ino_t inode, inode1; 44312032Speter ino_t maxino; 44412032Speter struct dinode *ip; 44512032Speter 44612032Speter maxino = super->fs_ncg * super->fs_ipg - 1; 44712032Speter /* first skip the name of the filesystem */ 44812032Speter while ((c = getchar()) != EOF && (c < '0' || c > '9')) 44912032Speter while ((c = getchar()) != EOF && c != '\n'); 45012032Speter ungetc(c,stdin); 45112032Speter inode1 = -1; 45212032Speter while (scanf("%d",&inode) == 1) { 45312032Speter if (inode < 0 || inode > maxino) { 45430262Scharnier warnx("illegal inode %d",inode); 45512032Speter return; 45612032Speter } 45712032Speter errno = 0; 45812032Speter if ((ip = get_inode(fd,super,inode)) 45912032Speter && !isfree(ip)) { 46012032Speter printf("%s\t",user(ip->di_uid)->name); 46112032Speter /* now skip whitespace */ 46212032Speter while ((c = getchar()) == ' ' || c == '\t'); 46312032Speter /* and print out the remainder of the input line */ 46412032Speter while (c != EOF && c != '\n') { 46512032Speter putchar(c); 46612032Speter c = getchar(); 46712032Speter } 46812032Speter putchar('\n'); 46912032Speter inode1 = inode; 47012032Speter } else { 47112032Speter if (errno) { 47230262Scharnier err(1, "%s", name); 47312032Speter } 47412032Speter /* skip this line */ 47512032Speter while ((c = getchar()) != EOF && c != '\n'); 47612032Speter } 47712032Speter if (c == EOF) 47812032Speter break; 47912032Speter } 48012032Speter} 48112032Speter 48230262Scharnierstatic void 48330262Scharnierusage() 48412032Speter{ 48512032Speter#ifdef COMPAT 48630262Scharnier fprintf(stderr,"usage: quot [-nfcvha] [filesystem ...]\n"); 48712032Speter#else /* COMPAT */ 48853764Scharnier fprintf(stderr,"usage: quot [-acfhknv] [filesystem ...]\n"); 48912032Speter#endif /* COMPAT */ 49012032Speter exit(1); 49112032Speter} 49212032Speter 49312032Speterstatic char superblock[SBSIZE]; 49412032Speter 49530262Scharniervoid 49612032Speterquot(name,mp) 49712032Speter char *name, *mp; 49812032Speter{ 49912032Speter int fd; 50012032Speter 50112032Speter get_inode(-1); /* flush cache */ 50212032Speter inituser(); 50312032Speter initfsizes(); 50412032Speter if ((fd = open(name,0)) < 0 50512032Speter || lseek(fd,SBOFF,0) != SBOFF 50612032Speter || read(fd,superblock,SBSIZE) != SBSIZE) { 50730262Scharnier warn("%s", name); 50812032Speter close(fd); 50912032Speter return; 51012032Speter } 51112032Speter if (((struct fs *)superblock)->fs_magic != FS_MAGIC) { 51230262Scharnier warnx("%s: not a BSD filesystem",name); 51312032Speter close(fd); 51412032Speter return; 51512032Speter } 51612032Speter printf("%s:",name); 51712032Speter if (mp) 51812032Speter printf(" (%s)",mp); 51912032Speter putchar('\n'); 52012032Speter (*func)(fd,superblock,name); 52112032Speter close(fd); 52212032Speter} 52312032Speter 52430262Scharnierint 52530262Scharniermain(argc,argv) 52612032Speter char **argv; 52712032Speter{ 52812032Speter char all = 0; 52912032Speter struct statfs *mp; 53074071Sps struct fstab *fs; 53112032Speter char dev[MNAMELEN + 1]; 53212032Speter char *nm; 53312032Speter int cnt; 53412032Speter 53512032Speter func = douser; 53612032Speter#ifndef COMPAT 53712032Speter header = getbsize(&headerlen,&blocksize); 53812032Speter#endif 53912032Speter while (--argc > 0 && **++argv == '-') { 54012032Speter while (*++*argv) { 54112032Speter switch (**argv) { 54212032Speter case 'n': 54312032Speter func = donames; 54412032Speter break; 54512032Speter case 'c': 54612032Speter func = dofsizes; 54712032Speter break; 54812032Speter case 'a': 54912032Speter all = 1; 55012032Speter break; 55112032Speter case 'f': 55212032Speter count = 1; 55312032Speter break; 55412032Speter case 'h': 55512032Speter estimate = 1; 55612032Speter break; 55712032Speter#ifndef COMPAT 55812032Speter case 'k': 55912032Speter blocksize = 1024; 56012032Speter break; 56112032Speter#endif /* COMPAT */ 56212032Speter case 'v': 56312032Speter unused = 1; 56412032Speter break; 56512032Speter default: 56612032Speter usage(); 56712032Speter } 56812032Speter } 56912032Speter } 57012032Speter if (all) { 57112032Speter cnt = getmntinfo(&mp,MNT_NOWAIT); 57212032Speter for (; --cnt >= 0; mp++) { 57332595Sbde if (!strncmp(mp->f_fstypename, "ufs", MFSNAMELEN)) { 57430262Scharnier if ((nm = strrchr(mp->f_mntfromname,'/'))) { 57569793Sobrien sprintf(dev,"%s%s",_PATH_DEV,nm + 1); 57612032Speter nm = dev; 57712032Speter } else 57812032Speter nm = mp->f_mntfromname; 57912032Speter quot(nm,mp->f_mntonname); 58012032Speter } 58112032Speter } 58212032Speter } 58374071Sps while (--argc >= 0) { 58474071Sps if ((fs = getfsfile(*argv)) != NULL) 58574071Sps quot(fs->fs_spec, 0); 58674071Sps else 58774071Sps quot(*argv,0); 58874071Sps argv++; 58974071Sps } 59012032Speter return 0; 59112032Speter} 592