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 62241737Sedstatic const char *qfextension[] = INITQFNAMES; 631553Srgrimes 64241737Sedstatic int aflag; /* all filesystems */ 65241737Sedstatic int gflag; /* operate on group quotas */ 66241737Sedstatic int uflag; /* operate on user quotas */ 67241737Sedstatic int vflag; /* verbose */ 681553Srgrimes 69241737Sedstatic int oneof(char *, char *[], int); 70241737Sedstatic int quotaonoff(struct fstab *fs, int, int); 7199822Salfredstatic void usage(void); 7230371Scharnier 7330371Scharnierint 7499822Salfredmain(int argc, char **argv) 751553Srgrimes{ 76180187Sdes struct fstab *fs; 77229384Sed const char *whoami; 781553Srgrimes long argnum, done = 0; 79124830Sgrehan int ch, i, offmode = 0, errs = 0; 801553Srgrimes 81229384Sed whoami = getprogname(); 821553Srgrimes if (strcmp(whoami, "quotaoff") == 0) 831553Srgrimes offmode++; 8430371Scharnier else if (strcmp(whoami, "quotaon") != 0) 8530371Scharnier errx(1, "name must be quotaon or quotaoff"); 8624428Simp while ((ch = getopt(argc, argv, "avug")) != -1) { 871553Srgrimes switch(ch) { 881553Srgrimes case 'a': 891553Srgrimes aflag++; 901553Srgrimes break; 911553Srgrimes case 'g': 921553Srgrimes gflag++; 931553Srgrimes break; 941553Srgrimes case 'u': 951553Srgrimes uflag++; 961553Srgrimes break; 971553Srgrimes case 'v': 981553Srgrimes vflag++; 991553Srgrimes break; 1001553Srgrimes default: 10130371Scharnier usage(); 1021553Srgrimes } 1031553Srgrimes } 1041553Srgrimes argc -= optind; 1051553Srgrimes argv += optind; 1061553Srgrimes if (argc <= 0 && !aflag) 10730371Scharnier usage(); 1081553Srgrimes if (!gflag && !uflag) { 1091553Srgrimes gflag++; 1101553Srgrimes uflag++; 1111553Srgrimes } 1121553Srgrimes setfsent(); 1131553Srgrimes while ((fs = getfsent()) != NULL) { 1141553Srgrimes if (strcmp(fs->fs_vfstype, "ufs") || 1151553Srgrimes strcmp(fs->fs_type, FSTAB_RW)) 1161553Srgrimes continue; 1171553Srgrimes if (aflag) { 118207736Smckusick if (gflag) 119207736Smckusick errs += quotaonoff(fs, offmode, GRPQUOTA); 120207736Smckusick if (uflag) 121207736Smckusick errs += quotaonoff(fs, offmode, USRQUOTA); 1221553Srgrimes continue; 1231553Srgrimes } 1241553Srgrimes if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 || 1251553Srgrimes (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) { 1261553Srgrimes done |= 1 << argnum; 127207736Smckusick if (gflag) 128207736Smckusick errs += quotaonoff(fs, offmode, GRPQUOTA); 129207736Smckusick if (uflag) 130207736Smckusick errs += quotaonoff(fs, offmode, USRQUOTA); 1311553Srgrimes } 1321553Srgrimes } 1331553Srgrimes endfsent(); 1341553Srgrimes for (i = 0; i < argc; i++) 1351553Srgrimes if ((done & (1 << i)) == 0) 13630371Scharnier warnx("%s not found in fstab", argv[i]); 1371553Srgrimes exit(errs); 1381553Srgrimes} 1391553Srgrimes 14030371Scharnierstatic void 141180187Sdesusage(void) 1421553Srgrimes{ 1431553Srgrimes 14430371Scharnier fprintf(stderr, "%s\n%s\n%s\n%s\n", 14530371Scharnier "usage: quotaon [-g] [-u] [-v] -a", 14630371Scharnier " quotaon [-g] [-u] [-v] filesystem ...", 14730371Scharnier " quotaoff [-g] [-u] [-v] -a", 14830371Scharnier " quotaoff [-g] [-u] [-v] filesystem ..."); 1491553Srgrimes exit(1); 1501553Srgrimes} 1511553Srgrimes 152241737Sedstatic int 153207736Smckusickquotaonoff(struct fstab *fs, int offmode, int type) 1541553Srgrimes{ 155207736Smckusick struct quotafile *qf; 1561553Srgrimes 157207736Smckusick if ((qf = quota_open(fs, type, O_RDONLY)) == NULL) 158207736Smckusick return (0); 1591553Srgrimes if (offmode) { 160207736Smckusick if (quota_off(qf) != 0) { 161207736Smckusick warn("%s", quota_fsname(qf)); 1621553Srgrimes return (1); 1631553Srgrimes } 1641553Srgrimes if (vflag) 165207736Smckusick printf("%s: quotas turned off\n", quota_fsname(qf)); 166207736Smckusick quota_close(qf); 167207736Smckusick return(0); 1681553Srgrimes } 169207736Smckusick if (quota_on(qf) != 0) { 170207736Smckusick warn("using %s on %s", quota_qfname(qf), quota_fsname(qf)); 1711553Srgrimes return (1); 1721553Srgrimes } 1731553Srgrimes if (vflag) 174166212Smpp printf("%s: %s quotas turned on with data file %s\n", 175207736Smckusick quota_fsname(qf), qfextension[type], quota_qfname(qf)); 176207736Smckusick quota_close(qf); 177207736Smckusick return(0); 1781553Srgrimes} 1791553Srgrimes 1801553Srgrimes/* 1811553Srgrimes * Check to see if target appears in list of size cnt. 1821553Srgrimes */ 183241737Sedstatic int 184180187Sdesoneof(char *target, char *list[], int cnt) 1851553Srgrimes{ 186180187Sdes int i; 1871553Srgrimes 1881553Srgrimes for (i = 0; i < cnt; i++) 1891553Srgrimes if (strcmp(target, list[i]) == 0) 1901553Srgrimes return (i); 1911553Srgrimes return (-1); 1921553Srgrimes} 193