quotaon.c revision 1553
140239Sken/* 246733Sken * Copyright (c) 1980, 1990, 1993 340239Sken * The Regents of the University of California. All rights reserved. 440239Sken * 540239Sken * This code is derived from software contributed to Berkeley by 640239Sken * Robert Elz at The University of Melbourne. 740239Sken * 840239Sken * Redistribution and use in source and binary forms, with or without 940239Sken * modification, are permitted provided that the following conditions 1040239Sken * are met: 1140239Sken * 1. Redistributions of source code must retain the above copyright 1240239Sken * notice, this list of conditions and the following disclaimer. 1340239Sken * 2. Redistributions in binary form must reproduce the above copyright 1440239Sken * notice, this list of conditions and the following disclaimer in the 1540239Sken * documentation and/or other materials provided with the distribution. 1640239Sken * 3. All advertising materials mentioning features or use of this software 1740239Sken * must display the following acknowledgement: 1840239Sken * This product includes software developed by the University of 1940239Sken * California, Berkeley and its contributors. 2040239Sken * 4. Neither the name of the University nor the names of its contributors 2140239Sken * may be used to endorse or promote products derived from this software 2240239Sken * without specific prior written permission. 2340239Sken * 2440239Sken * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2540239Sken * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2640239Sken * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2740239Sken * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2850476Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2940239Sken * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30318139Sken * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3140239Sken * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3279538Sru * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3340239Sken * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3440239Sken * SUCH DAMAGE. 3540239Sken */ 3640239Sken 3756460Sasmodai#ifndef lint 3840239Skenstatic char copyright[] = 3940239Sken"@(#) Copyright (c) 1980, 1990, 1993\n\ 4068962Sru The Regents of the University of California. All rights reserved.\n"; 4140239Sken#endif /* not lint */ 4279727Sschweikh 4340239Sken#ifndef lint 4440239Skenstatic char sccsid[] = "@(#)quotaon.c 8.1 (Berkeley) 6/6/93"; 4568962Sru#endif /* not lint */ 4640239Sken 47117011Sru/* 48117011Sru * Turn quota on/off for a filesystem. 4940239Sken */ 5040239Sken#include <sys/param.h> 5140239Sken#include <sys/file.h> 5240239Sken#include <sys/mount.h> 5368962Sru#include <ufs/ufs/quota.h> 5440239Sken#include <stdio.h> 5540239Sken#include <fstab.h> 56291716Sken 57291716Skenchar *qfname = QUOTAFILENAME; 5840239Skenchar *qfextension[] = INITQFNAMES; 5940239Sken 6040239Skenint aflag; /* all file systems */ 61291716Skenint gflag; /* operate on group quotas */ 62291716Skenint uflag; /* operate on user quotas */ 6340239Skenint vflag; /* verbose */ 6440239Sken 6540239Skenmain(argc, argv) 6640239Sken int argc; 6768962Sru char **argv; 6840239Sken{ 6968962Sru register struct fstab *fs; 7040239Sken char ch, *qfnp, *whoami, *rindex(); 7140239Sken long argnum, done = 0; 72291716Sken int i, offmode = 0, errs = 0; 73291716Sken extern char *optarg; 7440239Sken extern int optind; 7540239Sken 76291716Sken whoami = rindex(*argv, '/') + 1; 77291716Sken if (whoami == (char *)1) 7846733Sken whoami = *argv; 79117011Sru if (strcmp(whoami, "quotaoff") == 0) 80117011Sru offmode++; 8146733Sken else if (strcmp(whoami, "quotaon") != 0) { 8246733Sken fprintf(stderr, "Name must be quotaon or quotaoff not %s\n", 83117011Sru whoami); 84117011Sru exit(1); 8546733Sken } 8646733Sken while ((ch = getopt(argc, argv, "avug")) != EOF) { 8746733Sken switch(ch) { 88318139Sken case 'a': 89318139Sken aflag++; 90318139Sken break; 91318139Sken case 'g': 92318139Sken gflag++; 93291716Sken break; 9440239Sken case 'u': 95117011Sru uflag++; 96117011Sru break; 9768962Sru case 'v': 9840239Sken vflag++; 99141946Sru break; 100117011Sru default: 101117011Sru usage(whoami); 10240239Sken } 10340239Sken } 104291716Sken argc -= optind; 105291716Sken argv += optind; 106301719Strasz if (argc <= 0 && !aflag) 107291716Sken usage(whoami); 108291716Sken if (!gflag && !uflag) { 109291716Sken gflag++; 110292205Sbrueffer uflag++; 111291716Sken } 112291716Sken setfsent(); 113291716Sken while ((fs = getfsent()) != NULL) { 114291716Sken if (strcmp(fs->fs_vfstype, "ufs") || 115291716Sken strcmp(fs->fs_type, FSTAB_RW)) 116291716Sken continue; 117291716Sken if (aflag) { 118291716Sken if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) 119291716Sken errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp); 120291716Sken if (uflag && hasquota(fs, USRQUOTA, &qfnp)) 121291716Sken errs += quotaonoff(fs, offmode, USRQUOTA, qfnp); 122291716Sken continue; 123291716Sken } 124291716Sken if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || 125291716Sken (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { 126291716Sken done |= 1 << argnum; 127291716Sken if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) 128292205Sbrueffer errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp); 129292205Sbrueffer if (uflag && hasquota(fs, USRQUOTA, &qfnp)) 130291716Sken errs += quotaonoff(fs, offmode, USRQUOTA, qfnp); 131291716Sken } 132292205Sbrueffer } 133291716Sken endfsent(); 134291716Sken for (i = 0; i < argc; i++) 135291716Sken if ((done & (1 << i)) == 0) 136291716Sken fprintf(stderr, "%s not found in fstab\n", 137291716Sken argv[i]); 138291716Sken exit(errs); 139291716Sken} 140291716Sken 141291716Skenusage(whoami) 142291716Sken char *whoami; 143291716Sken{ 144291716Sken 145291716Sken fprintf(stderr, "Usage:\n\t%s [-g] [-u] [-v] -a\n", whoami); 146291716Sken fprintf(stderr, "\t%s [-g] [-u] [-v] filesys ...\n", whoami); 147291716Sken exit(1); 148291716Sken} 149291716Sken 150291716Skenquotaonoff(fs, offmode, type, qfpathname) 151291716Sken register struct fstab *fs; 152291716Sken int offmode, type; 153291716Sken char *qfpathname; 154291716Sken{ 155291716Sken 156291716Sken if (strcmp(fs->fs_file, "/") && readonly(fs)) 157291716Sken return (1); 158291716Sken if (offmode) { 159291716Sken if (quotactl(fs->fs_file, QCMD(Q_QUOTAOFF, type), 0, 0) < 0) { 160291716Sken fprintf(stderr, "quotaoff: "); 161291716Sken perror(fs->fs_file); 162291716Sken return (1); 163291716Sken } 164291716Sken if (vflag) 165291716Sken printf("%s: quotas turned off\n", fs->fs_file); 166291716Sken return (0); 167291716Sken } 168318139Sken if (quotactl(fs->fs_file, QCMD(Q_QUOTAON, type), 0, qfpathname) < 0) { 169318139Sken fprintf(stderr, "quotaon: using %s on", qfpathname); 170318139Sken perror(fs->fs_file); 171318139Sken return (1); 172318139Sken } 173291716Sken if (vflag) 174291716Sken printf("%s: %s quotas turned on\n", fs->fs_file, 175291716Sken qfextension[type]); 176291716Sken return (0); 177291716Sken} 178291716Sken 179291716Sken/* 180301719Strasz * Check to see if target appears in list of size cnt. 181291716Sken */ 182291716Skenoneof(target, list, cnt) 183291716Sken register char *target, *list[]; 184292205Sbrueffer int cnt; 185291716Sken{ 186291716Sken register int i; 187291716Sken 188291716Sken for (i = 0; i < cnt; i++) 189291716Sken if (strcmp(target, list[i]) == 0) 190291716Sken return (i); 191291716Sken return (-1); 192291716Sken} 193292205Sbrueffer 194292205Sbrueffer/* 195291716Sken * Check to see if a particular quota is to be enabled. 196291716Sken */ 197291716Skenhasquota(fs, type, qfnamep) 198291716Sken register struct fstab *fs; 199291716Sken int type; 200292205Sbrueffer char **qfnamep; 201291716Sken{ 202291716Sken register char *opt; 203291716Sken char *cp, *index(), *strtok(); 204291716Sken static char initname, usrname[100], grpname[100]; 205291716Sken static char buf[BUFSIZ]; 206291716Sken 207291716Sken if (!initname) { 208291716Sken sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname); 209291716Sken sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname); 210291716Sken initname = 1; 211291716Sken } 21240239Sken strcpy(buf, fs->fs_mntops); 21340239Sken for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { 21470466Sru if (cp = index(opt, '=')) 21540239Sken *cp++ = '\0'; 21640239Sken if (type == USRQUOTA && strcmp(opt, usrname) == 0) 21768962Sru break; 218117011Sru if (type == GRPQUOTA && strcmp(opt, grpname) == 0) 219117011Sru break; 22040239Sken } 22140239Sken if (!opt) 22240239Sken return (0); 22340239Sken if (cp) { 22440239Sken *qfnamep = cp; 225291716Sken return (1); 226291716Sken } 227291716Sken (void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]); 22840239Sken *qfnamep = buf; 229275990Sbrueffer return (1); 230204705Smav} 231291716Sken 232291716Sken/* 233291716Sken * Verify file system is mounted and not readonly. 234291716Sken */ 23540239Skenreadonly(fs) 236291716Sken register struct fstab *fs; 237291716Sken{ 23840239Sken struct statfs fsbuf; 23940239Sken 24040239Sken if (statfs(fs->fs_file, &fsbuf) < 0 || 24140239Sken strcmp(fsbuf.f_mntonname, fs->fs_file) || 242267938Sbapt strcmp(fsbuf.f_mntfromname, fs->fs_spec)) { 243 printf("%s: not mounted\n", fs->fs_file); 244 return (1); 245 } 246 if (fsbuf.f_flags & MNT_RDONLY) { 247 printf("%s: mounted read-only\n", fs->fs_file); 248 return (1); 249 } 250 return (0); 251} 252