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