Commit | Line | Data |
---|---|---|
2a18434a | 1 | /* |
2fe4291d | 2 | * Copyright (c) 1980, 1990 Regents of the University of California. |
f9ac90b4 KB |
3 | * All rights reserved. |
4 | * | |
2fe4291d KM |
5 | * This code is derived from software contributed to Berkeley by |
6 | * Robert Elz at The University of Melbourne. | |
7 | * | |
417f7a11 | 8 | * %sccs.include.redist.c% |
2a18434a KM |
9 | */ |
10 | ||
11 | #ifndef lint | |
12 | char copyright[] = | |
2fe4291d | 13 | "@(#) Copyright (c) 1980, 1990 Regents of the University of California.\n\ |
2a18434a | 14 | All rights reserved.\n"; |
f9ac90b4 | 15 | #endif /* not lint */ |
2a18434a | 16 | |
2a4d07fc | 17 | #ifndef lint |
417f7a11 | 18 | static char sccsid[] = "@(#)quotaon.c 5.11 (Berkeley) %G%"; |
f9ac90b4 | 19 | #endif /* not lint */ |
a2372382 | 20 | |
2a4d07fc | 21 | /* |
74974e2c | 22 | * Turn quota on/off for a filesystem. |
2a4d07fc KM |
23 | */ |
24 | #include <sys/param.h> | |
a2372382 | 25 | #include <sys/file.h> |
68403649 | 26 | #include <sys/mount.h> |
2fe4291d | 27 | #include <ufs/quota.h> |
2a4d07fc KM |
28 | #include <stdio.h> |
29 | #include <fstab.h> | |
30 | ||
2a4d07fc | 31 | int aflag; /* all file systems */ |
2fe4291d KM |
32 | int gflag; /* operate on group quotas */ |
33 | int uflag; /* operate on user quotas */ | |
34 | int vflag; /* verbose */ | |
74974e2c | 35 | |
2a4d07fc | 36 | main(argc, argv) |
74974e2c | 37 | int argc; |
2a4d07fc KM |
38 | char **argv; |
39 | { | |
2a4d07fc | 40 | register struct fstab *fs; |
2b2aecf0 | 41 | char ch, *qfnp, *whoami, *rindex(); |
2fe4291d KM |
42 | long argnum, done = 0; |
43 | int i, offmode = 0, errs = 0; | |
44 | extern char *optarg; | |
45 | extern int optind; | |
2a4d07fc | 46 | |
74974e2c KM |
47 | whoami = rindex(*argv, '/') + 1; |
48 | if (whoami == (char *)1) | |
49 | whoami = *argv; | |
50 | if (strcmp(whoami, "quotaoff") == 0) | |
51 | offmode++; | |
52 | else if (strcmp(whoami, "quotaon") != 0) { | |
53 | fprintf(stderr, "Name must be quotaon or quotaoff not %s\n", | |
54 | whoami); | |
55 | exit(1); | |
56 | } | |
2fe4291d KM |
57 | while ((ch = getopt(argc, argv, "avug")) != EOF) { |
58 | switch(ch) { | |
59 | case 'a': | |
60 | aflag++; | |
61 | break; | |
62 | case 'g': | |
63 | gflag++; | |
64 | break; | |
65 | case 'u': | |
66 | uflag++; | |
67 | break; | |
68 | case 'v': | |
69 | vflag++; | |
70 | break; | |
71 | default: | |
72 | usage(whoami); | |
73 | } | |
2a4d07fc | 74 | } |
2fe4291d KM |
75 | argc -= optind; |
76 | argv += optind; | |
77 | if (argc <= 0 && !aflag) | |
78 | usage(whoami); | |
79 | if (!gflag && !uflag) { | |
80 | gflag++; | |
81 | uflag++; | |
2a4d07fc | 82 | } |
2a4d07fc KM |
83 | setfsent(); |
84 | while ((fs = getfsent()) != NULL) { | |
2b2aecf0 KM |
85 | if (strcmp(fs->fs_vfstype, "ufs") || |
86 | strcmp(fs->fs_type, FSTAB_RW)) | |
87 | continue; | |
2fe4291d | 88 | if (aflag) { |
2b2aecf0 KM |
89 | if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) |
90 | errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp); | |
91 | if (uflag && hasquota(fs, USRQUOTA, &qfnp)) | |
92 | errs += quotaonoff(fs, offmode, USRQUOTA, qfnp); | |
2a4d07fc | 93 | continue; |
2fe4291d | 94 | } |
0a576588 | 95 | if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || |
2fe4291d KM |
96 | (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { |
97 | done |= 1 << argnum; | |
2b2aecf0 KM |
98 | if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) |
99 | errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp); | |
100 | if (uflag && hasquota(fs, USRQUOTA, &qfnp)) | |
101 | errs += quotaonoff(fs, offmode, USRQUOTA, qfnp); | |
2fe4291d | 102 | } |
2a4d07fc KM |
103 | } |
104 | endfsent(); | |
b7df0e2a KM |
105 | for (i = 0; i < argc; i++) |
106 | if ((done & (1 << i)) == 0) | |
7abf8d65 | 107 | fprintf(stderr, "%s not found in fstab\n", |
b7df0e2a | 108 | argv[i]); |
74974e2c | 109 | exit(errs); |
2a4d07fc KM |
110 | } |
111 | ||
2fe4291d KM |
112 | usage(whoami) |
113 | char *whoami; | |
114 | { | |
115 | ||
116 | fprintf(stderr, "Usage:\n\t%s [-g] [-u] [-v] -a\n", whoami); | |
117 | fprintf(stderr, "\t%s [-g] [-u] [-v] filesys ...\n", whoami); | |
118 | exit(1); | |
119 | } | |
120 | ||
2b2aecf0 | 121 | quotaonoff(fs, offmode, type, qfpathname) |
a2372382 | 122 | register struct fstab *fs; |
2fe4291d | 123 | int offmode, type; |
2b2aecf0 | 124 | char *qfpathname; |
a2372382 SL |
125 | { |
126 | ||
127 | if (strcmp(fs->fs_file, "/") && readonly(fs)) | |
128 | return (1); | |
129 | if (offmode) { | |
2b2aecf0 KM |
130 | if (quotactl(fs->fs_file, QCMD(Q_QUOTAOFF, type), 0, 0) < 0) { |
131 | fprintf(stderr, "quotaoff: "); | |
132 | perror(fs->fs_file); | |
133 | return (1); | |
134 | } | |
a2372382 SL |
135 | if (vflag) |
136 | printf("%s: quotas turned off\n", fs->fs_file); | |
a2372382 SL |
137 | return (0); |
138 | } | |
2b2aecf0 KM |
139 | if (quotactl(fs->fs_file, QCMD(Q_QUOTAON, type), 0, qfpathname) < 0) { |
140 | fprintf(stderr, "quotaon: using %s on", qfpathname); | |
141 | perror(fs->fs_file); | |
142 | return (1); | |
143 | } | |
a2372382 | 144 | if (vflag) |
2fe4291d KM |
145 | printf("%s: %s quotas turned on\n", fs->fs_file, |
146 | qfextension[type]); | |
a2372382 | 147 | return (0); |
a2372382 SL |
148 | } |
149 | ||
2fe4291d KM |
150 | /* |
151 | * Check to see if target appears in list of size cnt. | |
152 | */ | |
153 | oneof(target, list, cnt) | |
154 | register char *target, *list[]; | |
155 | int cnt; | |
2a4d07fc KM |
156 | { |
157 | register int i; | |
158 | ||
2fe4291d KM |
159 | for (i = 0; i < cnt; i++) |
160 | if (strcmp(target, list[i]) == 0) | |
161 | return (i); | |
162 | return (-1); | |
163 | } | |
164 | ||
165 | /* | |
166 | * Check to see if a particular quota is to be enabled. | |
167 | */ | |
2b2aecf0 KM |
168 | hasquota(fs, type, qfnamep) |
169 | register struct fstab *fs; | |
2fe4291d | 170 | int type; |
2b2aecf0 | 171 | char **qfnamep; |
2fe4291d KM |
172 | { |
173 | register char *opt; | |
2b2aecf0 | 174 | char *cp, *index(), *strtok(); |
2fe4291d | 175 | static char initname, usrname[100], grpname[100]; |
2b2aecf0 | 176 | static char buf[BUFSIZ]; |
2fe4291d KM |
177 | |
178 | if (!initname) { | |
179 | sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname); | |
180 | sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname); | |
181 | initname = 1; | |
182 | } | |
2b2aecf0 | 183 | strcpy(buf, fs->fs_mntops); |
2fe4291d | 184 | for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { |
2b2aecf0 KM |
185 | if (cp = index(opt, '=')) |
186 | *cp++ = '\0'; | |
2fe4291d | 187 | if (type == USRQUOTA && strcmp(opt, usrname) == 0) |
2b2aecf0 | 188 | break; |
2fe4291d | 189 | if (type == GRPQUOTA && strcmp(opt, grpname) == 0) |
2b2aecf0 | 190 | break; |
2fe4291d | 191 | } |
2b2aecf0 KM |
192 | if (!opt) |
193 | return (0); | |
194 | if (cp) { | |
195 | *qfnamep = cp; | |
196 | return (1); | |
197 | } | |
198 | (void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]); | |
199 | *qfnamep = buf; | |
200 | return (1); | |
2a4d07fc | 201 | } |
a2372382 | 202 | |
a2372382 SL |
203 | /* |
204 | * Verify file system is mounted and not readonly. | |
205 | */ | |
206 | readonly(fs) | |
207 | register struct fstab *fs; | |
208 | { | |
68403649 | 209 | struct statfs fsbuf; |
a2372382 | 210 | |
68403649 KM |
211 | if (statfs(fs->fs_file, &fsbuf) < 0 || |
212 | strcmp(fsbuf.f_mntonname, fs->fs_file) || | |
213 | strcmp(fsbuf.f_mntfromname, fs->fs_spec)) { | |
214 | printf("%s: not mounted\n", fs->fs_file); | |
215 | return (1); | |
a2372382 | 216 | } |
f795548e | 217 | if (fsbuf.f_flags & MNT_RDONLY) { |
68403649 KM |
218 | printf("%s: mounted read-only\n", fs->fs_file); |
219 | return (1); | |
220 | } | |
221 | return (0); | |
a2372382 | 222 | } |