Deleted Added
full compact
quotaon.c (114601) quotaon.c (124830)
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 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if 0
38#ifndef lint
39static const char copyright[] =
40"@(#) Copyright (c) 1980, 1990, 1993\n\
41 The Regents of the University of California. All rights reserved.\n";
42#endif /* not lint */
43
44#ifndef lint
45static char sccsid[] = "@(#)quotaon.c 8.1 (Berkeley) 6/6/93";
46#endif /* not lint */
47#endif
48#include <sys/cdefs.h>
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 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by the University of
19 * California, Berkeley and its contributors.
20 * 4. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 */
36
37#if 0
38#ifndef lint
39static const char copyright[] =
40"@(#) Copyright (c) 1980, 1990, 1993\n\
41 The Regents of the University of California. All rights reserved.\n";
42#endif /* not lint */
43
44#ifndef lint
45static char sccsid[] = "@(#)quotaon.c 8.1 (Berkeley) 6/6/93";
46#endif /* not lint */
47#endif
48#include <sys/cdefs.h>
49__FBSDID("$FreeBSD: head/usr.sbin/quotaon/quotaon.c 114601 2003-05-03 21:06:42Z obrien $");
49__FBSDID("$FreeBSD: head/usr.sbin/quotaon/quotaon.c 124830 2004-01-22 07:23:36Z grehan $");
50
51/*
52 * Turn quota on/off for a filesystem.
53 */
54#include <sys/param.h>
55#include <sys/file.h>
56#include <sys/mount.h>
57#include <ufs/ufs/quota.h>
58#include <err.h>
59#include <fstab.h>
60#include <stdio.h>
61#include <stdlib.h>
62#include <string.h>
63#include <unistd.h>
64
65const char *qfname = QUOTAFILENAME;
66const char *qfextension[] = INITQFNAMES;
67
68int aflag; /* all filesystems */
69int gflag; /* operate on group quotas */
70int uflag; /* operate on user quotas */
71int vflag; /* verbose */
72
73int hasquota(struct fstab *, int, char **);
74int oneof(char *, char *[], int);
75int quotaonoff(struct fstab *fs, int, int, char *);
76int readonly(struct fstab *);
77static void usage(void);
78
79int
80main(int argc, char **argv)
81{
82 register struct fstab *fs;
50
51/*
52 * Turn quota on/off for a filesystem.
53 */
54#include <sys/param.h>
55#include <sys/file.h>
56#include <sys/mount.h>
57#include <ufs/ufs/quota.h>
58#include <err.h>
59#include <fstab.h>
60#include <stdio.h>
61#include <stdlib.h>
62#include <string.h>
63#include <unistd.h>
64
65const char *qfname = QUOTAFILENAME;
66const char *qfextension[] = INITQFNAMES;
67
68int aflag; /* all filesystems */
69int gflag; /* operate on group quotas */
70int uflag; /* operate on user quotas */
71int vflag; /* verbose */
72
73int hasquota(struct fstab *, int, char **);
74int oneof(char *, char *[], int);
75int quotaonoff(struct fstab *fs, int, int, char *);
76int readonly(struct fstab *);
77static void usage(void);
78
79int
80main(int argc, char **argv)
81{
82 register struct fstab *fs;
83 char ch, *qfnp, *whoami;
83 char *qfnp, *whoami;
84 long argnum, done = 0;
84 long argnum, done = 0;
85 int i, offmode = 0, errs = 0;
85 int ch, i, offmode = 0, errs = 0;
86
87 whoami = rindex(*argv, '/') + 1;
88 if (whoami == (char *)1)
89 whoami = *argv;
90 if (strcmp(whoami, "quotaoff") == 0)
91 offmode++;
92 else if (strcmp(whoami, "quotaon") != 0)
93 errx(1, "name must be quotaon or quotaoff");
94 while ((ch = getopt(argc, argv, "avug")) != -1) {
95 switch(ch) {
96 case 'a':
97 aflag++;
98 break;
99 case 'g':
100 gflag++;
101 break;
102 case 'u':
103 uflag++;
104 break;
105 case 'v':
106 vflag++;
107 break;
108 default:
109 usage();
110 }
111 }
112 argc -= optind;
113 argv += optind;
114 if (argc <= 0 && !aflag)
115 usage();
116 if (!gflag && !uflag) {
117 gflag++;
118 uflag++;
119 }
120 setfsent();
121 while ((fs = getfsent()) != NULL) {
122 if (strcmp(fs->fs_vfstype, "ufs") ||
123 strcmp(fs->fs_type, FSTAB_RW))
124 continue;
125 if (aflag) {
126 if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
127 errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp);
128 if (uflag && hasquota(fs, USRQUOTA, &qfnp))
129 errs += quotaonoff(fs, offmode, USRQUOTA, qfnp);
130 continue;
131 }
132 if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 ||
133 (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) {
134 done |= 1 << argnum;
135 if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
136 errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp);
137 if (uflag && hasquota(fs, USRQUOTA, &qfnp))
138 errs += quotaonoff(fs, offmode, USRQUOTA, qfnp);
139 }
140 }
141 endfsent();
142 for (i = 0; i < argc; i++)
143 if ((done & (1 << i)) == 0)
144 warnx("%s not found in fstab", argv[i]);
145 exit(errs);
146}
147
148static void
149usage()
150{
151
152 fprintf(stderr, "%s\n%s\n%s\n%s\n",
153 "usage: quotaon [-g] [-u] [-v] -a",
154 " quotaon [-g] [-u] [-v] filesystem ...",
155 " quotaoff [-g] [-u] [-v] -a",
156 " quotaoff [-g] [-u] [-v] filesystem ...");
157 exit(1);
158}
159
160int
161quotaonoff(fs, offmode, type, qfpathname)
162 register struct fstab *fs;
163 int offmode, type;
164 char *qfpathname;
165{
166
167 if (strcmp(fs->fs_file, "/") && readonly(fs))
168 return (1);
169 if (offmode) {
170 if (quotactl(fs->fs_file, QCMD(Q_QUOTAOFF, type), 0, 0) < 0) {
171 warn("%s", fs->fs_file);
172 return (1);
173 }
174 if (vflag)
175 printf("%s: quotas turned off\n", fs->fs_file);
176 return (0);
177 }
178 if (quotactl(fs->fs_file, QCMD(Q_QUOTAON, type), 0, qfpathname) < 0) {
179 warnx("using %s on", qfpathname);
180 warn("%s", fs->fs_file);
181 return (1);
182 }
183 if (vflag)
184 printf("%s: %s quotas turned on\n", fs->fs_file,
185 qfextension[type]);
186 return (0);
187}
188
189/*
190 * Check to see if target appears in list of size cnt.
191 */
192int
193oneof(target, list, cnt)
194 register char *target, *list[];
195 int cnt;
196{
197 register int i;
198
199 for (i = 0; i < cnt; i++)
200 if (strcmp(target, list[i]) == 0)
201 return (i);
202 return (-1);
203}
204
205/*
206 * Check to see if a particular quota is to be enabled.
207 */
208int
209hasquota(fs, type, qfnamep)
210 register struct fstab *fs;
211 int type;
212 char **qfnamep;
213{
214 register char *opt;
215 char *cp;
216 static char initname, usrname[100], grpname[100];
217 static char buf[BUFSIZ];
218
219 if (!initname) {
220 sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname);
221 sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname);
222 initname = 1;
223 }
224 strcpy(buf, fs->fs_mntops);
225 for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) {
226 if ((cp = index(opt, '=')))
227 *cp++ = '\0';
228 if (type == USRQUOTA && strcmp(opt, usrname) == 0)
229 break;
230 if (type == GRPQUOTA && strcmp(opt, grpname) == 0)
231 break;
232 }
233 if (!opt)
234 return (0);
235 if (cp) {
236 *qfnamep = cp;
237 return (1);
238 }
239 (void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]);
240 *qfnamep = buf;
241 return (1);
242}
243
244/*
245 * Verify filesystem is mounted and not readonly.
246 */
247int
248readonly(fs)
249 register struct fstab *fs;
250{
251 struct statfs fsbuf;
252
253 if (statfs(fs->fs_file, &fsbuf) < 0 ||
254 strcmp(fsbuf.f_mntonname, fs->fs_file) ||
255 strcmp(fsbuf.f_mntfromname, fs->fs_spec)) {
256 printf("%s: not mounted\n", fs->fs_file);
257 return (1);
258 }
259 if (fsbuf.f_flags & MNT_RDONLY) {
260 printf("%s: mounted read-only\n", fs->fs_file);
261 return (1);
262 }
263 return (0);
264}
86
87 whoami = rindex(*argv, '/') + 1;
88 if (whoami == (char *)1)
89 whoami = *argv;
90 if (strcmp(whoami, "quotaoff") == 0)
91 offmode++;
92 else if (strcmp(whoami, "quotaon") != 0)
93 errx(1, "name must be quotaon or quotaoff");
94 while ((ch = getopt(argc, argv, "avug")) != -1) {
95 switch(ch) {
96 case 'a':
97 aflag++;
98 break;
99 case 'g':
100 gflag++;
101 break;
102 case 'u':
103 uflag++;
104 break;
105 case 'v':
106 vflag++;
107 break;
108 default:
109 usage();
110 }
111 }
112 argc -= optind;
113 argv += optind;
114 if (argc <= 0 && !aflag)
115 usage();
116 if (!gflag && !uflag) {
117 gflag++;
118 uflag++;
119 }
120 setfsent();
121 while ((fs = getfsent()) != NULL) {
122 if (strcmp(fs->fs_vfstype, "ufs") ||
123 strcmp(fs->fs_type, FSTAB_RW))
124 continue;
125 if (aflag) {
126 if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
127 errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp);
128 if (uflag && hasquota(fs, USRQUOTA, &qfnp))
129 errs += quotaonoff(fs, offmode, USRQUOTA, qfnp);
130 continue;
131 }
132 if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 ||
133 (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) {
134 done |= 1 << argnum;
135 if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
136 errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp);
137 if (uflag && hasquota(fs, USRQUOTA, &qfnp))
138 errs += quotaonoff(fs, offmode, USRQUOTA, qfnp);
139 }
140 }
141 endfsent();
142 for (i = 0; i < argc; i++)
143 if ((done & (1 << i)) == 0)
144 warnx("%s not found in fstab", argv[i]);
145 exit(errs);
146}
147
148static void
149usage()
150{
151
152 fprintf(stderr, "%s\n%s\n%s\n%s\n",
153 "usage: quotaon [-g] [-u] [-v] -a",
154 " quotaon [-g] [-u] [-v] filesystem ...",
155 " quotaoff [-g] [-u] [-v] -a",
156 " quotaoff [-g] [-u] [-v] filesystem ...");
157 exit(1);
158}
159
160int
161quotaonoff(fs, offmode, type, qfpathname)
162 register struct fstab *fs;
163 int offmode, type;
164 char *qfpathname;
165{
166
167 if (strcmp(fs->fs_file, "/") && readonly(fs))
168 return (1);
169 if (offmode) {
170 if (quotactl(fs->fs_file, QCMD(Q_QUOTAOFF, type), 0, 0) < 0) {
171 warn("%s", fs->fs_file);
172 return (1);
173 }
174 if (vflag)
175 printf("%s: quotas turned off\n", fs->fs_file);
176 return (0);
177 }
178 if (quotactl(fs->fs_file, QCMD(Q_QUOTAON, type), 0, qfpathname) < 0) {
179 warnx("using %s on", qfpathname);
180 warn("%s", fs->fs_file);
181 return (1);
182 }
183 if (vflag)
184 printf("%s: %s quotas turned on\n", fs->fs_file,
185 qfextension[type]);
186 return (0);
187}
188
189/*
190 * Check to see if target appears in list of size cnt.
191 */
192int
193oneof(target, list, cnt)
194 register char *target, *list[];
195 int cnt;
196{
197 register int i;
198
199 for (i = 0; i < cnt; i++)
200 if (strcmp(target, list[i]) == 0)
201 return (i);
202 return (-1);
203}
204
205/*
206 * Check to see if a particular quota is to be enabled.
207 */
208int
209hasquota(fs, type, qfnamep)
210 register struct fstab *fs;
211 int type;
212 char **qfnamep;
213{
214 register char *opt;
215 char *cp;
216 static char initname, usrname[100], grpname[100];
217 static char buf[BUFSIZ];
218
219 if (!initname) {
220 sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname);
221 sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname);
222 initname = 1;
223 }
224 strcpy(buf, fs->fs_mntops);
225 for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) {
226 if ((cp = index(opt, '=')))
227 *cp++ = '\0';
228 if (type == USRQUOTA && strcmp(opt, usrname) == 0)
229 break;
230 if (type == GRPQUOTA && strcmp(opt, grpname) == 0)
231 break;
232 }
233 if (!opt)
234 return (0);
235 if (cp) {
236 *qfnamep = cp;
237 return (1);
238 }
239 (void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]);
240 *qfnamep = buf;
241 return (1);
242}
243
244/*
245 * Verify filesystem is mounted and not readonly.
246 */
247int
248readonly(fs)
249 register struct fstab *fs;
250{
251 struct statfs fsbuf;
252
253 if (statfs(fs->fs_file, &fsbuf) < 0 ||
254 strcmp(fsbuf.f_mntonname, fs->fs_file) ||
255 strcmp(fsbuf.f_mntfromname, fs->fs_spec)) {
256 printf("%s: not mounted\n", fs->fs_file);
257 return (1);
258 }
259 if (fsbuf.f_flags & MNT_RDONLY) {
260 printf("%s: mounted read-only\n", fs->fs_file);
261 return (1);
262 }
263 return (0);
264}