xref: /original-bsd/usr.sbin/quotaon/quotaon.c (revision 78204ff3)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #ifndef lint
19 char copyright[] =
20 "@(#) Copyright (c) 1980 Regents of the University of California.\n\
21  All rights reserved.\n";
22 #endif /* not lint */
23 
24 #ifndef lint
25 static char sccsid[] = "@(#)quotaon.c	5.5 (Berkeley) 05/11/89";
26 #endif /* not lint */
27 
28 /*
29  * Turn quota on/off for a filesystem.
30  */
31 #include <sys/param.h>
32 #include <sys/file.h>
33 #include <stdio.h>
34 #include <fstab.h>
35 #include <mtab.h>
36 #include "pathnames.h"
37 
38 struct	mtab mtab[NMOUNT];
39 
40 int	vflag;		/* verbose */
41 int	aflag;		/* all file systems */
42 int	done;
43 int	mf;
44 
45 char	*qfname = "quotas";
46 char	quotafile[MAXPATHLEN + 1];
47 char	*index(), *rindex();
48 
49 main(argc, argv)
50 	int argc;
51 	char **argv;
52 {
53 	register struct fstab *fs;
54 	char *whoami, *rindex();
55 	int offmode = 0, errs = 0, i;
56 
57 	whoami = rindex(*argv, '/') + 1;
58 	if (whoami == (char *)1)
59 		whoami = *argv;
60 	if (strcmp(whoami, "quotaoff") == 0)
61 		offmode++;
62 	else if (strcmp(whoami, "quotaon") != 0) {
63 		fprintf(stderr, "Name must be quotaon or quotaoff not %s\n",
64 			whoami);
65 		exit(1);
66 	}
67 again:
68 	argc--, argv++;
69 	if (argc > 0 && strcmp(*argv, "-v") == 0) {
70 		vflag++;
71 		goto again;
72 	}
73 	if (argc > 0 && strcmp(*argv, "-a") == 0) {
74 		aflag++;
75 		goto again;
76 	}
77 	if (argc <= 0 && !aflag) {
78 		fprintf(stderr, "Usage:\n\t%s [-v] -a\n\t%s [-v] filesys ...\n",
79 			whoami, whoami);
80 		exit(1);
81 	}
82 	mf = open(_PATH_MTAB, O_RDONLY);
83 	if (mf < 0) {
84 		perror(_PATH_MTAB);
85 		exit(1);
86 	}
87 	(void) read(mf, (char *)mtab, sizeof (mtab));
88 	close(mf);
89 	setfsent();
90 	while ((fs = getfsent()) != NULL) {
91 		if (aflag &&
92 		    (fs->fs_type == 0 || strcmp(fs->fs_type, "rq") != 0))
93 			continue;
94 		if (!aflag &&
95 		    !(oneof(fs->fs_file, argv, argc) ||
96 		      oneof(fs->fs_spec, argv, argc)))
97 			continue;
98 		errs += quotaonoff(fs, offmode);
99 	}
100 	endfsent();
101 	for (i = 0; i < argc; i++)
102 		if ((done & (1 << i)) == 0)
103 			fprintf(stderr, "%s not found in fstab\n",
104 				argv[i]);
105 	exit(errs);
106 }
107 
108 quotaonoff(fs, offmode)
109 	register struct fstab *fs;
110 	int offmode;
111 {
112 
113 	if (strcmp(fs->fs_file, "/") && readonly(fs))
114 		return (1);
115 	if (offmode) {
116 		if (setquota(fs->fs_spec, NULL) < 0)
117 			goto bad;
118 		if (vflag)
119 			printf("%s: quotas turned off\n", fs->fs_file);
120 		changemtab(fs, FSTAB_RW);
121 		return (0);
122 	}
123 	(void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname);
124 	if (setquota(fs->fs_spec, quotafile) < 0)
125 		goto bad;
126 	if (vflag)
127 		printf("%s: quotas turned on\n", fs->fs_file);
128 	changemtab(fs, FSTAB_RQ);
129 	return (0);
130 bad:
131 	fprintf(stderr, "setquota: ");
132 	perror(fs->fs_spec);
133 	return (1);
134 }
135 
136 oneof(target, list, n)
137 	char *target, *list[];
138 	register int n;
139 {
140 	register int i;
141 
142 	for (i = 0; i < n; i++)
143 		if (strcmp(target, list[i]) == 0) {
144 			done |= 1 << i;
145 			return (1);
146 		}
147 	return (0);
148 }
149 
150 changemtab(fs, type)
151 	register struct fstab *fs;
152 	char *type;
153 {
154 	register struct mtab *mp;
155 	register char *cp;
156 
157 	cp = index(fs->fs_spec, '\0');
158 	while (*--cp == '/')
159 		*cp = '\0';
160 	cp = rindex(fs->fs_spec, '/');
161 	if (cp)
162 		cp++;
163 	else
164 		cp = fs->fs_spec;
165 	for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
166 		if (strcmp(mp->m_dname, cp) == 0)
167 			goto replace;
168 	for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
169 		if (mp->m_path[0] == '\0')
170 			goto replace;
171 	return;
172 replace:
173 	strcpy(mp->m_type, type);
174 	mp = mtab + NMOUNT - 1;
175 	while (mp > mtab && mp->m_path[0] == '\0')
176 		--mp;
177 	mf = creat(_PATH_MTAB, 0644);
178 	(void) write(mf, (char *)mtab, (mp - mtab + 1) * sizeof (struct mtab));
179 	close(mf);
180 }
181 
182 /*
183  * Verify file system is mounted and not readonly.
184  */
185 readonly(fs)
186 	register struct fstab *fs;
187 {
188 	register struct mtab *mp;
189 	register char *cp;
190 
191 	cp = index(fs->fs_spec, '\0');
192 	while (*--cp == '/')
193 		*cp = '\0';
194 	cp = rindex(fs->fs_spec, '/');
195 	if (cp)
196 		cp++;
197 	else
198 		cp = fs->fs_spec;
199 	for (mp = mtab; mp < mtab + NMOUNT; mp++) {
200 		if (mp->m_path[0] == '\0')
201 			continue;
202 		if (strcmp(cp, mp->m_dname) == 0) {
203 			if (strcmp(mp->m_type, FSTAB_RO) == 0) {
204 				printf("%s: mounted read-only\n", fs->fs_file);
205 				return (1);
206 			}
207 			return (0);
208 		}
209 	}
210 	printf("%s: not mounted\n", fs->fs_file);
211 	return (1);
212 }
213