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 * %sccs.include.redist.c% 9 */ 10 11 #ifndef lint 12 char copyright[] = 13 "@(#) Copyright (c) 1980, 1990 Regents of the University of California.\n\ 14 All rights reserved.\n"; 15 #endif /* not lint */ 16 17 #ifndef lint 18 static char sccsid[] = "@(#)quotaon.c 5.13 (Berkeley) 11/11/91"; 19 #endif /* not lint */ 20 21 /* 22 * Turn quota on/off for a filesystem. 23 */ 24 #include <sys/param.h> 25 #include <sys/file.h> 26 #include <sys/mount.h> 27 #include <ufs/ufs/quota.h> 28 #include <stdio.h> 29 #include <fstab.h> 30 31 char *qfname = QUOTAFILENAME; 32 char *qfextension[] = INITQFNAMES; 33 34 int aflag; /* all file systems */ 35 int gflag; /* operate on group quotas */ 36 int uflag; /* operate on user quotas */ 37 int vflag; /* verbose */ 38 39 main(argc, argv) 40 int argc; 41 char **argv; 42 { 43 register struct fstab *fs; 44 char ch, *qfnp, *whoami, *rindex(); 45 long argnum, done = 0; 46 int i, offmode = 0, errs = 0; 47 extern char *optarg; 48 extern int optind; 49 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 } 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 } 77 } 78 argc -= optind; 79 argv += optind; 80 if (argc <= 0 && !aflag) 81 usage(whoami); 82 if (!gflag && !uflag) { 83 gflag++; 84 uflag++; 85 } 86 setfsent(); 87 while ((fs = getfsent()) != NULL) { 88 if (strcmp(fs->fs_vfstype, "ufs") || 89 strcmp(fs->fs_type, FSTAB_RW)) 90 continue; 91 if (aflag) { 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); 96 continue; 97 } 98 if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || 99 (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { 100 done |= 1 << argnum; 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); 105 } 106 } 107 endfsent(); 108 for (i = 0; i < argc; i++) 109 if ((done & (1 << i)) == 0) 110 fprintf(stderr, "%s not found in fstab\n", 111 argv[i]); 112 exit(errs); 113 } 114 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 124 quotaonoff(fs, offmode, type, qfpathname) 125 register struct fstab *fs; 126 int offmode, type; 127 char *qfpathname; 128 { 129 130 if (strcmp(fs->fs_file, "/") && readonly(fs)) 131 return (1); 132 if (offmode) { 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 } 138 if (vflag) 139 printf("%s: quotas turned off\n", fs->fs_file); 140 return (0); 141 } 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 } 147 if (vflag) 148 printf("%s: %s quotas turned on\n", fs->fs_file, 149 qfextension[type]); 150 return (0); 151 } 152 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; 159 { 160 register int i; 161 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 */ 171 hasquota(fs, type, qfnamep) 172 register struct fstab *fs; 173 int type; 174 char **qfnamep; 175 { 176 register char *opt; 177 char *cp, *index(), *strtok(); 178 static char initname, usrname[100], grpname[100]; 179 static char buf[BUFSIZ]; 180 181 if (!initname) { 182 sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname); 183 sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname); 184 initname = 1; 185 } 186 strcpy(buf, fs->fs_mntops); 187 for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { 188 if (cp = index(opt, '=')) 189 *cp++ = '\0'; 190 if (type == USRQUOTA && strcmp(opt, usrname) == 0) 191 break; 192 if (type == GRPQUOTA && strcmp(opt, grpname) == 0) 193 break; 194 } 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); 204 } 205 206 /* 207 * Verify file system is mounted and not readonly. 208 */ 209 readonly(fs) 210 register struct fstab *fs; 211 { 212 struct statfs fsbuf; 213 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); 219 } 220 if (fsbuf.f_flags & MNT_RDONLY) { 221 printf("%s: mounted read-only\n", fs->fs_file); 222 return (1); 223 } 224 return (0); 225 } 226