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