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$"); 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> 56207736Smckusick#include <libutil.h> 571553Srgrimes#include <stdio.h> 5878720Sdd#include <stdlib.h> 5930371Scharnier#include <string.h> 6030371Scharnier#include <unistd.h> 611553Srgrimes 6299822Salfredconst char *qfname = QUOTAFILENAME; 6399822Salfredconst char *qfextension[] = INITQFNAMES; 641553Srgrimes 6596705Strhodesint aflag; /* all filesystems */ 661553Srgrimesint gflag; /* operate on group quotas */ 671553Srgrimesint uflag; /* operate on user quotas */ 681553Srgrimesint vflag; /* verbose */ 691553Srgrimes 7099822Salfredint oneof(char *, char *[], int); 71207736Smckusickint quotaonoff(struct fstab *fs, int, int); 7299822Salfredstatic void usage(void); 7330371Scharnier 7430371Scharnierint 7599822Salfredmain(int argc, char **argv) 761553Srgrimes{ 77180187Sdes struct fstab *fs; 78207736Smckusick char *whoami; 791553Srgrimes long argnum, done = 0; 80124830Sgrehan int ch, i, offmode = 0, errs = 0; 811553Srgrimes 821553Srgrimes whoami = rindex(*argv, '/') + 1; 831553Srgrimes if (whoami == (char *)1) 841553Srgrimes whoami = *argv; 851553Srgrimes if (strcmp(whoami, "quotaoff") == 0) 861553Srgrimes offmode++; 8730371Scharnier else if (strcmp(whoami, "quotaon") != 0) 8830371Scharnier errx(1, "name must be quotaon or quotaoff"); 8924428Simp while ((ch = getopt(argc, argv, "avug")) != -1) { 901553Srgrimes switch(ch) { 911553Srgrimes case 'a': 921553Srgrimes aflag++; 931553Srgrimes break; 941553Srgrimes case 'g': 951553Srgrimes gflag++; 961553Srgrimes break; 971553Srgrimes case 'u': 981553Srgrimes uflag++; 991553Srgrimes break; 1001553Srgrimes case 'v': 1011553Srgrimes vflag++; 1021553Srgrimes break; 1031553Srgrimes default: 10430371Scharnier usage(); 1051553Srgrimes } 1061553Srgrimes } 1071553Srgrimes argc -= optind; 1081553Srgrimes argv += optind; 1091553Srgrimes if (argc <= 0 && !aflag) 11030371Scharnier usage(); 1111553Srgrimes if (!gflag && !uflag) { 1121553Srgrimes gflag++; 1131553Srgrimes uflag++; 1141553Srgrimes } 1151553Srgrimes setfsent(); 1161553Srgrimes while ((fs = getfsent()) != NULL) { 1171553Srgrimes if (strcmp(fs->fs_vfstype, "ufs") || 1181553Srgrimes strcmp(fs->fs_type, FSTAB_RW)) 1191553Srgrimes continue; 1201553Srgrimes if (aflag) { 121207736Smckusick if (gflag) 122207736Smckusick errs += quotaonoff(fs, offmode, GRPQUOTA); 123207736Smckusick if (uflag) 124207736Smckusick errs += quotaonoff(fs, offmode, USRQUOTA); 1251553Srgrimes continue; 1261553Srgrimes } 1271553Srgrimes if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || 1281553Srgrimes (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { 1291553Srgrimes done |= 1 << argnum; 130207736Smckusick if (gflag) 131207736Smckusick errs += quotaonoff(fs, offmode, GRPQUOTA); 132207736Smckusick if (uflag) 133207736Smckusick errs += quotaonoff(fs, offmode, USRQUOTA); 1341553Srgrimes } 1351553Srgrimes } 1361553Srgrimes endfsent(); 1371553Srgrimes for (i = 0; i < argc; i++) 1381553Srgrimes if ((done & (1 << i)) == 0) 13930371Scharnier warnx("%s not found in fstab", argv[i]); 1401553Srgrimes exit(errs); 1411553Srgrimes} 1421553Srgrimes 14330371Scharnierstatic void 144180187Sdesusage(void) 1451553Srgrimes{ 1461553Srgrimes 14730371Scharnier fprintf(stderr, "%s\n%s\n%s\n%s\n", 14830371Scharnier "usage: quotaon [-g] [-u] [-v] -a", 14930371Scharnier " quotaon [-g] [-u] [-v] filesystem ...", 15030371Scharnier " quotaoff [-g] [-u] [-v] -a", 15130371Scharnier " quotaoff [-g] [-u] [-v] filesystem ..."); 1521553Srgrimes exit(1); 1531553Srgrimes} 1541553Srgrimes 15530371Scharnierint 156207736Smckusickquotaonoff(struct fstab *fs, int offmode, int type) 1571553Srgrimes{ 158207736Smckusick struct quotafile *qf; 1591553Srgrimes 160207736Smckusick if ((qf = quota_open(fs, type, O_RDONLY)) == NULL) 161207736Smckusick return (0); 1621553Srgrimes if (offmode) { 163207736Smckusick if (quota_off(qf) != 0) { 164207736Smckusick warn("%s", quota_fsname(qf)); 1651553Srgrimes return (1); 1661553Srgrimes } 1671553Srgrimes if (vflag) 168207736Smckusick printf("%s: quotas turned off\n", quota_fsname(qf)); 169207736Smckusick quota_close(qf); 170207736Smckusick return(0); 1711553Srgrimes } 172207736Smckusick if (quota_on(qf) != 0) { 173207736Smckusick warn("using %s on %s", quota_qfname(qf), quota_fsname(qf)); 1741553Srgrimes return (1); 1751553Srgrimes } 1761553Srgrimes if (vflag) 177166212Smpp printf("%s: %s quotas turned on with data file %s\n", 178207736Smckusick quota_fsname(qf), qfextension[type], quota_qfname(qf)); 179207736Smckusick quota_close(qf); 180207736Smckusick return(0); 1811553Srgrimes} 1821553Srgrimes 1831553Srgrimes/* 1841553Srgrimes * Check to see if target appears in list of size cnt. 1851553Srgrimes */ 18630371Scharnierint 187180187Sdesoneof(char *target, char *list[], int cnt) 1881553Srgrimes{ 189180187Sdes int i; 1901553Srgrimes 1911553Srgrimes for (i = 0; i < cnt; i++) 1921553Srgrimes if (strcmp(target, list[i]) == 0) 1931553Srgrimes return (i); 1941553Srgrimes return (-1); 1951553Srgrimes} 196