1: /*
   2:  * Copyright (c) 1980, 1990, 1993
   3:  *	The Regents of the University of California.  All rights reserved.
   4:  *
   5:  * This code is derived from software contributed to Berkeley by
   6:  * Robert Elz at The University of Melbourne.
   7:  *
   8:  * Redistribution and use in source and binary forms, with or without
   9:  * modification, are permitted provided that the following conditions
  10:  * are met:
  11:  * 1. Redistributions of source code must retain the above copyright
  12:  *    notice, this list of conditions and the following disclaimer.
  13:  * 2. Redistributions in binary form must reproduce the above copyright
  14:  *    notice, this list of conditions and the following disclaimer in the
  15:  *    documentation and/or other materials provided with the distribution.
  16:  * 3. All advertising materials mentioning features or use of this software
  17:  *    must display the following acknowledgement:
  18:  *	This product includes software developed by the University of
  19:  *	California, Berkeley and its contributors.
  20:  * 4. Neither the name of the University nor the names of its contributors
  21:  *    may be used to endorse or promote products derived from this software
  22:  *    without specific prior written permission.
  23:  *
  24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  34:  * SUCH DAMAGE.
  35:  */
  36: 
  37: #if !defined(lint) && defined(DOSCCS)
  38: static char copyright[] =
  39: "@(#) Copyright (c) 1980, 1990, 1993\n\
  40: 	The Regents of the University of California.  All rights reserved.\n";
  41: 
  42: static char sccsid[] = "@(#)repquota.c	8.1 (Berkeley) 6/6/93";
  43: #endif /* not lint */
  44: 
  45: /*
  46:  * Quota report
  47:  */
  48: #include <sys/param.h>
  49: #include <sys/stat.h>
  50: #include <sys/quota.h>
  51: #include <fstab.h>
  52: #include <pwd.h>
  53: #include <stdio.h>
  54: #include <errno.h>
  55: #include <string.h>
  56: 
  57: char *qfname = QUOTAFILENAME;
  58: 
  59: struct fileusage {
  60:     struct  fileusage *fu_next;
  61:     struct  dqblk fu_dqblk;
  62:     u_int   fu_id;
  63:     char    fu_name[1];
  64:     /* actually bigger */
  65: };
  66: #define FUHASH 256  /* must be power of two */
  67: struct fileusage *fuhead[FUHASH];
  68: struct fileusage *lookup();
  69: struct fileusage *addid();
  70: u_int highid;       /* highest addid()'ed identifier per type */
  71: 
  72: int vflag;          /* verbose */
  73: int aflag;          /* all file systems */
  74: 
  75: main(argc, argv)
  76:     int argc;
  77:     char **argv;
  78: {
  79:     register struct fstab *fs;
  80:     register struct passwd *pw;
  81:     int errs = 0;
  82:     int i, argnum;
  83:     long done = 0;
  84:     extern char *optarg;
  85:     extern int optind;
  86:     char ch, *qfnp;
  87: 
  88:     while ((ch = getopt(argc, argv, "aguv")) != EOF) {
  89:         switch(ch) {
  90:         case 'a':
  91:             aflag++;
  92:             break;
  93:         case 'v':
  94:             vflag++;
  95:             break;
  96:         default:
  97:             usage();
  98:         }
  99:     }
 100:     argc -= optind;
 101:     argv += optind;
 102:     if (argc == 0 && !aflag)
 103:         usage();
 104: 
 105:     setpwent();
 106:     while ((pw = getpwent()) != 0)
 107:         (void) addid(pw->pw_uid, pw->pw_name);
 108:     endpwent();
 109: 
 110:     setfsent();
 111:     while ((fs = getfsent()) != NULL) {
 112:         if (strcmp(fs->fs_vfstype, "ufs"))
 113:             continue;
 114:         if (aflag) {
 115:             if (hasquota(fs, &qfnp))
 116:                 errs += repquota(fs, qfnp);
 117:             continue;
 118:         }
 119:         if ((argnum = oneof(fs->fs_file, argv, argc)) >= 0 ||
 120:             (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) {
 121:             done |= 1 << argnum;
 122:             if (hasquota(fs, &qfnp))
 123:                 errs += repquota(fs, qfnp);
 124:         }
 125:     }
 126:     endfsent();
 127:     for (i = 0; i < argc; i++)
 128:         if ((done & (1 << i)) == 0)
 129:             fprintf(stderr, "%s not found in fstab\n", argv[i]);
 130:     exit(errs);
 131: }
 132: 
 133: usage()
 134: {
 135:     fprintf(stderr, "Usage:\n\t%s\n\t%s\n",
 136:         "repquota [-v] [-g] [-u] -a",
 137:         "repquota [-v] [-g] [-u] filesys ...");
 138:     exit(1);
 139: }
 140: 
 141: repquota(fs, qfpathname)
 142:     register struct fstab *fs;
 143:     char *qfpathname;
 144: {
 145:     register struct fileusage *fup;
 146:     FILE *qf;
 147:     u_int id;
 148:     struct dqblk dqbuf;
 149:     struct stat statb;
 150:     static struct dqblk zerodqblk;
 151:     static int warned = 0;
 152:     static int multiple = 0;
 153:     extern int errno;
 154: 
 155:     if ((qf = fopen(qfpathname, "r")) == NULL) {
 156:         perror(qfpathname);
 157:         return (1);
 158:     }
 159:     if (fstat(fileno(qf), &statb) < 0) {
 160:         perror(qfpathname);
 161:         fclose(qf);
 162:         return(1);
 163:     }
 164:     if (quota(Q_SYNC, 0, statb.st_dev, 0) < 0 &&
 165:         errno == EOPNOTSUPP && !warned && vflag) {
 166:         warned++;
 167:         fprintf(stdout,
 168:             "*** Warning: Quotas are not compiled into this kernel\n");
 169:     }
 170:     if (multiple++)
 171:         printf("\n");
 172:     if (vflag)
 173:         fprintf(stdout, "*** Report for quotas on %s (%s)\n",
 174:             fs->fs_file, fs->fs_spec);
 175:     for (id = 0; ; id++) {
 176:         fread(&dqbuf, sizeof(struct dqblk), 1, qf);
 177:         if (feof(qf))
 178:             break;
 179:         if (dqbuf.dqb_curinodes == 0 && dqbuf.dqb_curblocks == 0)
 180:             continue;
 181:         if ((fup = lookup(id)) == 0)
 182:             fup = addid(id, (char *)0);
 183:         fup->fu_dqblk = dqbuf;
 184:     }
 185:     fclose(qf);
 186:     printf("                        Block limits               File limits\n");
 187:     printf("User            used    soft    hard  warn    used  soft  hard  warn\n");
 188:     for (id = 0; id <= highid; id++) {
 189:         fup = lookup(id);
 190:         if (fup == 0)
 191:             continue;
 192:         if (fup->fu_dqblk.dqb_curinodes == 0 &&
 193:             fup->fu_dqblk.dqb_curblocks == 0)
 194:             continue;
 195:         printf("%-10s", fup->fu_name);
 196:         printf("%c%c%8ld%8ld%8ld%5u",
 197:             fup->fu_dqblk.dqb_bsoftlimit &&
 198:                 fup->fu_dqblk.dqb_curblocks >=
 199:                 fup->fu_dqblk.dqb_bsoftlimit ? '+' : '-',
 200:             fup->fu_dqblk.dqb_isoftlimit &&
 201:                 fup->fu_dqblk.dqb_curinodes >=
 202:                 fup->fu_dqblk.dqb_isoftlimit ? '+' : '-',
 203:             fup->fu_dqblk.dqb_curblocks / 1024,
 204:             fup->fu_dqblk.dqb_bsoftlimit / 1024,
 205:             fup->fu_dqblk.dqb_bhardlimit / 1024,
 206:             fup->fu_dqblk.dqb_bwarn);
 207: 
 208:         printf("  %6u%6u%6u%6u\n",
 209:             fup->fu_dqblk.dqb_curinodes,
 210:             fup->fu_dqblk.dqb_isoftlimit,
 211:             fup->fu_dqblk.dqb_ihardlimit,
 212:             fup->fu_dqblk.dqb_iwarn);
 213:         fup->fu_dqblk = zerodqblk;
 214:     }
 215:     return (0);
 216: }
 217: 
 218: /*
 219:  * Check to see if target appears in list of size cnt.
 220:  */
 221: oneof(target, list, cnt)
 222:     register char *target, *list[];
 223:     int cnt;
 224: {
 225:     register int i;
 226: 
 227:     for (i = 0; i < cnt; i++)
 228:         if (strcmp(target, list[i]) == 0)
 229:             return (i);
 230:     return (-1);
 231: }
 232: 
 233: /*
 234:  * Check to see if a particular quota is to be enabled.
 235:  */
 236: hasquota(fs, qfnamep)
 237:     register struct fstab *fs;
 238:     char **qfnamep;
 239: {
 240:     register char *opt;
 241:     char *cp;
 242:     static char initname, usrname[100];
 243:     static char buf[BUFSIZ];
 244: 
 245:     if (!initname) {
 246:         strcpy(usrname, qfname);
 247:         initname = 1;
 248:     }
 249:     strcpy(buf, fs->fs_mntops);
 250:     for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) {
 251:         if (cp = index(opt, '='))
 252:             *cp++ = '\0';
 253:         if (strcmp(opt, usrname) == 0)
 254:             break;
 255:         if (strcmp(opt, FSTAB_RQ) == 0) /* XXX compatibility */
 256:             break;
 257:     }
 258:     if (!opt)
 259:         return (0);
 260:     if (cp) {
 261:         *qfnamep = cp;
 262:         return (1);
 263:     }
 264:     (void) sprintf(buf, "%s/%s", fs->fs_file, qfname);
 265:     *qfnamep = buf;
 266:     return (1);
 267: }
 268: 
 269: /*
 270:  * Routines to manage the file usage table.
 271:  *
 272:  * Lookup an id.
 273:  */
 274: struct fileusage *
 275: lookup(id)
 276:     u_int id;
 277: {
 278:     register struct fileusage *fup;
 279: 
 280:     for (fup = fuhead[id & (FUHASH-1)]; fup != 0; fup = fup->fu_next)
 281:         if (fup->fu_id == id)
 282:             return (fup);
 283:     return ((struct fileusage *)0);
 284: }
 285: 
 286: /*
 287:  * Add a new file usage id if it does not already exist.
 288:  */
 289: struct fileusage *
 290: addid(id, name)
 291:     u_short id;
 292:     char *name;
 293: {
 294:     struct fileusage *fup, **fhp;
 295:     int len;
 296:     extern char *calloc();
 297: 
 298:     if (fup = lookup(id))
 299:         return (fup);
 300:     if (name)
 301:         len = strlen(name);
 302:     else
 303:         len = 10;
 304:     if ((fup = (struct fileusage *)calloc(1, sizeof(*fup) + len)) == NULL) {
 305:         fprintf(stderr, "out of memory for fileusage structures\n");
 306:         exit(1);
 307:     }
 308:     fhp = &fuhead[id & (FUHASH - 1)];
 309:     fup->fu_next = *fhp;
 310:     *fhp = fup;
 311:     fup->fu_id = id;
 312:     if (id > highid)
 313:         highid = id;
 314:     if (name) {
 315:         bcopy(name, fup->fu_name, len + 1);
 316:     } else {
 317:         sprintf(fup->fu_name, "%u", id);
 318:     }
 319:     return (fup);
 320: }

Defined functions

addid defined in line 289; used 3 times
hasquota defined in line 236; used 2 times
lookup defined in line 274; used 4 times
main defined in line 75; never used
oneof defined in line 221; used 2 times
repquota defined in line 141; used 2 times
usage defined in line 133; used 2 times

Defined variables

aflag defined in line 73; used 3 times
copyright defined in line 38; never used
fuhead defined in line 67; used 2 times
highid defined in line 70; used 3 times
qfname defined in line 57; used 2 times
sccsid defined in line 42; never used
vflag defined in line 72; used 3 times

Defined struct's

fileusage defined in line 59; used 22 times

Defined macros

FUHASH defined in line 66; used 3 times
Last modified: 1996-01-24
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 4226
Valid CSS Valid XHTML 1.0 Strict