xref: /original-bsd/usr.sbin/quotaon/quotaon.c (revision 28301386)
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.4 (Berkeley) 06/18/88";
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 
37 struct	mtab mtab[NMOUNT];
38 
39 int	vflag;		/* verbose */
40 int	aflag;		/* all file systems */
41 int	done;
42 int	mf;
43 
44 char	*qfname = "quotas";
45 char	quotafile[MAXPATHLEN + 1];
46 char	*index(), *rindex();
47 
48 main(argc, argv)
49 	int argc;
50 	char **argv;
51 {
52 	register struct fstab *fs;
53 	char *whoami, *rindex();
54 	int offmode = 0, errs = 0, i;
55 
56 	whoami = rindex(*argv, '/') + 1;
57 	if (whoami == (char *)1)
58 		whoami = *argv;
59 	if (strcmp(whoami, "quotaoff") == 0)
60 		offmode++;
61 	else if (strcmp(whoami, "quotaon") != 0) {
62 		fprintf(stderr, "Name must be quotaon or quotaoff not %s\n",
63 			whoami);
64 		exit(1);
65 	}
66 again:
67 	argc--, argv++;
68 	if (argc > 0 && strcmp(*argv, "-v") == 0) {
69 		vflag++;
70 		goto again;
71 	}
72 	if (argc > 0 && strcmp(*argv, "-a") == 0) {
73 		aflag++;
74 		goto again;
75 	}
76 	if (argc <= 0 && !aflag) {
77 		fprintf(stderr, "Usage:\n\t%s [-v] -a\n\t%s [-v] filesys ...\n",
78 			whoami, whoami);
79 		exit(1);
80 	}
81 	mf = open("/etc/mtab", O_RDONLY);
82 	if (mf < 0) {
83 		perror("/etc/mtab");
84 		exit(1);
85 	}
86 	(void) read(mf, (char *)mtab, sizeof (mtab));
87 	close(mf);
88 	setfsent();
89 	while ((fs = getfsent()) != NULL) {
90 		if (aflag &&
91 		    (fs->fs_type == 0 || strcmp(fs->fs_type, "rq") != 0))
92 			continue;
93 		if (!aflag &&
94 		    !(oneof(fs->fs_file, argv, argc) ||
95 		      oneof(fs->fs_spec, argv, argc)))
96 			continue;
97 		errs += quotaonoff(fs, offmode);
98 	}
99 	endfsent();
100 	for (i = 0; i < argc; i++)
101 		if ((done & (1 << i)) == 0)
102 			fprintf(stderr, "%s not found in /etc/fstab\n",
103 				argv[i]);
104 	exit(errs);
105 }
106 
107 quotaonoff(fs, offmode)
108 	register struct fstab *fs;
109 	int offmode;
110 {
111 
112 	if (strcmp(fs->fs_file, "/") && readonly(fs))
113 		return (1);
114 	if (offmode) {
115 		if (setquota(fs->fs_spec, NULL) < 0)
116 			goto bad;
117 		if (vflag)
118 			printf("%s: quotas turned off\n", fs->fs_file);
119 		changemtab(fs, FSTAB_RW);
120 		return (0);
121 	}
122 	(void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname);
123 	if (setquota(fs->fs_spec, quotafile) < 0)
124 		goto bad;
125 	if (vflag)
126 		printf("%s: quotas turned on\n", fs->fs_file);
127 	changemtab(fs, FSTAB_RQ);
128 	return (0);
129 bad:
130 	fprintf(stderr, "setquota: ");
131 	perror(fs->fs_spec);
132 	return (1);
133 }
134 
135 oneof(target, list, n)
136 	char *target, *list[];
137 	register int n;
138 {
139 	register int i;
140 
141 	for (i = 0; i < n; i++)
142 		if (strcmp(target, list[i]) == 0) {
143 			done |= 1 << i;
144 			return (1);
145 		}
146 	return (0);
147 }
148 
149 changemtab(fs, type)
150 	register struct fstab *fs;
151 	char *type;
152 {
153 	register struct mtab *mp;
154 	register char *cp;
155 
156 	cp = index(fs->fs_spec, '\0');
157 	while (*--cp == '/')
158 		*cp = '\0';
159 	cp = rindex(fs->fs_spec, '/');
160 	if (cp)
161 		cp++;
162 	else
163 		cp = fs->fs_spec;
164 	for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
165 		if (strcmp(mp->m_dname, cp) == 0)
166 			goto replace;
167 	for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
168 		if (mp->m_path[0] == '\0')
169 			goto replace;
170 	return;
171 replace:
172 	strcpy(mp->m_type, type);
173 	mp = mtab + NMOUNT - 1;
174 	while (mp > mtab && mp->m_path[0] == '\0')
175 		--mp;
176 	mf = creat("/etc/mtab", 0644);
177 	(void) write(mf, (char *)mtab, (mp - mtab + 1) * sizeof (struct mtab));
178 	close(mf);
179 }
180 
181 /*
182  * Verify file system is mounted and not readonly.
183  */
184 readonly(fs)
185 	register struct fstab *fs;
186 {
187 	register struct mtab *mp;
188 	register char *cp;
189 
190 	cp = index(fs->fs_spec, '\0');
191 	while (*--cp == '/')
192 		*cp = '\0';
193 	cp = rindex(fs->fs_spec, '/');
194 	if (cp)
195 		cp++;
196 	else
197 		cp = fs->fs_spec;
198 	for (mp = mtab; mp < mtab + NMOUNT; mp++) {
199 		if (mp->m_path[0] == '\0')
200 			continue;
201 		if (strcmp(cp, mp->m_dname) == 0) {
202 			if (strcmp(mp->m_type, FSTAB_RO) == 0) {
203 				printf("%s: mounted read-only\n", fs->fs_file);
204 				return (1);
205 			}
206 			return (0);
207 		}
208 	}
209 	printf("%s: not mounted\n", fs->fs_file);
210 	return (1);
211 }
212