1: #ifndef lint
   2: static char *sccsid = "@(#)quot.c	4.11 (Berkeley) 85/09/09";
   3: #endif
   4: 
   5: /*
   6:  * quot
   7:  */
   8: 
   9: #include <stdio.h>
  10: #include <ctype.h>
  11: #include <sys/param.h>
  12: #include <sys/inode.h>
  13: #include <sys/fs.h>
  14: #include <sys/file.h>
  15: 
  16: #define ISIZ    (MAXBSIZE/sizeof(struct dinode))
  17: union {
  18:     struct fs u_sblock;
  19:     char dummy[SBSIZE];
  20: } sb_un;
  21: #define sblock sb_un.u_sblock
  22: struct dinode itab[MAXBSIZE/sizeof(struct dinode)];
  23: 
  24: struct du {
  25:     struct  du *next;
  26:     long    blocks;
  27:     long    blocks30;
  28:     long    blocks60;
  29:     long    blocks90;
  30:     long    nfiles;
  31:     int uid;
  32: #define NDU 2048
  33: } du[NDU];
  34: int ndu;
  35: #define DUHASH  8209    /* smallest prime >= 4 * NDU */
  36: #define HASH(u) ((u) % DUHASH)
  37: struct  du *duhash[DUHASH];
  38: 
  39: #define TSIZE   500
  40: int sizes[TSIZE];
  41: long    overflow;
  42: 
  43: int nflg;
  44: int fflg;
  45: int cflg;
  46: int vflg;
  47: int hflg;
  48: long    now;
  49: 
  50: unsigned    ino;
  51: 
  52: char    *malloc();
  53: char    *getname();
  54: 
  55: main(argc, argv)
  56:     int argc;
  57:     char *argv[];
  58: {
  59:     register int n;
  60: 
  61:     now = time(0);
  62:     argc--, argv++;
  63:     while (argc > 0 && argv[0][0] == '-') {
  64:         register char *cp;
  65: 
  66:         for (cp = &argv[0][1]; *cp; cp++)
  67:             switch (*cp) {
  68:             case 'n':
  69:                 nflg++; break;
  70:             case 'f':
  71:                 fflg++; break;
  72:             case 'c':
  73:                 cflg++; break;
  74:             case 'v':
  75:                 vflg++; break;
  76:             case 'h':
  77:                 hflg++; break;
  78:             default:
  79:                 fprintf(stderr,
  80:                     "usage: quot [ -nfcvh ] [ device ... ]\n");
  81:                 exit(1);
  82:             }
  83:         argc--, argv++;
  84:     }
  85:     if (argc == 0)
  86:         quotall();
  87:     while (argc-- > 0)
  88:         if (check(*argv++, (char *)NULL) == 0)
  89:             report();
  90:     exit (0);
  91: }
  92: 
  93: #include <fstab.h>
  94: 
  95: quotall()
  96: {
  97:     register struct fstab *fs;
  98:     register char *cp;
  99:     char dev[80], *rindex();
 100: 
 101:     if (setfsent() == 0) {
 102:         fprintf(stderr, "quot: no %s file\n", FSTAB);
 103:         exit(1);
 104:     }
 105:     while (fs = getfsent()) {
 106:         if (strcmp(fs->fs_type, FSTAB_RO) &&
 107:             strcmp(fs->fs_type, FSTAB_RW) &&
 108:             strcmp(fs->fs_type, FSTAB_RQ))
 109:             continue;
 110:         cp = rindex(fs->fs_spec, '/');
 111:         if (cp == 0)
 112:             continue;
 113:         sprintf(dev, "/dev/r%s", cp + 1);
 114:         if (check(dev, fs->fs_file) == 0)
 115:             report();
 116:     }
 117:     endfsent();
 118: }
 119: 
 120: check(file, fsdir)
 121:     char *file;
 122:     char *fsdir;
 123: {
 124:     register int i, j, nfiles;
 125:     register struct du **dp;
 126:     daddr_t iblk;
 127:     int c, fd;
 128: 
 129:     /*
 130: 	 * Initialize tables between checks;
 131: 	 * because of the qsort done in report()
 132: 	 * the hash tables must be rebuilt each time.
 133: 	 */
 134:     for (i = 0; i < TSIZE; i++)
 135:         sizes[i] = 0;
 136:     overflow = 0;
 137:     for (dp = duhash; dp < &duhash[DUHASH]; dp++)
 138:         *dp = 0;
 139:     ndu = 0;
 140:     fd = open(file, O_RDONLY);
 141:     if (fd < 0) {
 142:         fprintf(stderr, "quot: ");
 143:         perror(file);
 144:         return (-1);
 145:     }
 146:     printf("%s", file);
 147:     if (fsdir == NULL) {
 148:         register struct fstab *fs = getfsspec(file);
 149:         if (fs != NULL)
 150:             fsdir = fs->fs_file;
 151:     }
 152:     if (fsdir != NULL && *fsdir != '\0')
 153:         printf(" (%s)", fsdir);
 154:     printf(":\n");
 155:     sync();
 156:     bread(fd, SBLOCK, (char *)&sblock, SBSIZE);
 157:     if (nflg) {
 158:         if (isdigit(c = getchar()))
 159:             ungetc(c, stdin);
 160:         else while (c != '\n' && c != EOF)
 161:             c = getchar();
 162:     }
 163:     nfiles = sblock.fs_ipg * sblock.fs_ncg;
 164:     for (ino = 0; ino < nfiles; ) {
 165:         iblk = fsbtodb(&sblock, itod(&sblock, ino));
 166:         bread(fd, iblk, (char *)itab, sblock.fs_bsize);
 167:         for (j = 0; j < INOPB(&sblock) && ino < nfiles; j++, ino++) {
 168:             if (ino < ROOTINO)
 169:                 continue;
 170:             acct(&itab[j]);
 171:         }
 172:     }
 173:     close(fd);
 174:     return (0);
 175: }
 176: 
 177: acct(ip)
 178:     register struct dinode *ip;
 179: {
 180:     register struct du *dp;
 181:     struct du **hp;
 182:     long blks, frags, size;
 183:     int n;
 184:     static fino;
 185: 
 186:     if ((ip->di_mode & IFMT) == 0)
 187:         return;
 188:     /*
 189: 	 * By default, take block count in inode.  Otherwise (-h),
 190: 	 * take the size field and estimate the blocks allocated.
 191: 	 * The latter does not account for holes in files.
 192: 	 */
 193:     if (!hflg)
 194:         size = ip->di_blocks / 2;
 195:     else {
 196:         blks = lblkno(&sblock, ip->di_size);
 197:         frags = blks * sblock.fs_frag +
 198:             numfrags(&sblock, dblksize(&sblock, ip, blks));
 199:         size = frags * sblock.fs_fsize / 1024;
 200:     }
 201:     if (cflg) {
 202:         if ((ip->di_mode&IFMT) != IFDIR && (ip->di_mode&IFMT) != IFREG)
 203:             return;
 204:         if (size >= TSIZE) {
 205:             overflow += size;
 206:             size = TSIZE-1;
 207:         }
 208:         sizes[size]++;
 209:         return;
 210:     }
 211:     hp = &duhash[HASH(ip->di_uid)];
 212:     for (dp = *hp; dp; dp = dp->next)
 213:         if (dp->uid == ip->di_uid)
 214:             break;
 215:     if (dp == 0) {
 216:         if (ndu >= NDU)
 217:             return;
 218:         dp = &du[ndu++];
 219:         dp->next = *hp;
 220:         *hp = dp;
 221:         dp->uid = ip->di_uid;
 222:         dp->nfiles = 0;
 223:         dp->blocks = 0;
 224:         dp->blocks30 = 0;
 225:         dp->blocks60 = 0;
 226:         dp->blocks90 = 0;
 227:     }
 228:     dp->blocks += size;
 229: #define DAY (60 * 60 * 24)  /* seconds per day */
 230:     if (now - ip->di_atime > 30 * DAY)
 231:         dp->blocks30 += size;
 232:     if (now - ip->di_atime > 60 * DAY)
 233:         dp->blocks60 += size;
 234:     if (now - ip->di_atime > 90 * DAY)
 235:         dp->blocks90 += size;
 236:     dp->nfiles++;
 237:     while (nflg) {
 238:         register char *np;
 239: 
 240:         if (fino == 0)
 241:             if (scanf("%d", &fino) <= 0)
 242:                 return;
 243:         if (fino > ino)
 244:             return;
 245:         if (fino < ino) {
 246:             while ((n = getchar()) != '\n' && n != EOF)
 247:                 ;
 248:             fino = 0;
 249:             continue;
 250:         }
 251:         if (np = getname(dp->uid))
 252:             printf("%.7s	", np);
 253:         else
 254:             printf("%d	", ip->di_uid);
 255:         while ((n = getchar()) == ' ' || n == '\t')
 256:             ;
 257:         putchar(n);
 258:         while (n != EOF && n != '\n') {
 259:             n = getchar();
 260:             putchar(n);
 261:         }
 262:         fino = 0;
 263:         break;
 264:     }
 265: }
 266: 
 267: bread(fd, bno, buf, cnt)
 268:     unsigned bno;
 269:     char *buf;
 270: {
 271: 
 272:     lseek(fd, (long)bno * DEV_BSIZE, L_SET);
 273:     if (read(fd, buf, cnt) != cnt) {
 274:         fprintf(stderr, "quot: read error at block %u\n", bno);
 275:         exit(1);
 276:     }
 277: }
 278: 
 279: qcmp(p1, p2)
 280:     register struct du *p1, *p2;
 281: {
 282:     char *s1, *s2;
 283: 
 284:     if (p1->blocks > p2->blocks)
 285:         return (-1);
 286:     if (p1->blocks < p2->blocks)
 287:         return (1);
 288:     s1 = getname(p1->uid);
 289:     if (s1 == 0)
 290:         return (0);
 291:     s2 = getname(p2->uid);
 292:     if (s2 == 0)
 293:         return (0);
 294:     return (strcmp(s1, s2));
 295: }
 296: 
 297: report()
 298: {
 299:     register i;
 300:     register struct du *dp;
 301: 
 302:     if (nflg)
 303:         return;
 304:     if (cflg) {
 305:         register long t = 0;
 306: 
 307:         for (i = 0; i < TSIZE - 1; i++)
 308:             if (sizes[i]) {
 309:                 t += i*sizes[i];
 310:                 printf("%d	%d	%D\n", i, sizes[i], t);
 311:             }
 312:         printf("%d	%d	%D\n",
 313:             TSIZE - 1, sizes[TSIZE - 1], overflow + t);
 314:         return;
 315:     }
 316:     qsort(du, ndu, sizeof (du[0]), qcmp);
 317:     for (dp = du; dp < &du[ndu]; dp++) {
 318:         register char *cp;
 319: 
 320:         if (dp->blocks == 0)
 321:             return;
 322:         printf("%5D\t", dp->blocks);
 323:         if (fflg)
 324:             printf("%5D\t", dp->nfiles);
 325:         if (cp = getname(dp->uid))
 326:             printf("%-8.8s", cp);
 327:         else
 328:             printf("#%-8d", dp->uid);
 329:         if (vflg)
 330:             printf("\t%5D\t%5D\t%5D",
 331:                 dp->blocks30, dp->blocks60, dp->blocks90);
 332:         printf("\n");
 333:     }
 334: }
 335: 
 336: /* rest should be done with nameserver or database */
 337: 
 338: #include <pwd.h>
 339: #include <grp.h>
 340: #include <utmp.h>
 341: 
 342: struct  utmp utmp;
 343: #define NMAX    (sizeof (utmp.ut_name))
 344: #define SCPYN(a, b) strncpy(a, b, NMAX)
 345: 
 346: #define NUID    64  /* power of 2 */
 347: #define UIDMASK 0x3f
 348: 
 349: struct ncache {
 350:     int uid;
 351:     char    name[NMAX+1];
 352: } nc[NUID];
 353: char    outrangename[NMAX+1];
 354: int outrangeuid = -1;
 355: 
 356: char *
 357: getname(uid)
 358: {
 359:     register struct passwd *pw;
 360:     struct passwd *getpwent();
 361:     extern int _pw_stayopen;
 362:     register int cp;
 363: 
 364:     _pw_stayopen = 1;
 365:     cp = uid & UIDMASK;
 366:     if (uid >= 0 && nc[cp].uid == uid && nc[cp].name[0])
 367:         return (nc[cp].name);
 368:     pw = getpwuid(uid);
 369:     if (!pw)
 370:         return (0);
 371:     nc[cp].uid = uid;
 372:     SCPYN(nc[cp].name, pw->pw_name);
 373:     return (nc[cp].name);
 374: }

Defined functions

acct defined in line 177; used 4 times
bread defined in line 267; used 2 times
check defined in line 120; used 2 times
getname defined in line 356; used 6 times
main defined in line 55; never used
qcmp defined in line 279; used 1 times
quotall defined in line 95; used 1 times
  • in line 86
report defined in line 297; used 2 times

Defined variables

cflg defined in line 45; used 3 times
du defined in line 33; used 5 times
duhash defined in line 37; used 3 times
fflg defined in line 44; used 2 times
hflg defined in line 47; used 2 times
ino defined in line 50; used 8 times
itab defined in line 22; used 2 times
nc defined in line 352; used 6 times
ndu defined in line 34; used 5 times
nflg defined in line 43; used 4 times
now defined in line 48; used 4 times
outrangename defined in line 353; never used
outrangeuid defined in line 354; never used
overflow defined in line 41; used 3 times
sccsid defined in line 2; never used
sizes defined in line 40; used 6 times
utmp defined in line 342; used 1 times
vflg defined in line 46; used 2 times

Defined struct's

du defined in line 24; used 14 times
ncache defined in line 349; never used

Defined macros

DAY defined in line 229; used 3 times
DUHASH defined in line 35; used 3 times
HASH defined in line 36; used 1 times
ISIZ defined in line 16; never used
NDU defined in line 32; used 2 times
NMAX defined in line 343; used 3 times
NUID defined in line 346; used 1 times
SCPYN defined in line 344; used 1 times
TSIZE defined in line 39; used 7 times
UIDMASK defined in line 347; used 1 times
sblock defined in line 21; used 12 times
Last modified: 1985-09-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1761
Valid CSS Valid XHTML 1.0 Strict