xref: /original-bsd/usr.sbin/quotaon/quotaon.c (revision c3e32dec)
1 /*
2  * Copyright (c) 1980, 1990, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Robert Elz at The University of Melbourne.
7  *
8  * %sccs.include.redist.c%
9  */
10 
11 #ifndef lint
12 static char copyright[] =
13 "@(#) Copyright (c) 1980, 1990, 1993\n\
14 	The Regents of the University of California.  All rights reserved.\n";
15 #endif /* not lint */
16 
17 #ifndef lint
18 static char sccsid[] = "@(#)quotaon.c	8.1 (Berkeley) 06/06/93";
19 #endif /* not lint */
20 
21 /*
22  * Turn quota on/off for a filesystem.
23  */
24 #include <sys/param.h>
25 #include <sys/file.h>
26 #include <sys/mount.h>
27 #include <ufs/ufs/quota.h>
28 #include <stdio.h>
29 #include <fstab.h>
30 
31 char *qfname = QUOTAFILENAME;
32 char *qfextension[] = INITQFNAMES;
33 
34 int	aflag;		/* all file systems */
35 int	gflag;		/* operate on group quotas */
36 int	uflag;		/* operate on user quotas */
37 int	vflag;		/* verbose */
38 
39 main(argc, argv)
40 	int argc;
41 	char **argv;
42 {
43 	register struct fstab *fs;
44 	char ch, *qfnp, *whoami, *rindex();
45 	long argnum, done = 0;
46 	int i, offmode = 0, errs = 0;
47 	extern char *optarg;
48 	extern int optind;
49 
50 	whoami = rindex(*argv, '/') + 1;
51 	if (whoami == (char *)1)
52 		whoami = *argv;
53 	if (strcmp(whoami, "quotaoff") == 0)
54 		offmode++;
55 	else if (strcmp(whoami, "quotaon") != 0) {
56 		fprintf(stderr, "Name must be quotaon or quotaoff not %s\n",
57 			whoami);
58 		exit(1);
59 	}
60 	while ((ch = getopt(argc, argv, "avug")) != EOF) {
61 		switch(ch) {
62 		case 'a':
63 			aflag++;
64 			break;
65 		case 'g':
66 			gflag++;
67 			break;
68 		case 'u':
69 			uflag++;
70 			break;
71 		case 'v':
72 			vflag++;
73 			break;
74 		default:
75 			usage(whoami);
76 		}
77 	}
78 	argc -= optind;
79 	argv += optind;
80 	if (argc <= 0 && !aflag)
81 		usage(whoami);
82 	if (!gflag && !uflag) {
83 		gflag++;
84 		uflag++;
85 	}
86 	setfsent();
87 	while ((fs = getfsent()) != NULL) {
88 		if (strcmp(fs->fs_vfstype, "ufs") ||
89 		    strcmp(fs->fs_type, FSTAB_RW))
90 			continue;
91 		if (aflag) {
92 			if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
93 				errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp);
94 			if (uflag && hasquota(fs, USRQUOTA, &qfnp))
95 				errs += quotaonoff(fs, offmode, USRQUOTA, qfnp);
96 			continue;
97 		}
98 		if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 ||
99 		    (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) {
100 			done |= 1 << argnum;
101 			if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
102 				errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp);
103 			if (uflag && hasquota(fs, USRQUOTA, &qfnp))
104 				errs += quotaonoff(fs, offmode, USRQUOTA, qfnp);
105 		}
106 	}
107 	endfsent();
108 	for (i = 0; i < argc; i++)
109 		if ((done & (1 << i)) == 0)
110 			fprintf(stderr, "%s not found in fstab\n",
111 				argv[i]);
112 	exit(errs);
113 }
114 
115 usage(whoami)
116 	char *whoami;
117 {
118 
119 	fprintf(stderr, "Usage:\n\t%s [-g] [-u] [-v] -a\n", whoami);
120 	fprintf(stderr, "\t%s [-g] [-u] [-v] filesys ...\n", whoami);
121 	exit(1);
122 }
123 
124 quotaonoff(fs, offmode, type, qfpathname)
125 	register struct fstab *fs;
126 	int offmode, type;
127 	char *qfpathname;
128 {
129 
130 	if (strcmp(fs->fs_file, "/") && readonly(fs))
131 		return (1);
132 	if (offmode) {
133 		if (quotactl(fs->fs_file, QCMD(Q_QUOTAOFF, type), 0, 0) < 0) {
134 			fprintf(stderr, "quotaoff: ");
135 			perror(fs->fs_file);
136 			return (1);
137 		}
138 		if (vflag)
139 			printf("%s: quotas turned off\n", fs->fs_file);
140 		return (0);
141 	}
142 	if (quotactl(fs->fs_file, QCMD(Q_QUOTAON, type), 0, qfpathname) < 0) {
143 		fprintf(stderr, "quotaon: using %s on", qfpathname);
144 		perror(fs->fs_file);
145 		return (1);
146 	}
147 	if (vflag)
148 		printf("%s: %s quotas turned on\n", fs->fs_file,
149 		    qfextension[type]);
150 	return (0);
151 }
152 
153 /*
154  * Check to see if target appears in list of size cnt.
155  */
156 oneof(target, list, cnt)
157 	register char *target, *list[];
158 	int cnt;
159 {
160 	register int i;
161 
162 	for (i = 0; i < cnt; i++)
163 		if (strcmp(target, list[i]) == 0)
164 			return (i);
165 	return (-1);
166 }
167 
168 /*
169  * Check to see if a particular quota is to be enabled.
170  */
171 hasquota(fs, type, qfnamep)
172 	register struct fstab *fs;
173 	int type;
174 	char **qfnamep;
175 {
176 	register char *opt;
177 	char *cp, *index(), *strtok();
178 	static char initname, usrname[100], grpname[100];
179 	static char buf[BUFSIZ];
180 
181 	if (!initname) {
182 		sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname);
183 		sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname);
184 		initname = 1;
185 	}
186 	strcpy(buf, fs->fs_mntops);
187 	for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) {
188 		if (cp = index(opt, '='))
189 			*cp++ = '\0';
190 		if (type == USRQUOTA && strcmp(opt, usrname) == 0)
191 			break;
192 		if (type == GRPQUOTA && strcmp(opt, grpname) == 0)
193 			break;
194 	}
195 	if (!opt)
196 		return (0);
197 	if (cp) {
198 		*qfnamep = cp;
199 		return (1);
200 	}
201 	(void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]);
202 	*qfnamep = buf;
203 	return (1);
204 }
205 
206 /*
207  * Verify file system is mounted and not readonly.
208  */
209 readonly(fs)
210 	register struct fstab *fs;
211 {
212 	struct statfs fsbuf;
213 
214 	if (statfs(fs->fs_file, &fsbuf) < 0 ||
215 	    strcmp(fsbuf.f_mntonname, fs->fs_file) ||
216 	    strcmp(fsbuf.f_mntfromname, fs->fs_spec)) {
217 		printf("%s: not mounted\n", fs->fs_file);
218 		return (1);
219 	}
220 	if (fsbuf.f_flags & MNT_RDONLY) {
221 		printf("%s: mounted read-only\n", fs->fs_file);
222 		return (1);
223 	}
224 	return (0);
225 }
226