1: /*
   2:  * Copyright (c) 1980 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  */
   6: 
   7: #if defined(DOSCCS) && !defined(lint)
   8: char copyright[] =
   9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\
  10:  All rights reserved.\n";
  11: 
  12: static char sccsid[] = "@(#)quota.c	5.4.3 (2.11BSD GTE) 1996/2/7";
  13: #endif
  14: 
  15: /*
  16:  * Disk quota reporting program.
  17:  */
  18: #include <stdio.h>
  19: #include <fstab.h>
  20: #include <ctype.h>
  21: #include <pwd.h>
  22: #include <errno.h>
  23: #include <string.h>
  24: 
  25: #include <sys/param.h>
  26: #include <sys/quota.h>
  27: #include <sys/file.h>
  28: #include <sys/stat.h>
  29: 
  30: int qflag;
  31: int vflag;
  32: int done;
  33: int morethanone;
  34: char    *qfname = "quotas";
  35: 
  36: main(argc, argv)
  37:     char *argv[];
  38: {
  39:     register char *cp;
  40:     extern int errno;
  41: 
  42:     if (quota(Q_SYNC, 0, 0, (caddr_t)0) < 0 && errno == EINVAL) {
  43:         fprintf(stderr, "There are no quotas on this system\n");
  44:         exit(0);
  45:     }
  46:     argc--,argv++;
  47:     while (argc > 0) {
  48:         if (argv[0][0] == '-')
  49:             for (cp = &argv[0][1]; *cp; cp++) switch (*cp) {
  50: 
  51:             case 'v':
  52:                 vflag++;
  53:                 break;
  54: 
  55:             case 'q':
  56:                 qflag++;
  57:                 break;
  58: 
  59:             default:
  60:                 fprintf(stderr, "quota: %c: unknown option\n",
  61:                     *cp);
  62:                 exit(1);
  63:             }
  64:         else
  65:             break;
  66:         argc--, argv++;
  67:     }
  68:     morethanone = argc > 1;
  69:     if (argc == 0) {
  70:         showuid(getuid());
  71:         exit(0);
  72:     }
  73:     for (; argc > 0; argc--, argv++) {
  74:         if (alldigits(*argv))
  75:             showuid(atoi(*argv));
  76:         else
  77:             showname(*argv);
  78:     }
  79: }
  80: 
  81: showuid(uid)
  82:     int uid;
  83: {
  84:     struct passwd *pwd = getpwuid(uid);
  85: 
  86:     if (pwd == NULL)
  87:         showquotas(uid, "(no account)");
  88:     else
  89:         showquotas(uid, pwd->pw_name);
  90: }
  91: 
  92: showname(name)
  93:     char *name;
  94: {
  95:     struct passwd *pwd = getpwnam(name);
  96: 
  97:     if (pwd == NULL) {
  98:         fprintf(stderr, "quota: %s: unknown user\n", name);
  99:         return;
 100:     }
 101:     showquotas(pwd->pw_uid, name);
 102: }
 103: 
 104: showquotas(uid, name)
 105:     int uid;
 106:     char *name;
 107: {
 108:     register struct fstab *fs;
 109:     register char *msgi, *msgb;
 110:     register enab = 1;
 111:     dev_t fsdev;
 112:     struct  stat statb;
 113:     char *qfpathname;
 114:     struct  dqblk dqblk;
 115:     int myuid, fd;
 116:     char iwarn[8], dwarn[8];
 117: 
 118:     myuid = getuid();
 119:     if (uid != myuid && myuid != 0) {
 120:         printf("quota: %s (uid %d): permission denied\n", name, uid);
 121:         return;
 122:     }
 123:     done = 0;
 124:     (void) setfsent();
 125:     while (fs = getfsent()) {
 126:         if (strcmp(fs->fs_vfstype, "ufs"))
 127:             continue;
 128:         if (!hasquota(fs, &qfpathname))
 129:             continue;
 130:         if (stat(fs->fs_spec, &statb) < 0)
 131:             continue;
 132:         msgi = msgb = (char *) 0;
 133: /*
 134:  * This check for the quota file being in the filesystem to which the quotas
 135:  * belong is silly but the kernel enforces it.   When the kernel is fixed the
 136:  * check can be removed.
 137: */
 138:         fsdev = statb.st_rdev;
 139:         if (stat(qfpathname, &statb) < 0 || statb.st_dev != fsdev)
 140:             continue;
 141:         if (quota(Q_GETDLIM, uid, fsdev, (caddr_t)&dqblk)) {
 142:             fd = open(qfpathname, O_RDONLY);
 143:             if (fd < 0)
 144:                 continue;
 145:             (void) lseek(fd, (off_t)(uid * sizeof (dqblk)), L_SET);
 146:             switch (read(fd, (char *)&dqblk, sizeof dqblk)) {
 147:             case 0:         /* EOF */
 148:                 /*
 149: 				 * Convert implicit 0 quota (EOF)
 150: 				 * into an explicit one (zero'ed dqblk).
 151: 				 */
 152:                 bzero((caddr_t)&dqblk, sizeof dqblk);
 153:                 break;
 154: 
 155:             case sizeof dqblk:  /* OK */
 156: #ifdef pdp11
 157:                 dqblk.dqb_curblocks= btodb(dqblk.dqb_curblocks);
 158:                 dqblk.dqb_bsoftlimit = btodb(dqblk.dqb_bsoftlimit);
 159:                 dqblk.dqb_bhardlimit = btodb(dqblk.dqb_bhardlimit);
 160: #endif
 161:                 break;
 162: 
 163:             default:        /* ERROR */
 164:                 fprintf(stderr, "quota: read error in ");
 165:                 perror(qfpathname);
 166:                 (void) close(fd);
 167:                 continue;
 168:             }
 169:             (void) close(fd);
 170:             if (!vflag && dqblk.dqb_isoftlimit == 0 &&
 171:                 dqblk.dqb_bsoftlimit == 0)
 172:                 continue;
 173:             enab = 0;
 174:         }
 175:         if (dqblk.dqb_ihardlimit &&
 176:             dqblk.dqb_curinodes >= dqblk.dqb_ihardlimit)
 177:             msgi = "File count limit reached on %s";
 178:         else if (enab && dqblk.dqb_iwarn == 0)
 179:             msgi = "Out of inode warnings on %s";
 180:         else if (dqblk.dqb_isoftlimit &&
 181:             dqblk.dqb_curinodes >= dqblk.dqb_isoftlimit)
 182:             msgi = "Too many files on %s";
 183:         if (dqblk.dqb_bhardlimit &&
 184:             dqblk.dqb_curblocks >= dqblk.dqb_bhardlimit)
 185:             msgb = "Block limit reached on %s";
 186:         else if (enab && dqblk.dqb_bwarn == 0)
 187:             msgb = "Out of block warnings on %s";
 188:         else if (dqblk.dqb_bsoftlimit &&
 189:             dqblk.dqb_curblocks >= dqblk.dqb_bsoftlimit)
 190:             msgb = "Over disc quota on %s";
 191:         if (dqblk.dqb_iwarn < MAX_IQ_WARN)
 192:             (void) sprintf(iwarn, "%d", dqblk.dqb_iwarn);
 193:         else
 194:             iwarn[0] = '\0';
 195:         if (dqblk.dqb_bwarn < MAX_DQ_WARN)
 196:             (void) sprintf(dwarn, "%d", dqblk.dqb_bwarn);
 197:         else
 198:             dwarn[0] = '\0';
 199:         if (qflag) {
 200:             if (msgi != (char *)0 || msgb != (char *)0)
 201:                 heading(uid, name);
 202:             if (msgi != (char *)0)
 203:                 xprintf(msgi, fs->fs_file);
 204:             if (msgb != (char *)0)
 205:                 xprintf(msgb, fs->fs_file);
 206:             continue;
 207:         }
 208:         if (vflag || dqblk.dqb_curblocks || dqblk.dqb_curinodes) {
 209:             heading(uid, name);
 210: #ifdef pdp11
 211:             printf("%10s%8ld%c%7ld%8ld%8s%8d%c%7u%8u%8s\n"
 212:                 , fs->fs_file
 213:                 , dqblk.dqb_curblocks
 214:                 , (msgb == (char *)0) ? ' ' : '*'
 215:                 , dqblk.dqb_bsoftlimit
 216:                 , dqblk.dqb_bhardlimit
 217: #else
 218:             printf("%10s%8d%c%7d%8d%8s%8d%c%7d%8d%8s\n"
 219:                 , fs->fs_file
 220:                 , dbtob(dqblk.dqb_curblocks) / 1024
 221:                 , (msgb == (char *)0) ? ' ' : '*'
 222:                 , dbtob(dqblk.dqb_bsoftlimit) / 1024
 223:                 , dbtob(dqblk.dqb_bhardlimit) / 1024
 224: #endif
 225:                 , dwarn
 226:                 , dqblk.dqb_curinodes
 227:                 , (msgi == (char *)0) ? ' ' : '*'
 228:                 , dqblk.dqb_isoftlimit
 229:                 , dqblk.dqb_ihardlimit
 230:                 , iwarn
 231:             );
 232:         }
 233:     }
 234:     (void) endfsent();
 235:     if (!done && !qflag) {
 236:         if (morethanone)
 237:             (void) putchar('\n');
 238:         xprintf("Disc quotas for %s (uid %d):", name, uid);
 239:         xprintf("none.");
 240:     }
 241:     xprintf((char *)0);
 242: }
 243: 
 244: heading(uid, name)
 245:     int uid;
 246:     char *name;
 247: {
 248: 
 249:     if (done++)
 250:         return;
 251:     xprintf((char *)0);
 252:     if (qflag) {
 253:         if (!morethanone)
 254:             return;
 255:         xprintf("User %s (uid %d):", name, uid);
 256:         xprintf((char *)0);
 257:         return;
 258:     }
 259:     (void) putchar('\n');
 260:     xprintf("Disc quotas for %s (uid %d):", name, uid);
 261:     xprintf((char *)0);
 262:     printf("%10s%8s %7s%8s%8s%8s %7s%8s%8s\n"
 263:         , "Filsys"
 264:         , "current"
 265:         , "quota"
 266:         , "limit"
 267:         , "#warns"
 268:         , "files"
 269:         , "quota"
 270:         , "limit"
 271:         , "#warns"
 272:     );
 273: }
 274: 
 275: /*VARARGS1*/
 276: xprintf(fmt, arg1, arg2, arg3, arg4, arg5, arg6)
 277:     char *fmt;
 278: {
 279:     char    buf[100];
 280:     static int column;
 281: 
 282:     if (fmt == 0 && column || column >= 40) {
 283:         (void) putchar('\n');
 284:         column = 0;
 285:     }
 286:     if (fmt == 0)
 287:         return;
 288:     (void) sprintf(buf, fmt, arg1, arg2, arg3, arg4, arg5, arg6);
 289:     if (column != 0 && strlen(buf) < 39)
 290:         while (column++ < 40)
 291:             (void) putchar(' ');
 292:     else if (column) {
 293:         (void) putchar('\n');
 294:         column = 0;
 295:     }
 296:     printf("%s", buf);
 297:     column += strlen(buf);
 298: }
 299: 
 300: /*
 301:  * Check to see if a particular quota is to be enabled.
 302:  */
 303: hasquota(fs, qfnamep)
 304:     register struct fstab *fs;
 305:     char **qfnamep;
 306: {
 307:     register char *opt;
 308:     char *cp;
 309:     static char initname, usrname[100];
 310:     static char buf[BUFSIZ];
 311: 
 312:     if (!initname) {
 313:         strcpy(usrname, qfname);
 314:         initname = 1;
 315:     }
 316:     strcpy(buf, fs->fs_mntops);
 317:     for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) {
 318:         if (cp = index(opt, '='))
 319:             *cp++ = '\0';
 320:         if (strcmp(opt, usrname) == 0)
 321:             break;
 322:         if (strcmp(opt, FSTAB_RQ) == 0) /* XXX compatibility */
 323:             break;
 324:     }
 325:     if (!opt)
 326:         return (0);
 327:     if (cp) {
 328:         *qfnamep = cp;
 329:         return (1);
 330:     }
 331:     (void) sprintf(buf, "%s/%s", fs->fs_file, qfname);
 332:     *qfnamep = buf;
 333:     return (1);
 334: }
 335: 
 336: alldigits(s)
 337:     register char *s;
 338: {
 339:     register c;
 340: 
 341:     c = *s++;
 342:     do {
 343:         if (!isdigit(c))
 344:             return (0);
 345:     } while (c = *s++);
 346:     return (1);
 347: }

Defined functions

alldigits defined in line 336; used 1 times
  • in line 74
hasquota defined in line 303; used 1 times
heading defined in line 244; used 2 times
main defined in line 36; never used
showname defined in line 92; used 1 times
  • in line 77
showquotas defined in line 104; used 3 times
showuid defined in line 81; used 2 times
xprintf defined in line 276; used 10 times

Defined variables

copyright defined in line 8; never used
done defined in line 32; used 3 times
morethanone defined in line 33; used 3 times
qflag defined in line 30; used 4 times
qfname defined in line 34; used 2 times
sccsid defined in line 12; never used
vflag defined in line 31; used 3 times
Last modified: 1996-02-08
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3477
Valid CSS Valid XHTML 1.0 Strict