quotaon.c revision 124830
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 * 3. All advertising materials mentioning features or use of this software 171553Srgrimes * must display the following acknowledgement: 181553Srgrimes * This product includes software developed by the University of 191553Srgrimes * California, Berkeley and its contributors. 201553Srgrimes * 4. Neither the name of the University nor the names of its contributors 211553Srgrimes * may be used to endorse or promote products derived from this software 221553Srgrimes * without specific prior written permission. 231553Srgrimes * 241553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341553Srgrimes * SUCH DAMAGE. 351553Srgrimes */ 361553Srgrimes 37114601Sobrien#if 0 381553Srgrimes#ifndef lint 3930371Scharnierstatic const char copyright[] = 401553Srgrimes"@(#) Copyright (c) 1980, 1990, 1993\n\ 411553Srgrimes The Regents of the University of California. All rights reserved.\n"; 421553Srgrimes#endif /* not lint */ 431553Srgrimes 441553Srgrimes#ifndef lint 451553Srgrimesstatic char sccsid[] = "@(#)quotaon.c 8.1 (Berkeley) 6/6/93"; 46114601Sobrien#endif /* not lint */ 4730371Scharnier#endif 48114601Sobrien#include <sys/cdefs.h> 49114601Sobrien__FBSDID("$FreeBSD: head/usr.sbin/quotaon/quotaon.c 124830 2004-01-22 07:23:36Z grehan $"); 501553Srgrimes 511553Srgrimes/* 521553Srgrimes * Turn quota on/off for a filesystem. 531553Srgrimes */ 541553Srgrimes#include <sys/param.h> 551553Srgrimes#include <sys/file.h> 561553Srgrimes#include <sys/mount.h> 571553Srgrimes#include <ufs/ufs/quota.h> 5830371Scharnier#include <err.h> 5930371Scharnier#include <fstab.h> 601553Srgrimes#include <stdio.h> 6178720Sdd#include <stdlib.h> 6230371Scharnier#include <string.h> 6330371Scharnier#include <unistd.h> 641553Srgrimes 6599822Salfredconst char *qfname = QUOTAFILENAME; 6699822Salfredconst char *qfextension[] = INITQFNAMES; 671553Srgrimes 6896705Strhodesint aflag; /* all filesystems */ 691553Srgrimesint gflag; /* operate on group quotas */ 701553Srgrimesint uflag; /* operate on user quotas */ 711553Srgrimesint vflag; /* verbose */ 721553Srgrimes 7399822Salfredint hasquota(struct fstab *, int, char **); 7499822Salfredint oneof(char *, char *[], int); 7599822Salfredint quotaonoff(struct fstab *fs, int, int, char *); 7699822Salfredint readonly(struct fstab *); 7799822Salfredstatic void usage(void); 7830371Scharnier 7930371Scharnierint 8099822Salfredmain(int argc, char **argv) 811553Srgrimes{ 821553Srgrimes register struct fstab *fs; 83124830Sgrehan char *qfnp, *whoami; 841553Srgrimes long argnum, done = 0; 85124830Sgrehan int ch, i, offmode = 0, errs = 0; 861553Srgrimes 871553Srgrimes whoami = rindex(*argv, '/') + 1; 881553Srgrimes if (whoami == (char *)1) 891553Srgrimes whoami = *argv; 901553Srgrimes if (strcmp(whoami, "quotaoff") == 0) 911553Srgrimes offmode++; 9230371Scharnier else if (strcmp(whoami, "quotaon") != 0) 9330371Scharnier errx(1, "name must be quotaon or quotaoff"); 9424428Simp while ((ch = getopt(argc, argv, "avug")) != -1) { 951553Srgrimes switch(ch) { 961553Srgrimes case 'a': 971553Srgrimes aflag++; 981553Srgrimes break; 991553Srgrimes case 'g': 1001553Srgrimes gflag++; 1011553Srgrimes break; 1021553Srgrimes case 'u': 1031553Srgrimes uflag++; 1041553Srgrimes break; 1051553Srgrimes case 'v': 1061553Srgrimes vflag++; 1071553Srgrimes break; 1081553Srgrimes default: 10930371Scharnier usage(); 1101553Srgrimes } 1111553Srgrimes } 1121553Srgrimes argc -= optind; 1131553Srgrimes argv += optind; 1141553Srgrimes if (argc <= 0 && !aflag) 11530371Scharnier usage(); 1161553Srgrimes if (!gflag && !uflag) { 1171553Srgrimes gflag++; 1181553Srgrimes uflag++; 1191553Srgrimes } 1201553Srgrimes setfsent(); 1211553Srgrimes while ((fs = getfsent()) != NULL) { 1221553Srgrimes if (strcmp(fs->fs_vfstype, "ufs") || 1231553Srgrimes strcmp(fs->fs_type, FSTAB_RW)) 1241553Srgrimes continue; 1251553Srgrimes if (aflag) { 1261553Srgrimes if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) 1271553Srgrimes errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp); 1281553Srgrimes if (uflag && hasquota(fs, USRQUOTA, &qfnp)) 1291553Srgrimes errs += quotaonoff(fs, offmode, USRQUOTA, qfnp); 1301553Srgrimes continue; 1311553Srgrimes } 1321553Srgrimes if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || 1331553Srgrimes (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { 1341553Srgrimes done |= 1 << argnum; 1351553Srgrimes if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) 1361553Srgrimes errs += quotaonoff(fs, offmode, GRPQUOTA, qfnp); 1371553Srgrimes if (uflag && hasquota(fs, USRQUOTA, &qfnp)) 1381553Srgrimes errs += quotaonoff(fs, offmode, USRQUOTA, qfnp); 1391553Srgrimes } 1401553Srgrimes } 1411553Srgrimes endfsent(); 1421553Srgrimes for (i = 0; i < argc; i++) 1431553Srgrimes if ((done & (1 << i)) == 0) 14430371Scharnier warnx("%s not found in fstab", argv[i]); 1451553Srgrimes exit(errs); 1461553Srgrimes} 1471553Srgrimes 14830371Scharnierstatic void 14930371Scharnierusage() 1501553Srgrimes{ 1511553Srgrimes 15230371Scharnier fprintf(stderr, "%s\n%s\n%s\n%s\n", 15330371Scharnier "usage: quotaon [-g] [-u] [-v] -a", 15430371Scharnier " quotaon [-g] [-u] [-v] filesystem ...", 15530371Scharnier " quotaoff [-g] [-u] [-v] -a", 15630371Scharnier " quotaoff [-g] [-u] [-v] filesystem ..."); 1571553Srgrimes exit(1); 1581553Srgrimes} 1591553Srgrimes 16030371Scharnierint 1611553Srgrimesquotaonoff(fs, offmode, type, qfpathname) 1621553Srgrimes register struct fstab *fs; 1631553Srgrimes int offmode, type; 1641553Srgrimes char *qfpathname; 1651553Srgrimes{ 1661553Srgrimes 1671553Srgrimes if (strcmp(fs->fs_file, "/") && readonly(fs)) 1681553Srgrimes return (1); 1691553Srgrimes if (offmode) { 1701553Srgrimes if (quotactl(fs->fs_file, QCMD(Q_QUOTAOFF, type), 0, 0) < 0) { 17130371Scharnier warn("%s", fs->fs_file); 1721553Srgrimes return (1); 1731553Srgrimes } 1741553Srgrimes if (vflag) 1751553Srgrimes printf("%s: quotas turned off\n", fs->fs_file); 1761553Srgrimes return (0); 1771553Srgrimes } 1781553Srgrimes if (quotactl(fs->fs_file, QCMD(Q_QUOTAON, type), 0, qfpathname) < 0) { 17930371Scharnier warnx("using %s on", qfpathname); 18030371Scharnier warn("%s", fs->fs_file); 1811553Srgrimes return (1); 1821553Srgrimes } 1831553Srgrimes if (vflag) 1841553Srgrimes printf("%s: %s quotas turned on\n", fs->fs_file, 1851553Srgrimes qfextension[type]); 1861553Srgrimes return (0); 1871553Srgrimes} 1881553Srgrimes 1891553Srgrimes/* 1901553Srgrimes * Check to see if target appears in list of size cnt. 1911553Srgrimes */ 19230371Scharnierint 1931553Srgrimesoneof(target, list, cnt) 1941553Srgrimes register char *target, *list[]; 1951553Srgrimes int cnt; 1961553Srgrimes{ 1971553Srgrimes register int i; 1981553Srgrimes 1991553Srgrimes for (i = 0; i < cnt; i++) 2001553Srgrimes if (strcmp(target, list[i]) == 0) 2011553Srgrimes return (i); 2021553Srgrimes return (-1); 2031553Srgrimes} 2041553Srgrimes 2051553Srgrimes/* 2061553Srgrimes * Check to see if a particular quota is to be enabled. 2071553Srgrimes */ 20830371Scharnierint 2091553Srgrimeshasquota(fs, type, qfnamep) 2101553Srgrimes register struct fstab *fs; 2111553Srgrimes int type; 2121553Srgrimes char **qfnamep; 2131553Srgrimes{ 2141553Srgrimes register char *opt; 21530371Scharnier char *cp; 2161553Srgrimes static char initname, usrname[100], grpname[100]; 2171553Srgrimes static char buf[BUFSIZ]; 2181553Srgrimes 2191553Srgrimes if (!initname) { 2201553Srgrimes sprintf(usrname, "%s%s", qfextension[USRQUOTA], qfname); 2211553Srgrimes sprintf(grpname, "%s%s", qfextension[GRPQUOTA], qfname); 2221553Srgrimes initname = 1; 2231553Srgrimes } 2241553Srgrimes strcpy(buf, fs->fs_mntops); 2251553Srgrimes for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) { 22630371Scharnier if ((cp = index(opt, '='))) 2271553Srgrimes *cp++ = '\0'; 2281553Srgrimes if (type == USRQUOTA && strcmp(opt, usrname) == 0) 2291553Srgrimes break; 2301553Srgrimes if (type == GRPQUOTA && strcmp(opt, grpname) == 0) 2311553Srgrimes break; 2321553Srgrimes } 2331553Srgrimes if (!opt) 2341553Srgrimes return (0); 2351553Srgrimes if (cp) { 2361553Srgrimes *qfnamep = cp; 2371553Srgrimes return (1); 2381553Srgrimes } 2391553Srgrimes (void) sprintf(buf, "%s/%s.%s", fs->fs_file, qfname, qfextension[type]); 2401553Srgrimes *qfnamep = buf; 2411553Srgrimes return (1); 2421553Srgrimes} 2431553Srgrimes 2441553Srgrimes/* 24596705Strhodes * Verify filesystem is mounted and not readonly. 2461553Srgrimes */ 24730371Scharnierint 2481553Srgrimesreadonly(fs) 2491553Srgrimes register struct fstab *fs; 2501553Srgrimes{ 2511553Srgrimes struct statfs fsbuf; 2521553Srgrimes 2531553Srgrimes if (statfs(fs->fs_file, &fsbuf) < 0 || 2541553Srgrimes strcmp(fsbuf.f_mntonname, fs->fs_file) || 2551553Srgrimes strcmp(fsbuf.f_mntfromname, fs->fs_spec)) { 2561553Srgrimes printf("%s: not mounted\n", fs->fs_file); 2571553Srgrimes return (1); 2581553Srgrimes } 2591553Srgrimes if (fsbuf.f_flags & MNT_RDONLY) { 2601553Srgrimes printf("%s: mounted read-only\n", fs->fs_file); 2611553Srgrimes return (1); 2621553Srgrimes } 2631553Srgrimes return (0); 2641553Srgrimes} 265