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