xref: /original-bsd/usr.sbin/quotaon/quotaon.c (revision 5839a6df)
1 /*
2  * Copyright (c) 1980 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  */
6 
7 #ifndef lint
8 char copyright[] =
9 "@(#) Copyright (c) 1980 Regents of the University of California.\n\
10  All rights reserved.\n";
11 #endif not lint
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)quotaon.c	5.2 (Berkeley) 08/08/85";
15 #endif not lint
16 
17 /*
18  * Turn quota on/off for a filesystem.
19  */
20 #include <sys/param.h>
21 #include <sys/file.h>
22 #include <stdio.h>
23 #include <fstab.h>
24 #include <mtab.h>
25 
26 struct	mtab mtab[NMOUNT];
27 
28 int	vflag;		/* verbose */
29 int	aflag;		/* all file systems */
30 int	done;
31 int	mf;
32 
33 char	*qfname = "quotas";
34 char	quotafile[MAXPATHLEN + 1];
35 char	*index(), *rindex();
36 
37 main(argc, argv)
38 	int argc;
39 	char **argv;
40 {
41 	register struct fstab *fs;
42 	char *whoami, *rindex();
43 	int offmode = 0, errs = 0, i;
44 
45 	whoami = rindex(*argv, '/') + 1;
46 	if (whoami == (char *)1)
47 		whoami = *argv;
48 	if (strcmp(whoami, "quotaoff") == 0)
49 		offmode++;
50 	else if (strcmp(whoami, "quotaon") != 0) {
51 		fprintf(stderr, "Name must be quotaon or quotaoff not %s\n",
52 			whoami);
53 		exit(1);
54 	}
55 again:
56 	argc--, argv++;
57 	if (argc > 0 && strcmp(*argv, "-v") == 0) {
58 		vflag++;
59 		goto again;
60 	}
61 	if (argc > 0 && strcmp(*argv, "-a") == 0) {
62 		aflag++;
63 		goto again;
64 	}
65 	if (argc <= 0 && !aflag) {
66 		fprintf(stderr, "Usage:\n\t%s [-v] -a\n\t%s [-v] filesys ...\n",
67 			whoami, whoami);
68 		exit(1);
69 	}
70 	mf = open("/etc/mtab", O_RDONLY);
71 	if (mf < 0) {
72 		perror("/etc/mtab");
73 		exit(1);
74 	}
75 	(void) read(mf, (char *)mtab, sizeof (mtab));
76 	close(mf);
77 	setfsent();
78 	while ((fs = getfsent()) != NULL) {
79 		if (aflag &&
80 		    (fs->fs_type == 0 || strcmp(fs->fs_type, "rq") != 0))
81 			continue;
82 		if (!aflag &&
83 		    !(oneof(fs->fs_file, argv, argc) ||
84 		      oneof(fs->fs_spec, argv, argc)))
85 			continue;
86 		errs += quotaonoff(fs, offmode);
87 	}
88 	endfsent();
89 	for (i = 0; i < argc; i++)
90 		if ((done & (1 << i)) == 0)
91 			fprintf(stderr, "%s not found in /etc/fstab\n",
92 				argv[i]);
93 	exit(errs);
94 }
95 
96 quotaonoff(fs, offmode)
97 	register struct fstab *fs;
98 	int offmode;
99 {
100 
101 	if (strcmp(fs->fs_file, "/") && readonly(fs))
102 		return (1);
103 	if (offmode) {
104 		if (setquota(fs->fs_spec, NULL) < 0)
105 			goto bad;
106 		if (vflag)
107 			printf("%s: quotas turned off\n", fs->fs_file);
108 		changemtab(fs, FSTAB_RW);
109 		return (0);
110 	}
111 	(void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname);
112 	if (setquota(fs->fs_spec, quotafile) < 0)
113 		goto bad;
114 	if (vflag)
115 		printf("%s: quotas turned on\n", fs->fs_file);
116 	changemtab(fs, FSTAB_RQ);
117 	return (0);
118 bad:
119 	fprintf(stderr, "setquota: ");
120 	perror(fs->fs_spec);
121 	return (1);
122 }
123 
124 oneof(target, list, n)
125 	char *target, *list[];
126 	register int n;
127 {
128 	register int i;
129 
130 	for (i = 0; i < n; i++)
131 		if (strcmp(target, list[i]) == 0) {
132 			done |= 1 << i;
133 			return (1);
134 		}
135 	return (0);
136 }
137 
138 changemtab(fs, type)
139 	register struct fstab *fs;
140 	char *type;
141 {
142 	register struct mtab *mp;
143 	register char *cp;
144 
145 	cp = index(fs->fs_spec, '\0');
146 	while (*--cp == '/')
147 		*cp = '\0';
148 	cp = rindex(fs->fs_spec, '/');
149 	if (cp)
150 		cp++;
151 	else
152 		cp = fs->fs_spec;
153 	for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
154 		if (strcmp(mp->m_dname, cp) == 0)
155 			goto replace;
156 	for (mp = mtab; mp < &mtab[NMOUNT]; mp++)
157 		if (mp->m_path[0] == '\0')
158 			goto replace;
159 	return;
160 replace:
161 	strcpy(mp->m_type, type);
162 	mp = mtab + NMOUNT - 1;
163 	while (mp > mtab && mp->m_path[0] == '\0')
164 		--mp;
165 	mf = creat("/etc/mtab", 0644);
166 	(void) write(mf, (char *)mtab, (mp - mtab + 1) * sizeof (struct mtab));
167 	close(mf);
168 }
169 
170 /*
171  * Verify file system is mounted and not readonly.
172  */
173 readonly(fs)
174 	register struct fstab *fs;
175 {
176 	register struct mtab *mp;
177 	register char *cp;
178 
179 	cp = index(fs->fs_spec, '\0');
180 	while (*--cp == '/')
181 		*cp = '\0';
182 	cp = rindex(fs->fs_spec, '/');
183 	if (cp)
184 		cp++;
185 	else
186 		cp = fs->fs_spec;
187 	for (mp = mtab; mp < mtab + NMOUNT; mp++) {
188 		if (mp->m_path[0] == '\0')
189 			continue;
190 		if (strcmp(cp, mp->m_dname) == 0) {
191 			if (strcmp(mp->m_type, FSTAB_RO) == 0) {
192 				printf("%s: mounted read-only\n", fs->fs_file);
193 				return (1);
194 			}
195 			return (0);
196 		}
197 	}
198 	printf("%s: not mounted\n", fs->fs_file);
199 	return (1);
200 }
201