Commit | Line | Data |
---|---|---|
2a4d07fc | 1 | #ifndef lint |
a2372382 | 2 | static char sccsid[] = "@(#)quotaon.c 4.4 (Berkeley, Melbourne) %G%"; |
2a4d07fc | 3 | #endif |
a2372382 | 4 | |
2a4d07fc | 5 | /* |
74974e2c | 6 | * Turn quota on/off for a filesystem. |
2a4d07fc KM |
7 | */ |
8 | #include <sys/param.h> | |
a2372382 | 9 | #include <sys/file.h> |
2a4d07fc KM |
10 | #include <stdio.h> |
11 | #include <fstab.h> | |
a2372382 SL |
12 | #include <mtab.h> |
13 | ||
14 | struct mtab mtab[NMOUNT]; | |
2a4d07fc KM |
15 | |
16 | int vflag; /* verbose */ | |
17 | int aflag; /* all file systems */ | |
b7df0e2a | 18 | int done; |
a2372382 | 19 | int mf; |
2a4d07fc | 20 | |
a2372382 SL |
21 | char *qfname = "quotas"; |
22 | char quotafile[MAXPATHLEN + 1]; | |
23 | char *index(), *rindex(); | |
74974e2c | 24 | |
2a4d07fc | 25 | main(argc, argv) |
74974e2c | 26 | int argc; |
2a4d07fc KM |
27 | char **argv; |
28 | { | |
2a4d07fc | 29 | register struct fstab *fs; |
74974e2c | 30 | char *whoami, *rindex(); |
b7df0e2a | 31 | int offmode = 0, errs = 0, i; |
2a4d07fc | 32 | |
74974e2c KM |
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 | } | |
2a4d07fc KM |
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 | } | |
74974e2c KM |
53 | if (argc <= 0 && !aflag) { |
54 | fprintf(stderr, "Usage:\n\t%s [-v] -a\n\t%s [-v] filesys ...\n", | |
55 | whoami, whoami); | |
2a4d07fc KM |
56 | exit(1); |
57 | } | |
a2372382 SL |
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); | |
2a4d07fc KM |
65 | setfsent(); |
66 | while ((fs = getfsent()) != NULL) { | |
b7df0e2a KM |
67 | if (aflag && |
68 | (fs->fs_type == 0 || strcmp(fs->fs_type, "rq") != 0)) | |
2a4d07fc | 69 | continue; |
b7df0e2a KM |
70 | if (!aflag && |
71 | !(oneof(fs->fs_file, argv, argc) || | |
72 | oneof(fs->fs_spec, argv, argc))) | |
2a4d07fc | 73 | continue; |
a2372382 | 74 | errs += quotaonoff(fs, offmode); |
2a4d07fc KM |
75 | } |
76 | endfsent(); | |
b7df0e2a KM |
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]); | |
74974e2c | 81 | exit(errs); |
2a4d07fc KM |
82 | } |
83 | ||
a2372382 SL |
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 | ||
2a4d07fc KM |
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++) | |
b7df0e2a KM |
119 | if (strcmp(target, list[i]) == 0) { |
120 | done |= 1 << i; | |
2a4d07fc | 121 | return (1); |
b7df0e2a | 122 | } |
2a4d07fc KM |
123 | return (0); |
124 | } | |
a2372382 SL |
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 | } |