1: /* 2: * Copyright (c) 1980, 1990, 1993 3: * The Regents of the University of California. 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, with or without 9: * modification, are permitted provided that the following conditions 10: * are met: 11: * 1. Redistributions of source code must retain the above copyright 12: * notice, this list of conditions and the following disclaimer. 13: * 2. Redistributions in binary form must reproduce the above copyright 14: * notice, this list of conditions and the following disclaimer in the 15: * documentation and/or other materials provided with the distribution. 16: * 3. All advertising materials mentioning features or use of this software 17: * must display the following acknowledgement: 18: * This product includes software developed by the University of 19: * California, Berkeley and its contributors. 20: * 4. Neither the name of the University nor the names of its contributors 21: * may be used to endorse or promote products derived from this software 22: * without specific prior written permission. 23: * 24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34: * SUCH DAMAGE. 35: */ 36: 37: #if !defined(lint) && defined(DOSCCS) 38: static char copyright[] = 39: "@(#) Copyright (c) 1980, 1990, 1993\n\ 40: The Regents of the University of California. All rights reserved.\n"; 41: 42: static char sccsid[] = "@(#)quotaon.c 8.1.1 (2.11BSD) 1996/1/21"; 43: #endif /* not lint */ 44: 45: /* 46: * Turn quota on/off for a filesystem. 47: */ 48: #include <sys/param.h> 49: #include <sys/file.h> 50: #include <sys/mount.h> 51: #include <stdio.h> 52: #include <fstab.h> 53: #include <string.h> 54: #include <stdlib.h> 55: 56: char *qfname = "quotas"; 57: 58: int aflag; /* all file systems */ 59: int vflag; /* verbose */ 60: 61: main(argc, argv) 62: int argc; 63: char **argv; 64: { 65: register struct fstab *fs; 66: char ch, *qfnp, *whoami; 67: long done = 0; 68: int i, argnum, offmode = 0, errs = 0; 69: 70: whoami = rindex(*argv, '/') + 1; 71: if (whoami == (char *)1) 72: whoami = *argv; 73: if (strcmp(whoami, "quotaoff") == 0) 74: offmode++; 75: else if (strcmp(whoami, "quotaon") != 0) { 76: fprintf(stderr, "Name must be quotaon or quotaoff not %s\n", 77: whoami); 78: exit(1); 79: } 80: while ((ch = getopt(argc, argv, "avug")) != EOF) { 81: switch(ch) { 82: case 'a': 83: aflag++; 84: break; 85: case 'v': 86: vflag++; 87: break; 88: default: 89: usage(whoami); 90: } 91: } 92: argc -= optind; 93: argv += optind; 94: if (argc <= 0 && !aflag) 95: usage(whoami); 96: setfsent(); 97: while ((fs = getfsent()) != NULL) { 98: if (strcmp(fs->fs_type, FSTAB_RQ) == 0) /* XXX compatibility */ 99: fs->fs_type = FSTAB_RW; 100: if (strcmp(fs->fs_vfstype, "ufs") || 101: strcmp(fs->fs_type, FSTAB_RW)) 102: continue; 103: if (aflag) { 104: if (hasquota(fs, &qfnp)) 105: errs += quotaonoff(fs, offmode, qfnp); 106: continue; 107: } 108: if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || 109: (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { 110: done |= 1 << argnum; 111: if (hasquota(fs, &qfnp)) 112: errs += quotaonoff(fs, offmode, qfnp); 113: } 114: } 115: endfsent(); 116: for (i = 0; i < argc; i++) 117: if ((done & (1 << i)) == 0) 118: fprintf(stderr, "%s not found in fstab\n", 119: argv[i]); 120: exit(errs); 121: } 122: 123: usage(whoami) 124: char *whoami; 125: { 126: 127: fprintf(stderr, "Usage:\n\t%s [-v] -a\n", whoami); 128: fprintf(stderr, "\t%s [-v] filesys ...\n", whoami); 129: exit(1); 130: } 131: 132: quotaonoff(fs, offmode, qfpathname) 133: register struct fstab *fs; 134: int offmode; 135: char *qfpathname; 136: { 137: 138: if (strcmp(fs->fs_file, "/") && readonly(fs)) 139: return (1); 140: if (offmode) { 141: if (setquota(fs->fs_spec, (char *)NULL) < 0) { 142: fprintf(stderr, "quotaoff: "); 143: perror(fs->fs_spec); 144: return (1); 145: } 146: if (vflag) 147: printf("%s: quotas turned off\n", fs->fs_file); 148: return (0); 149: } 150: if (setquota(fs->fs_spec, qfpathname) < 0) { 151: fprintf(stderr, "quotaon: using %s on", qfpathname); 152: perror(fs->fs_file); 153: return (1); 154: } 155: if (vflag) 156: printf("%s: quotas turned on\n", fs->fs_file); 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, qfnamep) 179: register struct fstab *fs; 180: char **qfnamep; 181: { 182: register char *opt; 183: char *cp; 184: static char initname, usrname[100]; 185: static char buf[BUFSIZ]; 186: 187: if (!initname) { 188: strcpy(usrname, qfname); 189: initname = 1; 190: } 191: strcpy(buf, fs->fs_mntops); 192: for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { 193: if (cp = index(opt, '=')) 194: *cp++ = '\0'; 195: if (strcmp(opt, usrname) == 0) 196: break; 197: if (strcmp(opt, FSTAB_RQ) == 0) /* XXX compatibility */ 198: break; 199: } 200: if (!opt) 201: return (0); 202: if (cp) { 203: *qfnamep = cp; 204: return (1); 205: } 206: (void) sprintf(buf, "%s/%s", fs->fs_file, qfname); 207: *qfnamep = buf; 208: return (1); 209: } 210: 211: /* 212: * Verify file system is mounted and not readonly. 213: */ 214: readonly(fs) 215: register struct fstab *fs; 216: { 217: struct statfs fsbuf; 218: 219: if (statfs(fs->fs_file, &fsbuf) < 0 || 220: strcmp(fsbuf.f_mntonname, fs->fs_file) || 221: strcmp(fsbuf.f_mntfromname, fs->fs_spec)) { 222: printf("%s: not mounted\n", fs->fs_file); 223: return (1); 224: } 225: if (fsbuf.f_flags & MNT_RDONLY) { 226: printf("%s: mounted read-only\n", fs->fs_file); 227: return (1); 228: } 229: return (0); 230: }