2 * Copyright (c) 1980, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
5 * This code is derived from software contributed to Berkeley by
6 * Robert Elz at The University of Melbourne.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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 * 4. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 static const char copyright[] =
36 "@(#) Copyright (c) 1980, 1990, 1993\n\
37 The Regents of the University of California. All rights reserved.\n";
41 static char sccsid[] = "@(#)quotaon.c 8.1 (Berkeley) 6/6/93";
44 #include <sys/cdefs.h>
45 __FBSDID("$FreeBSD$");
48 * Turn quota on/off for a filesystem.
50 #include <sys/param.h>
52 #include <sys/mount.h>
53 #include <ufs/ufs/quota.h>
61 const char *qfname = QUOTAFILENAME;
62 const char *qfextension[] = INITQFNAMES;
64 int aflag; /* all filesystems */
65 int gflag; /* operate on group quotas */
66 int uflag; /* operate on user quotas */
67 int vflag; /* verbose */
69 int hasquota(struct fstab *, int, char **);
70 int oneof(char *, char *[], int);
71 int quotaonoff(struct fstab *fs, int, int, char *);
72 int readonly(struct fstab *);
73 static void usage(void);
76 main(int argc, char **argv)
78 register struct fstab *fs;
80 long argnum, done = 0;
81 int ch, i, offmode = 0, errs = 0;
83 whoami = rindex(*argv, '/') + 1;
84 if (whoami == (char *)1)
86 if (strcmp(whoami, "quotaoff") == 0)
88 else if (strcmp(whoami, "quotaon") != 0)
89 errx(1, "name must be quotaon or quotaoff");
90 while ((ch = getopt(argc, argv, "avug")) != -1) {
110 if (argc <= 0 && !aflag)
112 if (!gflag && !uflag) {
117 while ((fs = getfsent()) != NULL) {
118 if (strcmp(fs->fs_vfstype, "ufs") ||
119 strcmp(fs->fs_type, FSTAB_RW))
122 if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
123 errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp);
124 if (uflag && hasquota(fs, USRQUOTA, &qfnp))
125 errs += quotaonoff(fs, offmode, USRQUOTA, qfnp);
128 if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 ||
129 (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) {
131 if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
132 errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp);
133 if (uflag && hasquota(fs, USRQUOTA, &qfnp))
134 errs += quotaonoff(fs, offmode, USRQUOTA, qfnp);
138 for (i = 0; i < argc; i++)
139 if ((done & (1 << i)) == 0)
140 warnx("%s not found in fstab", argv[i]);
148 fprintf(stderr, "%s\n%s\n%s\n%s\n",
149 "usage: quotaon [-g] [-u] [-v] -a",
150 " quotaon [-g] [-u] [-v] filesystem ...",
151 " quotaoff [-g] [-u] [-v] -a",
152 " quotaoff [-g] [-u] [-v] filesystem ...");
157 quotaonoff(fs, offmode, type, qfpathname)
158 register struct fstab *fs;
163 if (strcmp(fs->fs_file, "/") && readonly(fs))
166 if (quotactl(fs->fs_file, QCMD(Q_QUOTAOFF, type), 0, 0) < 0) {
167 warn("%s", fs->fs_file);
171 printf("%s: quotas turned off\n", fs->fs_file);
174 if (quotactl(fs->fs_file, QCMD(Q_QUOTAON, type), 0, qfpathname) < 0) {
175 warnx("using %s on", qfpathname);
176 warn("%s", fs->fs_file);
180 printf("%s: %s quotas turned on with data file %s\n",
181 fs->fs_file, qfextension[type], qfpathname);
186 * Check to see if target appears in list of size cnt.
189 oneof(target, list, cnt)
190 register char *target, *list[];
195 for (i = 0; i < cnt; i++)
196 if (strcmp(target, list[i]) == 0)
202 * Check to see if a particular quota is to be enabled.
205 hasquota(fs, type, qfnamep)
213 static char initname, usrname[100], grpname[100];
214 static char buf[BUFSIZ];
217 (void)snprintf(usrname, sizeof(usrname), "%s%s",
218 qfextension[USRQUOTA], qfname);
219 (void)snprintf(grpname, sizeof(grpname), "%s%s",
220 qfextension[GRPQUOTA], qfname);
223 strcpy(buf, fs->fs_mntops);
224 for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) {
225 if ((cp = index(opt, '=')))
227 if (type == USRQUOTA && strcmp(opt, usrname) == 0)
229 if (type == GRPQUOTA && strcmp(opt, grpname) == 0)
237 (void)snprintf(buf, sizeof(buf), "%s/%s.%s", fs->fs_file,
238 qfname, qfextension[type]);
241 if (statfs(fs->fs_file, &sfb) != 0) {
242 warn("cannot statfs mount point %s", fs->fs_file);
245 if (strcmp(fs->fs_file, sfb.f_mntonname)) {
246 warnx("%s not mounted for %s quotas", fs->fs_file,
247 type == USRQUOTA ? "user" : "group");
254 * Verify filesystem is mounted and not readonly.
258 register struct fstab *fs;
262 if (statfs(fs->fs_file, &fsbuf) < 0 ||
263 strcmp(fsbuf.f_mntonname, fs->fs_file) ||
264 strcmp(fsbuf.f_mntfromname, fs->fs_spec)) {
265 printf("%s: not mounted\n", fs->fs_file);
268 if (fsbuf.f_flags & MNT_RDONLY) {
269 printf("%s: mounted read-only\n", fs->fs_file);