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