quotaon.c revision 166212
11553Srgrimes/* 21553Srgrimes * Copyright (c) 1980, 1990, 1993 31553Srgrimes * The Regents of the University of California. All rights reserved. 41553Srgrimes * 51553Srgrimes * This code is derived from software contributed to Berkeley by 61553Srgrimes * Robert Elz at The University of Melbourne. 71553Srgrimes * 81553Srgrimes * Redistribution and use in source and binary forms, with or without 91553Srgrimes * modification, are permitted provided that the following conditions 101553Srgrimes * are met: 111553Srgrimes * 1. Redistributions of source code must retain the above copyright 121553Srgrimes * notice, this list of conditions and the following disclaimer. 131553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141553Srgrimes * notice, this list of conditions and the following disclaimer in the 151553Srgrimes * documentation and/or other materials provided with the distribution. 161553Srgrimes * 4. Neither the name of the University nor the names of its contributors 171553Srgrimes * may be used to endorse or promote products derived from this software 181553Srgrimes * without specific prior written permission. 191553Srgrimes * 201553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 211553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 221553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 231553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 241553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 251553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 261553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 271553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 281553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 291553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 301553Srgrimes * SUCH DAMAGE. 311553Srgrimes */ 321553Srgrimes 33114601Sobrien#if 0 341553Srgrimes#ifndef lint 3530371Scharnierstatic const char copyright[] = 361553Srgrimes"@(#) Copyright (c) 1980, 1990, 1993\n\ 371553Srgrimes The Regents of the University of California. All rights reserved.\n"; 381553Srgrimes#endif /* not lint */ 391553Srgrimes 401553Srgrimes#ifndef lint 411553Srgrimesstatic char sccsid[] = "@(#)quotaon.c 8.1 (Berkeley) 6/6/93"; 42114601Sobrien#endif /* not lint */ 4330371Scharnier#endif 44114601Sobrien#include <sys/cdefs.h> 45114601Sobrien__FBSDID("$FreeBSD: head/usr.sbin/quotaon/quotaon.c 166212 2007-01-24 22:52:32Z mpp $"); 461553Srgrimes 471553Srgrimes/* 481553Srgrimes * Turn quota on/off for a filesystem. 491553Srgrimes */ 501553Srgrimes#include <sys/param.h> 511553Srgrimes#include <sys/file.h> 521553Srgrimes#include <sys/mount.h> 531553Srgrimes#include <ufs/ufs/quota.h> 5430371Scharnier#include <err.h> 5530371Scharnier#include <fstab.h> 561553Srgrimes#include <stdio.h> 5778720Sdd#include <stdlib.h> 5830371Scharnier#include <string.h> 5930371Scharnier#include <unistd.h> 601553Srgrimes 6199822Salfredconst char *qfname = QUOTAFILENAME; 6299822Salfredconst char *qfextension[] = INITQFNAMES; 631553Srgrimes 6496705Strhodesint aflag; /* all filesystems */ 651553Srgrimesint gflag; /* operate on group quotas */ 661553Srgrimesint uflag; /* operate on user quotas */ 671553Srgrimesint vflag; /* verbose */ 681553Srgrimes 6999822Salfredint hasquota(struct fstab *, int, char **); 7099822Salfredint oneof(char *, char *[], int); 7199822Salfredint quotaonoff(struct fstab *fs, int, int, char *); 7299822Salfredint readonly(struct fstab *); 7399822Salfredstatic void usage(void); 7430371Scharnier 7530371Scharnierint 7699822Salfredmain(int argc, char **argv) 771553Srgrimes{ 781553Srgrimes register struct fstab *fs; 79124830Sgrehan char *qfnp, *whoami; 801553Srgrimes long argnum, done = 0; 81124830Sgrehan int ch, i, offmode = 0, errs = 0; 821553Srgrimes 831553Srgrimes whoami = rindex(*argv, '/') + 1; 841553Srgrimes if (whoami == (char *)1) 851553Srgrimes whoami = *argv; 861553Srgrimes if (strcmp(whoami, "quotaoff") == 0) 871553Srgrimes offmode++; 8830371Scharnier else if (strcmp(whoami, "quotaon") != 0) 8930371Scharnier errx(1, "name must be quotaon or quotaoff"); 9024428Simp while ((ch = getopt(argc, argv, "avug")) != -1) { 911553Srgrimes switch(ch) { 921553Srgrimes case 'a': 931553Srgrimes aflag++; 941553Srgrimes break; 951553Srgrimes case 'g': 961553Srgrimes gflag++; 971553Srgrimes break; 981553Srgrimes case 'u': 991553Srgrimes uflag++; 1001553Srgrimes break; 1011553Srgrimes case 'v': 1021553Srgrimes vflag++; 1031553Srgrimes break; 1041553Srgrimes default: 10530371Scharnier usage(); 1061553Srgrimes } 1071553Srgrimes } 1081553Srgrimes argc -= optind; 1091553Srgrimes argv += optind; 1101553Srgrimes if (argc <= 0 && !aflag) 11130371Scharnier usage(); 1121553Srgrimes if (!gflag && !uflag) { 1131553Srgrimes gflag++; 1141553Srgrimes uflag++; 1151553Srgrimes } 1161553Srgrimes setfsent(); 1171553Srgrimes while ((fs = getfsent()) != NULL) { 1181553Srgrimes if (strcmp(fs->fs_vfstype, "ufs") || 1191553Srgrimes strcmp(fs->fs_type, FSTAB_RW)) 1201553Srgrimes continue; 1211553Srgrimes if (aflag) { 1221553Srgrimes if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) 1231553Srgrimes errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp); 1241553Srgrimes if (uflag && hasquota(fs, USRQUOTA, &qfnp)) 1251553Srgrimes errs += quotaonoff(fs, offmode, USRQUOTA, qfnp); 1261553Srgrimes continue; 1271553Srgrimes } 1281553Srgrimes if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || 1291553Srgrimes (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { 1301553Srgrimes done |= 1 << argnum; 1311553Srgrimes if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) 1321553Srgrimes errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp); 1331553Srgrimes if (uflag && hasquota(fs, USRQUOTA, &qfnp)) 1341553Srgrimes errs += quotaonoff(fs, offmode, USRQUOTA, qfnp); 1351553Srgrimes } 1361553Srgrimes } 1371553Srgrimes endfsent(); 1381553Srgrimes for (i = 0; i < argc; i++) 1391553Srgrimes if ((done & (1 << i)) == 0) 14030371Scharnier warnx("%s not found in fstab", argv[i]); 1411553Srgrimes exit(errs); 1421553Srgrimes} 1431553Srgrimes 14430371Scharnierstatic void 14530371Scharnierusage() 1461553Srgrimes{ 1471553Srgrimes 14830371Scharnier fprintf(stderr, "%s\n%s\n%s\n%s\n", 14930371Scharnier "usage: quotaon [-g] [-u] [-v] -a", 15030371Scharnier " quotaon [-g] [-u] [-v] filesystem ...", 15130371Scharnier " quotaoff [-g] [-u] [-v] -a", 15230371Scharnier " quotaoff [-g] [-u] [-v] filesystem ..."); 1531553Srgrimes exit(1); 1541553Srgrimes} 1551553Srgrimes 15630371Scharnierint 1571553Srgrimesquotaonoff(fs, offmode, type, qfpathname) 1581553Srgrimes register struct fstab *fs; 1591553Srgrimes int offmode, type; 1601553Srgrimes char *qfpathname; 1611553Srgrimes{ 1621553Srgrimes 1631553Srgrimes if (strcmp(fs->fs_file, "/") && readonly(fs)) 1641553Srgrimes return (1); 1651553Srgrimes if (offmode) { 1661553Srgrimes if (quotactl(fs->fs_file, QCMD(Q_QUOTAOFF, type), 0, 0) < 0) { 16730371Scharnier warn("%s", fs->fs_file); 1681553Srgrimes return (1); 1691553Srgrimes } 1701553Srgrimes if (vflag) 1711553Srgrimes printf("%s: quotas turned off\n", fs->fs_file); 1721553Srgrimes return (0); 1731553Srgrimes } 1741553Srgrimes if (quotactl(fs->fs_file, QCMD(Q_QUOTAON, type), 0, qfpathname) < 0) { 17530371Scharnier warnx("using %s on", qfpathname); 17630371Scharnier warn("%s", fs->fs_file); 1771553Srgrimes return (1); 1781553Srgrimes } 1791553Srgrimes if (vflag) 180166212Smpp printf("%s: %s quotas turned on with data file %s\n", 181166212Smpp fs->fs_file, qfextension[type], qfpathname); 1821553Srgrimes return (0); 1831553Srgrimes} 1841553Srgrimes 1851553Srgrimes/* 1861553Srgrimes * Check to see if target appears in list of size cnt. 1871553Srgrimes */ 18830371Scharnierint 1891553Srgrimesoneof(target, list, cnt) 1901553Srgrimes register char *target, *list[]; 1911553Srgrimes int cnt; 1921553Srgrimes{ 1931553Srgrimes register int i; 1941553Srgrimes 1951553Srgrimes for (i = 0; i < cnt; i++) 1961553Srgrimes if (strcmp(target, list[i]) == 0) 1971553Srgrimes return (i); 1981553Srgrimes return (-1); 1991553Srgrimes} 2001553Srgrimes 2011553Srgrimes/* 2021553Srgrimes * Check to see if a particular quota is to be enabled. 2031553Srgrimes */ 20430371Scharnierint 2051553Srgrimeshasquota(fs, type, qfnamep) 2061553Srgrimes register struct fstab *fs; 2071553Srgrimes int type; 2081553Srgrimes char **qfnamep; 2091553Srgrimes{ 2101553Srgrimes register char *opt; 21130371Scharnier char *cp; 2121553Srgrimes static char initname, usrname[100], grpname[100]; 2131553Srgrimes static char buf[BUFSIZ]; 2141553Srgrimes 2151553Srgrimes if (!initname) { 2161553Srgrimes sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname); 2171553Srgrimes sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname); 2181553Srgrimes initname = 1; 2191553Srgrimes } 2201553Srgrimes strcpy(buf, fs->fs_mntops); 2211553Srgrimes for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { 22230371Scharnier if ((cp = index(opt, '='))) 2231553Srgrimes *cp++ = '\0'; 2241553Srgrimes if (type == USRQUOTA && strcmp(opt, usrname) == 0) 2251553Srgrimes break; 2261553Srgrimes if (type == GRPQUOTA && strcmp(opt, grpname) == 0) 2271553Srgrimes break; 2281553Srgrimes } 2291553Srgrimes if (!opt) 2301553Srgrimes return (0); 2311553Srgrimes if (cp) { 2321553Srgrimes *qfnamep = cp; 2331553Srgrimes return (1); 2341553Srgrimes } 2351553Srgrimes (void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]); 2361553Srgrimes *qfnamep = buf; 2371553Srgrimes return (1); 2381553Srgrimes} 2391553Srgrimes 2401553Srgrimes/* 24196705Strhodes * Verify filesystem is mounted and not readonly. 2421553Srgrimes */ 24330371Scharnierint 2441553Srgrimesreadonly(fs) 2451553Srgrimes register struct fstab *fs; 2461553Srgrimes{ 2471553Srgrimes struct statfs fsbuf; 2481553Srgrimes 2491553Srgrimes if (statfs(fs->fs_file, &fsbuf) < 0 || 2501553Srgrimes strcmp(fsbuf.f_mntonname, fs->fs_file) || 2511553Srgrimes strcmp(fsbuf.f_mntfromname, fs->fs_spec)) { 2521553Srgrimes printf("%s: not mounted\n", fs->fs_file); 2531553Srgrimes return (1); 2541553Srgrimes } 2551553Srgrimes if (fsbuf.f_flags & MNT_RDONLY) { 2561553Srgrimes printf("%s: mounted read-only\n", fs->fs_file); 2571553Srgrimes return (1); 2581553Srgrimes } 2591553Srgrimes return (0); 2601553Srgrimes} 261