xref: /freebsd/usr.sbin/quotaon/quotaon.c (revision 0afa8e065e14bb8fd338d75690e0238c00167d40)
1 /*-
2  * SPDX-License-Identifier: BSD-3-Clause
3  *
4  * Copyright (c) 1980, 1990, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * Robert Elz at The University of Melbourne.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  * 3. Neither the name of the University nor the names of its contributors
19  *    may be used to endorse or promote products derived from this software
20  *    without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32  * SUCH DAMAGE.
33  */
34 
35 #if 0
36 #ifndef lint
37 static const char copyright[] =
38 "@(#) Copyright (c) 1980, 1990, 1993\n\
39 	The Regents of the University of California.  All rights reserved.\n";
40 #endif /* not lint */
41 
42 #ifndef lint
43 static char sccsid[] = "@(#)quotaon.c	8.1 (Berkeley) 6/6/93";
44 #endif /* not lint */
45 #endif
46 #include <sys/cdefs.h>
47 __FBSDID("$FreeBSD$");
48 
49 /*
50  * Turn quota on/off for a filesystem.
51  */
52 #include <sys/param.h>
53 #include <sys/file.h>
54 #include <sys/mount.h>
55 #include <ufs/ufs/quota.h>
56 #include <err.h>
57 #include <fstab.h>
58 #include <libutil.h>
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <string.h>
62 #include <unistd.h>
63 
64 static const char *qfextension[] = INITQFNAMES;
65 
66 static int	aflag;		/* all filesystems */
67 static int	gflag;		/* operate on group quotas */
68 static int	uflag;		/* operate on user quotas */
69 static int	vflag;		/* verbose */
70 
71 static int oneof(char *, char *[], int);
72 static int quotaonoff(struct fstab *fs, int, int);
73 static void usage(void);
74 
75 int
76 main(int argc, char **argv)
77 {
78 	struct fstab *fs;
79 	const char *whoami;
80 	long argnum, done = 0;
81 	int ch, i, offmode = 0, errs = 0;
82 
83 	whoami = getprogname();
84 	if (strcmp(whoami, "quotaoff") == 0)
85 		offmode++;
86 	else if (strcmp(whoami, "quotaon") != 0)
87 		errx(1, "name must be quotaon or quotaoff");
88 	while ((ch = getopt(argc, argv, "avug")) != -1) {
89 		switch(ch) {
90 		case 'a':
91 			aflag++;
92 			break;
93 		case 'g':
94 			gflag++;
95 			break;
96 		case 'u':
97 			uflag++;
98 			break;
99 		case 'v':
100 			vflag++;
101 			break;
102 		default:
103 			usage();
104 		}
105 	}
106 	argc -= optind;
107 	argv += optind;
108 	if (argc <= 0 && !aflag)
109 		usage();
110 	if (!gflag && !uflag) {
111 		gflag++;
112 		uflag++;
113 	}
114 	setfsent();
115 	while ((fs = getfsent()) != NULL) {
116 		if (strcmp(fs->fs_vfstype, "ufs") ||
117 		    strcmp(fs->fs_type, FSTAB_RW))
118 			continue;
119 		if (aflag) {
120 			if (gflag)
121 				errs += quotaonoff(fs, offmode, GRPQUOTA);
122 			if (uflag)
123 				errs += quotaonoff(fs, offmode, USRQUOTA);
124 			continue;
125 		}
126 		if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 ||
127 		    (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) {
128 			done |= 1 << argnum;
129 			if (gflag)
130 				errs += quotaonoff(fs, offmode, GRPQUOTA);
131 			if (uflag)
132 				errs += quotaonoff(fs, offmode, USRQUOTA);
133 		}
134 	}
135 	endfsent();
136 	for (i = 0; i < argc; i++)
137 		if ((done & (1 << i)) == 0)
138 			warnx("%s not found in fstab", argv[i]);
139 	exit(errs);
140 }
141 
142 static void
143 usage(void)
144 {
145 
146 	fprintf(stderr, "%s\n%s\n%s\n%s\n",
147 		"usage: quotaon [-g] [-u] [-v] -a",
148 		"       quotaon [-g] [-u] [-v] filesystem ...",
149 		"       quotaoff [-g] [-u] [-v] -a",
150 		"       quotaoff [-g] [-u] [-v] filesystem ...");
151 	exit(1);
152 }
153 
154 static int
155 quotaonoff(struct fstab *fs, int offmode, int type)
156 {
157 	struct quotafile *qf;
158 
159 	if ((qf = quota_open(fs, type, O_RDONLY)) == NULL)
160 		return (0);
161 	if (offmode) {
162 		if (quota_off(qf) != 0) {
163 			warn("%s", quota_fsname(qf));
164 			return (1);
165 		}
166 		if (vflag)
167 			printf("%s: quotas turned off\n", quota_fsname(qf));
168 		quota_close(qf);
169 		return(0);
170 	}
171 	if (quota_on(qf) != 0) {
172 		warn("using %s on %s", quota_qfname(qf), quota_fsname(qf));
173 		return (1);
174 	}
175 	if (vflag)
176 		printf("%s: %s quotas turned on with data file %s\n",
177 		    quota_fsname(qf), qfextension[type], quota_qfname(qf));
178 	quota_close(qf);
179 	return(0);
180 }
181 
182 /*
183  * Check to see if target appears in list of size cnt.
184  */
185 static int
186 oneof(char *target, char *list[], int cnt)
187 {
188 	int i;
189 
190 	for (i = 0; i < cnt; i++)
191 		if (strcmp(target, list[i]) == 0)
192 			return (i);
193 	return (-1);
194 }
195