quot.c revision 28160
176259Sgreen/*
2126274Sdes * Copyright (C) 1991, 1994 Wolfgang Solfrank.
376259Sgreen * Copyright (C) 1991, 1994 TooLs GmbH.
4126274Sdes * All rights reserved.
5126274Sdes *
6126274Sdes * Redistribution and use in source and binary forms, with or without
776259Sgreen * modification, are permitted provided that the following conditions
8126274Sdes * are met:
9126274Sdes * 1. Redistributions of source code must retain the above copyright
10126274Sdes *    notice, this list of conditions and the following disclaimer.
11126274Sdes * 2. Redistributions in binary form must reproduce the above copyright
12126274Sdes *    notice, this list of conditions and the following disclaimer in the
13126274Sdes *    documentation and/or other materials provided with the distribution.
14126274Sdes * 3. All advertising materials mentioning features or use of this software
1576259Sgreen *    must display the following acknowledgement:
1676259Sgreen *	This product includes software developed by TooLs GmbH.
1776259Sgreen * 4. The name of TooLs GmbH may not be used to endorse or promote products
1876259Sgreen *    derived from this software without specific prior written permission.
19126274Sdes *
2076259Sgreen * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
2176259Sgreen * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2276259Sgreen * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2376259Sgreen * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2476259Sgreen * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2592555Sdes * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2676259Sgreen * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2776259Sgreen * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2876259Sgreen * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
2976259Sgreen * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3076259Sgreen */
31126274Sdes
32126274Sdes#ifndef lint
33126274Sdesstatic char rcsid[] = "$Id: quot.c,v 1.5 1997/02/22 16:12:39 peter Exp $";
34126274Sdes#endif /* not lint */
35126274Sdes
36126274Sdes#include <sys/param.h>
37126274Sdes#include <sys/mount.h>
38126274Sdes#include <sys/time.h>
39126274Sdes#include <ufs/ffs/fs.h>
40126274Sdes#include <ufs/ufs/quota.h>
41126274Sdes#include <ufs/ufs/inode.h>
42126274Sdes
43126274Sdes#include <stdio.h>
44126274Sdes#include <stdlib.h>
45126274Sdes#include <string.h>
46126274Sdes#include <errno.h>
47126274Sdes#include <pwd.h>
48126274Sdes
49126274Sdes/* some flags of what to do: */
50126274Sdesstatic char estimate;
51126274Sdesstatic char count;
5298937Sdesstatic char unused;
5398937Sdesstatic int (*func)();
5498937Sdesstatic long blocksize;
5598937Sdesstatic char *header;
5698937Sdesstatic int headerlen;
5798937Sdes
58126274Sdes/*
59126274Sdes * Original BSD quot doesn't round to number of frags/blocks,
6076259Sgreen * doesn't account for indirection blocks and gets it totally
61126274Sdes * wrong if the	size is a multiple of the blocksize.
62126274Sdes * The new code always counts the number of 512 byte blocks
63126274Sdes * instead of the number of kilobytes and converts them	to
64113908Sdes * kByte when done (on request).
65126274Sdes */
66126274Sdes#ifdef	COMPAT
67126274Sdes#define	SIZE(n)	(n)
68126274Sdes#else
69126274Sdes#define	SIZE(n)	(((n) * 512 + blocksize - 1)/blocksize)
70126274Sdes#endif
71126274Sdes
72126274Sdes#define	INOCNT(fs)	((fs)->fs_ipg)
73126274Sdes#define	INOSZ(fs)	(sizeof(struct dinode) * INOCNT(fs))
74126274Sdes
75126274Sdesstatic struct dinode *get_inode(fd,super,ino)
76126274Sdes	struct fs *super;
77126274Sdes	ino_t ino;
78126274Sdes{
79126274Sdes	static struct dinode *ip;
80126274Sdes	static ino_t last;
81126274Sdes
82126274Sdes	if (fd < 0) {		/* flush cache */
83126274Sdes		if (ip) {
84126274Sdes			free(ip);
85126274Sdes			ip = 0;
86126274Sdes		}
87126274Sdes		return 0;
88126274Sdes	}
89126274Sdes
90126274Sdes	if (!ip || ino < last || ino >= last + INOCNT(super)) {
91126274Sdes		if (!ip
92126274Sdes		    && !(ip = (struct dinode *)malloc(INOSZ(super)))) {
93126274Sdes			perror("allocate inodes");
94126274Sdes			exit(1);
95126274Sdes		}
96126274Sdes		last = (ino / INOCNT(super)) * INOCNT(super);
97126274Sdes		if (lseek(fd, (off_t)ino_to_fsba(super, last) << super->fs_fshift, 0) < (off_t)0
98126274Sdes		    || read(fd,ip,INOSZ(super)) != INOSZ(super)) {
99126274Sdes			perror("read inodes");
100126274Sdes			exit(1);
101126274Sdes		}
102126274Sdes	}
103126274Sdes
104126274Sdes	return ip + ino % INOCNT(super);
105126274Sdes}
106126274Sdes
107126274Sdes#ifdef	COMPAT
108126274Sdes#define	actualblocks(super,ip)	((ip)->di_blocks/2)
109126274Sdes#else
110126274Sdes#define	actualblocks(super,ip)	((ip)->di_blocks)
111126274Sdes#endif
112126274Sdes
113126274Sdesstatic virtualblocks(super,ip)
114126274Sdes	struct fs *super;
115126274Sdes	struct dinode *ip;
116126274Sdes{
117126274Sdes	register off_t nblk, sz;
118126274Sdes
119126274Sdes	sz = ip->di_size;
120126274Sdes#ifdef	COMPAT
121126274Sdes	if (lblkno(super,sz) >= NDADDR) {
122126274Sdes		nblk = blkroundup(super,sz);
123126274Sdes		if (sz == nblk)
124126274Sdes			nblk += super->fs_bsize;
125126274Sdes	}
126126274Sdes
127126274Sdes	return sz / 1024;
128126274Sdes
129126274Sdes#else	/* COMPAT */
130126274Sdes
131126274Sdes	if (lblkno(super,sz) >= NDADDR) {
132126274Sdes		nblk = blkroundup(super,sz);
13392555Sdes		sz = lblkno(super,nblk);
134126274Sdes		sz = (sz - NDADDR + NINDIR(super) - 1) / NINDIR(super);
135126274Sdes		while (sz > 0) {
136126274Sdes			nblk += sz * super->fs_bsize;
137126274Sdes			/* sz - 1 rounded up */
138126274Sdes			sz = (sz - 1 + NINDIR(super) - 1) / NINDIR(super);
139126274Sdes		}
140126274Sdes	} else
141126274Sdes		nblk = fragroundup(super,sz);
142126274Sdes
143126274Sdes	return nblk / 512;
144126274Sdes#endif	/* COMPAT */
145126274Sdes}
146126274Sdes
147126274Sdesstatic isfree(ip)
148126274Sdes	struct dinode *ip;
149126274Sdes{
150126274Sdes#ifdef	COMPAT
151126274Sdes	return (ip->di_mode&IFMT) == 0;
152126274Sdes#else	/* COMPAT */
153126274Sdes
154126274Sdes	switch (ip->di_mode&IFMT) {
155126274Sdes	case IFIFO:
156126274Sdes	case IFLNK:		/* should check FASTSYMLINK? */
157126274Sdes	case IFDIR:
158126274Sdes	case IFREG:
159126274Sdes		return 0;
160126274Sdes	default:
161126274Sdes		return 1;
162126274Sdes	}
163126274Sdes#endif
164126274Sdes}
165126274Sdes
166126274Sdesstatic struct user {
167126274Sdes	uid_t uid;
168126274Sdes	char *name;
169126274Sdes	daddr_t space;
170126274Sdes	long count;
171126274Sdes	daddr_t spc30;
172126274Sdes	daddr_t spc60;
173126274Sdes	daddr_t spc90;
174126274Sdes} *users;
175126274Sdesstatic int nusers;
176126274Sdes
177126274Sdesstatic inituser()
178126274Sdes{
179126274Sdes	register i;
180126274Sdes	register struct user *usr;
181126274Sdes
182126274Sdes	if (!nusers) {
183126274Sdes		nusers = 8;
184126274Sdes		if (!(users =
185126274Sdes		    (struct user *)calloc(nusers,sizeof(struct user)))) {
186126274Sdes			perror("allocate users");
187126274Sdes			exit(1);
188126274Sdes		}
189126274Sdes	} else {
190126274Sdes		for (usr = users, i = nusers; --i >= 0; usr++) {
191126274Sdes			usr->space = usr->spc30 = usr->spc60 = usr->spc90 = 0;
192126274Sdes			usr->count = 0;
193126274Sdes		}
194126274Sdes	}
195126274Sdes}
196126274Sdes
197126274Sdesstatic usrrehash()
198126274Sdes{
199126274Sdes	register i;
200126274Sdes	register struct user *usr, *usrn;
201126274Sdes	struct user *svusr;
202126274Sdes
203126274Sdes	svusr = users;
204126274Sdes	nusers <<= 1;
205126274Sdes	if (!(users = (struct user *)calloc(nusers,sizeof(struct user)))) {
206126274Sdes		perror("allocate users");
207126274Sdes		exit(1);
208126274Sdes	}
209126274Sdes	for (usr = svusr, i = nusers >> 1; --i >= 0; usr++) {
210126274Sdes		for (usrn = users + (usr->uid&(nusers - 1)); usrn->name;
211126274Sdes		    usrn--) {
212126274Sdes			if (usrn <= users)
213126274Sdes				usrn = users + nusers;
214126274Sdes		}
215126274Sdes		*usrn = *usr;
216126274Sdes	}
217126274Sdes}
218126274Sdes
219126274Sdesstatic struct user *user(uid)
220126274Sdes	uid_t uid;
221126274Sdes{
222126274Sdes	register struct user *usr;
223126274Sdes	register i;
224126274Sdes	struct passwd *pwd;
225126274Sdes
226126274Sdes	while (1) {
227126274Sdes		for (usr = users + (uid&(nusers - 1)), i = nusers; --i >= 0;
228126274Sdes		    usr--) {
229126274Sdes			if (!usr->name) {
230126274Sdes				usr->uid = uid;
231126274Sdes
232126274Sdes				if (!(pwd = getpwuid(uid))) {
233126274Sdes					if (usr->name = (char *)malloc(7))
234126274Sdes						sprintf(usr->name,"#%d",uid);
235126274Sdes				} else {
236126274Sdes					if (usr->name = (char *)
237126274Sdes					    malloc(strlen(pwd->pw_name) + 1))
238126274Sdes						strcpy(usr->name,pwd->pw_name);
239126274Sdes				}
240126274Sdes				if (!usr->name) {
241126274Sdes					perror("allocate users");
242126274Sdes					exit(1);
243126274Sdes				}
244126274Sdes
245126274Sdes				return usr;
246126274Sdes
247126274Sdes			} else if (usr->uid == uid)
248126274Sdes				return usr;
249126274Sdes
250126274Sdes			if (usr <= users)
251126274Sdes				usr = users + nusers;
252126274Sdes		}
253126274Sdes		usrrehash();
254126274Sdes	}
255126274Sdes}
256126274Sdes
257126274Sdesstatic cmpusers(u1,u2)
258126274Sdes	struct user *u1, *u2;
259126274Sdes{
260126274Sdes	return u2->space - u1->space;
261126274Sdes}
262126274Sdes
263126274Sdes#define	sortusers(users)	(qsort((users),nusers,sizeof(struct user), \
264126274Sdes				    cmpusers))
265126274Sdes
266126274Sdesstatic uses(uid,blks,act)
267126274Sdes	uid_t uid;
268126274Sdes	daddr_t blks;
269126274Sdes	time_t act;
270126274Sdes{
271126274Sdes	static time_t today;
272126274Sdes	register struct user *usr;
273126274Sdes
274126274Sdes	if (!today)
275126274Sdes		time(&today);
276126274Sdes
277126274Sdes	usr = user(uid);
278126274Sdes	usr->count++;
279126274Sdes	usr->space += blks;
280126274Sdes
281126274Sdes	if (today - act > 90L * 24L * 60L * 60L)
282126274Sdes		usr->spc90 += blks;
283126274Sdes	if (today - act > 60L * 24L * 60L * 60L)
284126274Sdes		usr->spc60 += blks;
285126274Sdes	if (today - act > 30L * 24L * 60L * 60L)
286126274Sdes		usr->spc30 += blks;
287126274Sdes}
288126274Sdes
289126274Sdes#ifdef	COMPAT
290126274Sdes#define	FSZCNT	500
291126274Sdes#else
292126274Sdes#define	FSZCNT	512
293126274Sdes#endif
294126274Sdesstruct fsizes {
295126274Sdes	struct fsizes *fsz_next;
296126274Sdes	daddr_t fsz_first, fsz_last;
297126274Sdes	ino_t fsz_count[FSZCNT];
298126274Sdes	daddr_t fsz_sz[FSZCNT];
299126274Sdes} *fsizes;
300126274Sdes
301126274Sdesstatic initfsizes()
302126274Sdes{
303126274Sdes	register struct fsizes *fp;
304126274Sdes	register i;
305126274Sdes
306126274Sdes	for (fp = fsizes; fp; fp = fp->fsz_next) {
307126274Sdes		for (i = FSZCNT; --i >= 0;) {
308126274Sdes			fp->fsz_count[i] = 0;
309126274Sdes			fp->fsz_sz[i] = 0;
310126274Sdes		}
311126274Sdes	}
312126274Sdes}
313126274Sdes
314126274Sdesstatic dofsizes(fd,super,name)
315126274Sdes	struct fs *super;
316126274Sdes	char *name;
317126274Sdes{
318126274Sdes	ino_t inode, maxino;
319126274Sdes	struct dinode *ip;
320126274Sdes	daddr_t sz, ksz;
321126274Sdes	struct fsizes *fp, **fsp;
322126274Sdes	register i;
323126274Sdes
324126274Sdes	maxino = super->fs_ncg * super->fs_ipg - 1;
325126274Sdes#ifdef	COMPAT
326126274Sdes	if (!(fsizes = (struct fsizes *)malloc(sizeof(struct fsizes)))) {
327126274Sdes		perror("alloc fsize structure");
328126274Sdes		exit(1);
329126274Sdes	}
330126274Sdes#endif	/* COMPAT */
331126274Sdes	for (inode = 0; inode < maxino; inode++) {
332126274Sdes		errno = 0;
333126274Sdes		if ((ip = get_inode(fd,super,inode))
334126274Sdes#ifdef	COMPAT
335126274Sdes		    && ((ip->di_mode&IFMT) == IFREG
336126274Sdes			|| (ip->di_mode&IFMT) == IFDIR)
337126274Sdes#else	/* COMPAT */
338126274Sdes		    && !isfree(ip)
339126274Sdes#endif	/* COMPAT */
340126274Sdes		    ) {
341126274Sdes			sz = estimate ? virtualblocks(super,ip) :
342126274Sdes			    actualblocks(super,ip);
343126274Sdes#ifdef	COMPAT
344126274Sdes			if (sz >= FSZCNT) {
345126274Sdes				fsizes->fsz_count[FSZCNT-1]++;
346126274Sdes				fsizes->fsz_sz[FSZCNT-1] += sz;
347126274Sdes			} else {
348126274Sdes				fsizes->fsz_count[sz]++;
349126274Sdes				fsizes->fsz_sz[sz] += sz;
350126274Sdes			}
351126274Sdes#else	/* COMPAT */
352126274Sdes			ksz = SIZE(sz);
353126274Sdes			for (fsp = &fsizes; fp = *fsp; fsp = &fp->fsz_next) {
354126274Sdes				if (ksz < fp->fsz_last)
355126274Sdes					break;
356126274Sdes			}
357126274Sdes			if (!fp || ksz < fp->fsz_first) {
358126274Sdes				if (!(fp = (struct fsizes *)
359126274Sdes				    malloc(sizeof(struct fsizes)))) {
360126274Sdes					perror("alloc fsize structure");
361126274Sdes					exit(1);
362126274Sdes				}
363126274Sdes				fp->fsz_next = *fsp;
364126274Sdes				*fsp = fp;
365126274Sdes				fp->fsz_first = (ksz / FSZCNT) * FSZCNT;
366126274Sdes				fp->fsz_last = fp->fsz_first + FSZCNT;
367126274Sdes				for (i = FSZCNT; --i >= 0;) {
368126274Sdes					fp->fsz_count[i] = 0;
369126274Sdes					fp->fsz_sz[i] = 0;
370126274Sdes				}
371126274Sdes			}
372126274Sdes			fp->fsz_count[ksz % FSZCNT]++;
373126274Sdes			fp->fsz_sz[ksz % FSZCNT] += sz;
374126274Sdes#endif	/* COMPAT */
375126274Sdes		} else if (errno) {
376126274Sdes			perror(name);
377126274Sdes			exit(1);
378126274Sdes		}
379126274Sdes	}
380126274Sdes	sz = 0;
381126274Sdes	for (fp = fsizes; fp; fp = fp->fsz_next) {
382126274Sdes		for (i = 0; i < FSZCNT; i++) {
383126274Sdes			if (fp->fsz_count[i])
384126274Sdes				printf("%d\t%d\t%d\n",fp->fsz_first + i,
385126274Sdes				    fp->fsz_count[i],
386126274Sdes				    SIZE(sz += fp->fsz_sz[i]));
387126274Sdes		}
388126274Sdes	}
389126274Sdes}
390126274Sdes
391126274Sdesstatic douser(fd,super,name)
392126274Sdes	struct fs *super;
393126274Sdes	char *name;
394126274Sdes{
395126274Sdes	ino_t inode, maxino;
396126274Sdes	struct user *usr, *usrs;
397126274Sdes	struct dinode *ip;
398126274Sdes	register n;
399126274Sdes
400126274Sdes	maxino = super->fs_ncg * super->fs_ipg - 1;
401126274Sdes	for (inode = 0; inode < maxino; inode++) {
402126274Sdes		errno = 0;
403126274Sdes		if ((ip = get_inode(fd,super,inode))
404126274Sdes		    && !isfree(ip))
405126274Sdes			uses(ip->di_uid,
406126274Sdes			    estimate ? virtualblocks(super,ip) :
407126274Sdes				actualblocks(super,ip),
408126274Sdes			    ip->di_atime);
409126274Sdes		else if (errno) {
410126274Sdes			perror(name);
411126274Sdes			exit(1);
412126274Sdes		}
413126274Sdes	}
414126274Sdes	if (!(usrs = (struct user *)malloc(nusers * sizeof(struct user)))) {
415126274Sdes		perror("allocate users");
416126274Sdes		exit(1);
417126274Sdes	}
418126274Sdes	bcopy(users,usrs,nusers * sizeof(struct user));
419126274Sdes	sortusers(usrs);
420126274Sdes	for (usr = usrs, n = nusers; --n >= 0 && usr->count; usr++) {
421126274Sdes		printf("%5d",SIZE(usr->space));
422126274Sdes		if (count)
423126274Sdes			printf("\t%5d",usr->count);
424126274Sdes		printf("\t%-8s",usr->name);
425126274Sdes		if (unused)
426126274Sdes			printf("\t%5d\t%5d\t%5d",
427126274Sdes			       SIZE(usr->spc30),
428126274Sdes			       SIZE(usr->spc60),
429126274Sdes			       SIZE(usr->spc90));
430126274Sdes		printf("\n");
431126274Sdes	}
432126274Sdes	free(usrs);
433126274Sdes}
434126274Sdes
435126274Sdesstatic donames(fd,super,name)
436126274Sdes	struct fs *super;
437126274Sdes	char *name;
438126274Sdes{
439126274Sdes	int c;
440126274Sdes	ino_t inode, inode1;
441126274Sdes	ino_t maxino;
442126274Sdes	struct dinode *ip;
443126274Sdes
444126274Sdes	maxino = super->fs_ncg * super->fs_ipg - 1;
445126274Sdes	/* first skip the name of the filesystem */
446126274Sdes	while ((c = getchar()) != EOF && (c < '0' || c > '9'))
447126274Sdes		while ((c = getchar()) != EOF && c != '\n');
448126274Sdes	ungetc(c,stdin);
449126274Sdes	inode1 = -1;
450126274Sdes	while (scanf("%d",&inode) == 1) {
451126274Sdes		if (inode < 0 || inode > maxino) {
452126274Sdes			fprintf(stderr,"illegal inode %d\n",inode);
453126274Sdes			return;
454126274Sdes		}
455126274Sdes		errno = 0;
456126274Sdes		if ((ip = get_inode(fd,super,inode))
457126274Sdes		    && !isfree(ip)) {
458126274Sdes			printf("%s\t",user(ip->di_uid)->name);
459126274Sdes			/* now skip whitespace */
460126274Sdes			while ((c = getchar()) == ' ' || c == '\t');
461126274Sdes			/* and print out the remainder of the input line */
462126274Sdes			while (c != EOF && c != '\n') {
463126274Sdes				putchar(c);
464126274Sdes				c = getchar();
465126274Sdes			}
466126274Sdes			putchar('\n');
467126274Sdes			inode1 = inode;
468126274Sdes		} else {
469126274Sdes			if (errno) {
470126274Sdes				perror(name);
471126274Sdes				exit(1);
472126274Sdes			}
473126274Sdes			/* skip this line */
474126274Sdes			while ((c = getchar()) != EOF && c != '\n');
475126274Sdes		}
476126274Sdes		if (c == EOF)
477126274Sdes			break;
478126274Sdes	}
479126274Sdes}
480126274Sdes
481126274Sdesstatic usage()
482126274Sdes{
483126274Sdes#ifdef	COMPAT
484126274Sdes	fprintf(stderr,"Usage: quot [-nfcvha] [filesystem ...]\n");
485126274Sdes#else	/* COMPAT */
486126274Sdes	fprintf(stderr,"Usage: quot [ -acfhknv ] [ filesystem ... ]\n");
487126274Sdes#endif	/* COMPAT */
488126274Sdes	exit(1);
489126274Sdes}
490126274Sdes
491126274Sdesstatic char superblock[SBSIZE];
492126274Sdes
493126274Sdesquot(name,mp)
494126274Sdes	char *name, *mp;
495126274Sdes{
496126274Sdes	int fd;
497126274Sdes
498126274Sdes	get_inode(-1);		/* flush cache */
499126274Sdes	inituser();
500126274Sdes	initfsizes();
501126274Sdes	if ((fd = open(name,0)) < 0
502126274Sdes	    || lseek(fd,SBOFF,0) != SBOFF
503126274Sdes	    || read(fd,superblock,SBSIZE) != SBSIZE) {
504126274Sdes		perror(name);
505126274Sdes		close(fd);
506126274Sdes		return;
507126274Sdes	}
508126274Sdes	if (((struct fs *)superblock)->fs_magic != FS_MAGIC) {
509126274Sdes		fprintf(stderr,"%s: not a BSD filesystem\n",name);
510126274Sdes		close(fd);
511126274Sdes		return;
512126274Sdes	}
513126274Sdes	printf("%s:",name);
514126274Sdes	if (mp)
515126274Sdes		printf(" (%s)",mp);
516126274Sdes	putchar('\n');
517126274Sdes	(*func)(fd,superblock,name);
518126274Sdes	close(fd);
519126274Sdes}
520126274Sdes
521126274Sdesint main(argc,argv)
522126274Sdes	char **argv;
523126274Sdes{
524126274Sdes	int fd;
525126274Sdes	char all = 0;
526126274Sdes	FILE *fp;
527126274Sdes	struct statfs *mp;
528126274Sdes	struct vfsconf vfc, *vfsp;
529126274Sdes	char dev[MNAMELEN + 1];
530126274Sdes	char *nm;
531126274Sdes	int cnt;
532126274Sdes
533126274Sdes	func = douser;
534126274Sdes#ifndef	COMPAT
535126274Sdes	header = getbsize(&headerlen,&blocksize);
536126274Sdes#endif
537126274Sdes	while (--argc > 0 && **++argv == '-') {
538126274Sdes		while (*++*argv) {
539126274Sdes			switch (**argv) {
540126274Sdes			case 'n':
541126274Sdes				func = donames;
542126274Sdes				break;
543126274Sdes			case 'c':
544126274Sdes				func = dofsizes;
545126274Sdes				break;
546126274Sdes			case 'a':
547126274Sdes				all = 1;
548126274Sdes				break;
549126274Sdes			case 'f':
550126274Sdes				count = 1;
551126274Sdes				break;
552126274Sdes			case 'h':
553126274Sdes				estimate = 1;
554126274Sdes				break;
555126274Sdes#ifndef	COMPAT
556126274Sdes			case 'k':
557126274Sdes				blocksize = 1024;
558126274Sdes				break;
559126274Sdes#endif	/* COMPAT */
560126274Sdes			case 'v':
561126274Sdes				unused = 1;
562126274Sdes				break;
563126274Sdes			default:
564126274Sdes				usage();
565126274Sdes			}
566126274Sdes		}
567126274Sdes	}
568126274Sdes	if (all) {
569126274Sdes		cnt = getmntinfo(&mp,MNT_NOWAIT);
570126274Sdes		vfsp = getvfsbyname("ufs");
571126274Sdes		if (vfsp == NULL) {
572126274Sdes			fprintf(stderr, "cannot find ufs/ffs filesystem type!\n");
573126274Sdes			exit(1);
574126274Sdes		}
575126274Sdes		for (; --cnt >= 0; mp++) {
576126274Sdes			if (mp->f_type == vfsp->vfc_index) {
577126274Sdes				if (nm = strrchr(mp->f_mntfromname,'/')) {
578126274Sdes					sprintf(dev,"/dev/r%s",nm + 1);
579126274Sdes					nm = dev;
580126274Sdes				} else
581126274Sdes					nm = mp->f_mntfromname;
582126274Sdes				quot(nm,mp->f_mntonname);
583126274Sdes			}
584126274Sdes		}
585126274Sdes	}
586126274Sdes	while (--argc >= 0)
587126274Sdes		quot(*argv++,0);
588126274Sdes	return 0;
589126274Sdes}
590126274Sdes