1594fe2e1Smckusick /*
2*bc58f311Sbostic * Copyright (c) 1980, 1990, 1993
3*bc58f311Sbostic * The Regents of the University of California. All rights reserved.
4411fb891Sbostic *
504cc11fdSmckusick * This code is derived from software contributed to Berkeley by
604cc11fdSmckusick * Robert Elz at The University of Melbourne.
704cc11fdSmckusick *
882448923Sbostic * %sccs.include.redist.c%
9594fe2e1Smckusick */
10594fe2e1Smckusick
11a793d08eSmckusick #ifndef lint
12*bc58f311Sbostic static char copyright[] =
13*bc58f311Sbostic "@(#) Copyright (c) 1980, 1990, 1993\n\
14*bc58f311Sbostic The Regents of the University of California. All rights reserved.\n";
15411fb891Sbostic #endif /* not lint */
16594fe2e1Smckusick
17594fe2e1Smckusick #ifndef lint
18*bc58f311Sbostic static char sccsid[] = "@(#)quotaon.c 8.1 (Berkeley) 06/06/93";
19411fb891Sbostic #endif /* not lint */
20cb1621a5Ssam
21a793d08eSmckusick /*
222bc3bff3Smckusick * Turn quota on/off for a filesystem.
23a793d08eSmckusick */
24a793d08eSmckusick #include <sys/param.h>
25cb1621a5Ssam #include <sys/file.h>
26421c8cdaSmckusick #include <sys/mount.h>
27e48db97fSbostic #include <ufs/ufs/quota.h>
28a793d08eSmckusick #include <stdio.h>
29a793d08eSmckusick #include <fstab.h>
30a793d08eSmckusick
31f5159bfbSmckusick char *qfname = QUOTAFILENAME;
32f5159bfbSmckusick char *qfextension[] = INITQFNAMES;
33f5159bfbSmckusick
34a793d08eSmckusick int aflag; /* all file systems */
3504cc11fdSmckusick int gflag; /* operate on group quotas */
3604cc11fdSmckusick int uflag; /* operate on user quotas */
3704cc11fdSmckusick int vflag; /* verbose */
382bc3bff3Smckusick
main(argc,argv)39a793d08eSmckusick main(argc, argv)
402bc3bff3Smckusick int argc;
41a793d08eSmckusick char **argv;
42a793d08eSmckusick {
43a793d08eSmckusick register struct fstab *fs;
44a3f6c32eSmckusick char ch, *qfnp, *whoami, *rindex();
4504cc11fdSmckusick long argnum, done = 0;
4604cc11fdSmckusick int i, offmode = 0, errs = 0;
4704cc11fdSmckusick extern char *optarg;
4804cc11fdSmckusick extern int optind;
49a793d08eSmckusick
502bc3bff3Smckusick whoami = rindex(*argv, '/') + 1;
512bc3bff3Smckusick if (whoami == (char *)1)
522bc3bff3Smckusick whoami = *argv;
532bc3bff3Smckusick if (strcmp(whoami, "quotaoff") == 0)
542bc3bff3Smckusick offmode++;
552bc3bff3Smckusick else if (strcmp(whoami, "quotaon") != 0) {
562bc3bff3Smckusick fprintf(stderr, "Name must be quotaon or quotaoff not %s\n",
572bc3bff3Smckusick whoami);
582bc3bff3Smckusick exit(1);
592bc3bff3Smckusick }
6004cc11fdSmckusick while ((ch = getopt(argc, argv, "avug")) != EOF) {
6104cc11fdSmckusick switch(ch) {
6204cc11fdSmckusick case 'a':
63a793d08eSmckusick aflag++;
6404cc11fdSmckusick break;
6504cc11fdSmckusick case 'g':
6604cc11fdSmckusick gflag++;
6704cc11fdSmckusick break;
6804cc11fdSmckusick case 'u':
6904cc11fdSmckusick uflag++;
7004cc11fdSmckusick break;
7104cc11fdSmckusick case 'v':
7204cc11fdSmckusick vflag++;
7304cc11fdSmckusick break;
7404cc11fdSmckusick default:
7504cc11fdSmckusick usage(whoami);
76a793d08eSmckusick }
7704cc11fdSmckusick }
7804cc11fdSmckusick argc -= optind;
7904cc11fdSmckusick argv += optind;
8004cc11fdSmckusick if (argc <= 0 && !aflag)
8104cc11fdSmckusick usage(whoami);
8204cc11fdSmckusick if (!gflag && !uflag) {
8304cc11fdSmckusick gflag++;
8404cc11fdSmckusick uflag++;
85a793d08eSmckusick }
86a793d08eSmckusick setfsent();
87a793d08eSmckusick while ((fs = getfsent()) != NULL) {
88a3f6c32eSmckusick if (strcmp(fs->fs_vfstype, "ufs") ||
89a3f6c32eSmckusick strcmp(fs->fs_type, FSTAB_RW))
90a3f6c32eSmckusick continue;
9104cc11fdSmckusick if (aflag) {
92a3f6c32eSmckusick if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
93a3f6c32eSmckusick errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp);
94a3f6c32eSmckusick if (uflag && hasquota(fs, USRQUOTA, &qfnp))
95a3f6c32eSmckusick errs += quotaonoff(fs, offmode, USRQUOTA, qfnp);
96a793d08eSmckusick continue;
9704cc11fdSmckusick }
9823f08f3cSmckusick if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 ||
9904cc11fdSmckusick (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) {
10004cc11fdSmckusick done |= 1 << argnum;
101a3f6c32eSmckusick if (gflag && hasquota(fs, GRPQUOTA, &qfnp))
102a3f6c32eSmckusick errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp);
103a3f6c32eSmckusick if (uflag && hasquota(fs, USRQUOTA, &qfnp))
104a3f6c32eSmckusick errs += quotaonoff(fs, offmode, USRQUOTA, qfnp);
10504cc11fdSmckusick }
106a793d08eSmckusick }
107a793d08eSmckusick endfsent();
108ff0a8d2eSmckusick for (i = 0; i < argc; i++)
109ff0a8d2eSmckusick if ((done & (1 << i)) == 0)
1101b9b1393Sbostic fprintf(stderr, "%s not found in fstab\n",
111ff0a8d2eSmckusick argv[i]);
1122bc3bff3Smckusick exit(errs);
113a793d08eSmckusick }
114a793d08eSmckusick
usage(whoami)11504cc11fdSmckusick usage(whoami)
11604cc11fdSmckusick char *whoami;
117cb1621a5Ssam {
118cb1621a5Ssam
11904cc11fdSmckusick fprintf(stderr, "Usage:\n\t%s [-g] [-u] [-v] -a\n", whoami);
12004cc11fdSmckusick fprintf(stderr, "\t%s [-g] [-u] [-v] filesys ...\n", whoami);
12104cc11fdSmckusick exit(1);
12204cc11fdSmckusick }
12304cc11fdSmckusick
quotaonoff(fs,offmode,type,qfpathname)124a3f6c32eSmckusick quotaonoff(fs, offmode, type, qfpathname)
12504cc11fdSmckusick register struct fstab *fs;
12604cc11fdSmckusick int offmode, type;
127a3f6c32eSmckusick char *qfpathname;
12804cc11fdSmckusick {
12904cc11fdSmckusick
130cb1621a5Ssam if (strcmp(fs->fs_file, "/") && readonly(fs))
131cb1621a5Ssam return (1);
132cb1621a5Ssam if (offmode) {
133a3f6c32eSmckusick if (quotactl(fs->fs_file, QCMD(Q_QUOTAOFF, type), 0, 0) < 0) {
134a3f6c32eSmckusick fprintf(stderr, "quotaoff: ");
135a3f6c32eSmckusick perror(fs->fs_file);
136a3f6c32eSmckusick return (1);
137a3f6c32eSmckusick }
138cb1621a5Ssam if (vflag)
139cb1621a5Ssam printf("%s: quotas turned off\n", fs->fs_file);
140cb1621a5Ssam return (0);
141cb1621a5Ssam }
142a3f6c32eSmckusick if (quotactl(fs->fs_file, QCMD(Q_QUOTAON, type), 0, qfpathname) < 0) {
143a3f6c32eSmckusick fprintf(stderr, "quotaon: using %s on", qfpathname);
144a3f6c32eSmckusick perror(fs->fs_file);
145a3f6c32eSmckusick return (1);
146a3f6c32eSmckusick }
147cb1621a5Ssam if (vflag)
14804cc11fdSmckusick printf("%s: %s quotas turned on\n", fs->fs_file,
14904cc11fdSmckusick qfextension[type]);
150cb1621a5Ssam return (0);
151cb1621a5Ssam }
152cb1621a5Ssam
15304cc11fdSmckusick /*
15404cc11fdSmckusick * Check to see if target appears in list of size cnt.
15504cc11fdSmckusick */
oneof(target,list,cnt)15604cc11fdSmckusick oneof(target, list, cnt)
15704cc11fdSmckusick register char *target, *list[];
15804cc11fdSmckusick int cnt;
159a793d08eSmckusick {
160a793d08eSmckusick register int i;
161a793d08eSmckusick
16204cc11fdSmckusick for (i = 0; i < cnt; i++)
16304cc11fdSmckusick if (strcmp(target, list[i]) == 0)
16404cc11fdSmckusick return (i);
16504cc11fdSmckusick return (-1);
16604cc11fdSmckusick }
16704cc11fdSmckusick
16804cc11fdSmckusick /*
16904cc11fdSmckusick * Check to see if a particular quota is to be enabled.
17004cc11fdSmckusick */
hasquota(fs,type,qfnamep)171a3f6c32eSmckusick hasquota(fs, type, qfnamep)
172a3f6c32eSmckusick register struct fstab *fs;
17304cc11fdSmckusick int type;
174a3f6c32eSmckusick char **qfnamep;
17504cc11fdSmckusick {
17604cc11fdSmckusick register char *opt;
177a3f6c32eSmckusick char *cp, *index(), *strtok();
17804cc11fdSmckusick static char initname, usrname[100], grpname[100];
179a3f6c32eSmckusick static char buf[BUFSIZ];
18004cc11fdSmckusick
18104cc11fdSmckusick if (!initname) {
18204cc11fdSmckusick sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname);
18304cc11fdSmckusick sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname);
18404cc11fdSmckusick initname = 1;
18504cc11fdSmckusick }
186a3f6c32eSmckusick strcpy(buf, fs->fs_mntops);
18704cc11fdSmckusick for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) {
188a3f6c32eSmckusick if (cp = index(opt, '='))
189a3f6c32eSmckusick *cp++ = '\0';
19004cc11fdSmckusick if (type == USRQUOTA && strcmp(opt, usrname) == 0)
191a3f6c32eSmckusick break;
19204cc11fdSmckusick if (type == GRPQUOTA && strcmp(opt, grpname) == 0)
193a3f6c32eSmckusick break;
194a3f6c32eSmckusick }
195a3f6c32eSmckusick if (!opt)
196a3f6c32eSmckusick return (0);
197a3f6c32eSmckusick if (cp) {
198a3f6c32eSmckusick *qfnamep = cp;
199a793d08eSmckusick return (1);
200ff0a8d2eSmckusick }
201a3f6c32eSmckusick (void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]);
202a3f6c32eSmckusick *qfnamep = buf;
203a3f6c32eSmckusick return (1);
204a793d08eSmckusick }
205cb1621a5Ssam
206cb1621a5Ssam /*
207cb1621a5Ssam * Verify file system is mounted and not readonly.
208cb1621a5Ssam */
readonly(fs)209cb1621a5Ssam readonly(fs)
210cb1621a5Ssam register struct fstab *fs;
211cb1621a5Ssam {
212421c8cdaSmckusick struct statfs fsbuf;
213cb1621a5Ssam
214421c8cdaSmckusick if (statfs(fs->fs_file, &fsbuf) < 0 ||
215421c8cdaSmckusick strcmp(fsbuf.f_mntonname, fs->fs_file) ||
216421c8cdaSmckusick strcmp(fsbuf.f_mntfromname, fs->fs_spec)) {
217421c8cdaSmckusick printf("%s: not mounted\n", fs->fs_file);
218421c8cdaSmckusick return (1);
219421c8cdaSmckusick }
220aa385572Smckusick if (fsbuf.f_flags & MNT_RDONLY) {
221cb1621a5Ssam printf("%s: mounted read-only\n", fs->fs_file);
222cb1621a5Ssam return (1);
223cb1621a5Ssam }
224cb1621a5Ssam return (0);
225cb1621a5Ssam }
226