xref: /original-bsd/usr.sbin/quotaon/quotaon.c (revision bc58f311)
1594fe2e1Smckusick /*
2*bc58f311Sbostic  * Copyright (c) 1980, 1990, 1993
3*bc58f311Sbostic  *	The Regents of the University of California.  All rights reserved.
4411fb891Sbostic  *
504cc11fdSmckusick  * This code is derived from software contributed to Berkeley by
604cc11fdSmckusick  * Robert Elz at The University of Melbourne.
704cc11fdSmckusick  *
882448923Sbostic  * %sccs.include.redist.c%
9594fe2e1Smckusick  */
10594fe2e1Smckusick 
11a793d08eSmckusick #ifndef lint
12*bc58f311Sbostic static char copyright[] =
13*bc58f311Sbostic "@(#) Copyright (c) 1980, 1990, 1993\n\
14*bc58f311Sbostic 	The Regents of the University of California.  All rights reserved.\n";
15411fb891Sbostic #endif /* not lint */
16594fe2e1Smckusick 
17594fe2e1Smckusick #ifndef lint
18*bc58f311Sbostic static char sccsid[] = "@(#)quotaon.c	8.1 (Berkeley) 06/06/93";
19411fb891Sbostic #endif /* not lint */
20cb1621a5Ssam 
21a793d08eSmckusick /*
222bc3bff3Smckusick  * Turn quota on/off for a filesystem.
23a793d08eSmckusick  */
24a793d08eSmckusick #include <sys/param.h>
25cb1621a5Ssam #include <sys/file.h>
26421c8cdaSmckusick #include <sys/mount.h>
27e48db97fSbostic #include <ufs/ufs/quota.h>
28a793d08eSmckusick #include <stdio.h>
29a793d08eSmckusick #include <fstab.h>
30a793d08eSmckusick 
31f5159bfbSmckusick char *qfname = QUOTAFILENAME;
32f5159bfbSmckusick char *qfextension[] = INITQFNAMES;
33f5159bfbSmckusick 
34a793d08eSmckusick int	aflag;		/* all file systems */
3504cc11fdSmckusick int	gflag;		/* operate on group quotas */
3604cc11fdSmckusick int	uflag;		/* operate on user quotas */
3704cc11fdSmckusick int	vflag;		/* verbose */
382bc3bff3Smckusick 
main(argc,argv)39a793d08eSmckusick main(argc, argv)
402bc3bff3Smckusick 	int argc;
41a793d08eSmckusick 	char **argv;
42a793d08eSmckusick {
43a793d08eSmckusick 	register struct fstab *fs;
44a3f6c32eSmckusick 	char ch, *qfnp, *whoami, *rindex();
4504cc11fdSmckusick 	long argnum, done = 0;
4604cc11fdSmckusick 	int i, offmode = 0, errs = 0;
4704cc11fdSmckusick 	extern char *optarg;
4804cc11fdSmckusick 	extern int optind;
49a793d08eSmckusick 
502bc3bff3Smckusick 	whoami = rindex(*argv, '/') + 1;
512bc3bff3Smckusick 	if (whoami == (char *)1)
522bc3bff3Smckusick 		whoami = *argv;
532bc3bff3Smckusick 	if (strcmp(whoami, "quotaoff") == 0)
542bc3bff3Smckusick 		offmode++;
552bc3bff3Smckusick 	else if (strcmp(whoami, "quotaon") != 0) {
562bc3bff3Smckusick 		fprintf(stderr, "Name must be quotaon or quotaoff not %s\n",
572bc3bff3Smckusick 			whoami);
582bc3bff3Smckusick 		exit(1);
592bc3bff3Smckusick 	}
6004cc11fdSmckusick 	while ((ch = getopt(argc, argv, "avug")) != EOF) {
6104cc11fdSmckusick 		switch(ch) {
6204cc11fdSmckusick 		case 'a':
63a793d08eSmckusick 			aflag++;
6404cc11fdSmckusick 			break;
6504cc11fdSmckusick 		case 'g':
6604cc11fdSmckusick 			gflag++;
6704cc11fdSmckusick 			break;
6804cc11fdSmckusick 		case 'u':
6904cc11fdSmckusick 			uflag++;
7004cc11fdSmckusick 			break;
7104cc11fdSmckusick 		case 'v':
7204cc11fdSmckusick 			vflag++;
7304cc11fdSmckusick 			break;
7404cc11fdSmckusick 		default:
7504cc11fdSmckusick 			usage(whoami);
76a793d08eSmckusick 		}
7704cc11fdSmckusick 	}
7804cc11fdSmckusick 	argc -= optind;
7904cc11fdSmckusick 	argv += optind;
8004cc11fdSmckusick 	if (argc <= 0 && !aflag)
8104cc11fdSmckusick 		usage(whoami);
8204cc11fdSmckusick 	if (!gflag && !uflag) {
8304cc11fdSmckusick 		gflag++;
8404cc11fdSmckusick 		uflag++;
85a793d08eSmckusick 	}
86a793d08eSmckusick 	setfsent();
87a793d08eSmckusick 	while ((fs = getfsent()) != NULL) {
88a3f6c32eSmckusick 		if (strcmp(fs->fs_vfstype, "ufs") ||
89a3f6c32eSmckusick 		    strcmp(fs->fs_type, FSTAB_RW))
90a3f6c32eSmckusick 			continue;
9104cc11fdSmckusick 		if (aflag) {
92a3f6c32eSmckusick 			if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
93a3f6c32eSmckusick 				errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp);
94a3f6c32eSmckusick 			if (uflag && hasquota(fs, USRQUOTA, &qfnp))
95a3f6c32eSmckusick 				errs += quotaonoff(fs, offmode, USRQUOTA, qfnp);
96a793d08eSmckusick 			continue;
9704cc11fdSmckusick 		}
9823f08f3cSmckusick 		if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 ||
9904cc11fdSmckusick 		    (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) {
10004cc11fdSmckusick 			done |= 1 << argnum;
101a3f6c32eSmckusick 			if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
102a3f6c32eSmckusick 				errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp);
103a3f6c32eSmckusick 			if (uflag && hasquota(fs, USRQUOTA, &qfnp))
104a3f6c32eSmckusick 				errs += quotaonoff(fs, offmode, USRQUOTA, qfnp);
10504cc11fdSmckusick 		}
106a793d08eSmckusick 	}
107a793d08eSmckusick 	endfsent();
108ff0a8d2eSmckusick 	for (i = 0; i < argc; i++)
109ff0a8d2eSmckusick 		if ((done & (1 << i)) == 0)
1101b9b1393Sbostic 			fprintf(stderr, "%s not found in fstab\n",
111ff0a8d2eSmckusick 				argv[i]);
1122bc3bff3Smckusick 	exit(errs);
113a793d08eSmckusick }
114a793d08eSmckusick 
usage(whoami)11504cc11fdSmckusick usage(whoami)
11604cc11fdSmckusick 	char *whoami;
117cb1621a5Ssam {
118cb1621a5Ssam 
11904cc11fdSmckusick 	fprintf(stderr, "Usage:\n\t%s [-g] [-u] [-v] -a\n", whoami);
12004cc11fdSmckusick 	fprintf(stderr, "\t%s [-g] [-u] [-v] filesys ...\n", whoami);
12104cc11fdSmckusick 	exit(1);
12204cc11fdSmckusick }
12304cc11fdSmckusick 
quotaonoff(fs,offmode,type,qfpathname)124a3f6c32eSmckusick quotaonoff(fs, offmode, type, qfpathname)
12504cc11fdSmckusick 	register struct fstab *fs;
12604cc11fdSmckusick 	int offmode, type;
127a3f6c32eSmckusick 	char *qfpathname;
12804cc11fdSmckusick {
12904cc11fdSmckusick 
130cb1621a5Ssam 	if (strcmp(fs->fs_file, "/") && readonly(fs))
131cb1621a5Ssam 		return (1);
132cb1621a5Ssam 	if (offmode) {
133a3f6c32eSmckusick 		if (quotactl(fs->fs_file, QCMD(Q_QUOTAOFF, type), 0, 0) < 0) {
134a3f6c32eSmckusick 			fprintf(stderr, "quotaoff: ");
135a3f6c32eSmckusick 			perror(fs->fs_file);
136a3f6c32eSmckusick 			return (1);
137a3f6c32eSmckusick 		}
138cb1621a5Ssam 		if (vflag)
139cb1621a5Ssam 			printf("%s: quotas turned off\n", fs->fs_file);
140cb1621a5Ssam 		return (0);
141cb1621a5Ssam 	}
142a3f6c32eSmckusick 	if (quotactl(fs->fs_file, QCMD(Q_QUOTAON, type), 0, qfpathname) < 0) {
143a3f6c32eSmckusick 		fprintf(stderr, "quotaon: using %s on", qfpathname);
144a3f6c32eSmckusick 		perror(fs->fs_file);
145a3f6c32eSmckusick 		return (1);
146a3f6c32eSmckusick 	}
147cb1621a5Ssam 	if (vflag)
14804cc11fdSmckusick 		printf("%s: %s quotas turned on\n", fs->fs_file,
14904cc11fdSmckusick 		    qfextension[type]);
150cb1621a5Ssam 	return (0);
151cb1621a5Ssam }
152cb1621a5Ssam 
15304cc11fdSmckusick /*
15404cc11fdSmckusick  * Check to see if target appears in list of size cnt.
15504cc11fdSmckusick  */
oneof(target,list,cnt)15604cc11fdSmckusick oneof(target, list, cnt)
15704cc11fdSmckusick 	register char *target, *list[];
15804cc11fdSmckusick 	int cnt;
159a793d08eSmckusick {
160a793d08eSmckusick 	register int i;
161a793d08eSmckusick 
16204cc11fdSmckusick 	for (i = 0; i < cnt; i++)
16304cc11fdSmckusick 		if (strcmp(target, list[i]) == 0)
16404cc11fdSmckusick 			return (i);
16504cc11fdSmckusick 	return (-1);
16604cc11fdSmckusick }
16704cc11fdSmckusick 
16804cc11fdSmckusick /*
16904cc11fdSmckusick  * Check to see if a particular quota is to be enabled.
17004cc11fdSmckusick  */
hasquota(fs,type,qfnamep)171a3f6c32eSmckusick hasquota(fs, type, qfnamep)
172a3f6c32eSmckusick 	register struct fstab *fs;
17304cc11fdSmckusick 	int type;
174a3f6c32eSmckusick 	char **qfnamep;
17504cc11fdSmckusick {
17604cc11fdSmckusick 	register char *opt;
177a3f6c32eSmckusick 	char *cp, *index(), *strtok();
17804cc11fdSmckusick 	static char initname, usrname[100], grpname[100];
179a3f6c32eSmckusick 	static char buf[BUFSIZ];
18004cc11fdSmckusick 
18104cc11fdSmckusick 	if (!initname) {
18204cc11fdSmckusick 		sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname);
18304cc11fdSmckusick 		sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname);
18404cc11fdSmckusick 		initname = 1;
18504cc11fdSmckusick 	}
186a3f6c32eSmckusick 	strcpy(buf, fs->fs_mntops);
18704cc11fdSmckusick 	for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) {
188a3f6c32eSmckusick 		if (cp = index(opt, '='))
189a3f6c32eSmckusick 			*cp++ = '\0';
19004cc11fdSmckusick 		if (type == USRQUOTA && strcmp(opt, usrname) == 0)
191a3f6c32eSmckusick 			break;
19204cc11fdSmckusick 		if (type == GRPQUOTA && strcmp(opt, grpname) == 0)
193a3f6c32eSmckusick 			break;
194a3f6c32eSmckusick 	}
195a3f6c32eSmckusick 	if (!opt)
196a3f6c32eSmckusick 		return (0);
197a3f6c32eSmckusick 	if (cp) {
198a3f6c32eSmckusick 		*qfnamep = cp;
199a793d08eSmckusick 		return (1);
200ff0a8d2eSmckusick 	}
201a3f6c32eSmckusick 	(void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]);
202a3f6c32eSmckusick 	*qfnamep = buf;
203a3f6c32eSmckusick 	return (1);
204a793d08eSmckusick }
205cb1621a5Ssam 
206cb1621a5Ssam /*
207cb1621a5Ssam  * Verify file system is mounted and not readonly.
208cb1621a5Ssam  */
readonly(fs)209cb1621a5Ssam readonly(fs)
210cb1621a5Ssam 	register struct fstab *fs;
211cb1621a5Ssam {
212421c8cdaSmckusick 	struct statfs fsbuf;
213cb1621a5Ssam 
214421c8cdaSmckusick 	if (statfs(fs->fs_file, &fsbuf) < 0 ||
215421c8cdaSmckusick 	    strcmp(fsbuf.f_mntonname, fs->fs_file) ||
216421c8cdaSmckusick 	    strcmp(fsbuf.f_mntfromname, fs->fs_spec)) {
217421c8cdaSmckusick 		printf("%s: not mounted\n", fs->fs_file);
218421c8cdaSmckusick 		return (1);
219421c8cdaSmckusick 	}
220aa385572Smckusick 	if (fsbuf.f_flags & MNT_RDONLY) {
221cb1621a5Ssam 		printf("%s: mounted read-only\n", fs->fs_file);
222cb1621a5Ssam 		return (1);
223cb1621a5Ssam 	}
224cb1621a5Ssam 	return (0);
225cb1621a5Ssam }
226