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: #ifndef lint 8: char copyright[] = 9: "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10: All rights reserved.\n"; 11: #endif not lint 12: 13: #ifndef lint 14: static char sccsid[] = "@(#)repquota.c 5.4 (Berkeley) 3/5/86"; 15: #endif not lint 16: 17: /* 18: * Quota report 19: */ 20: #include <stdio.h> 21: #include <errno.h> 22: #include <sys/param.h> 23: #include <sys/quota.h> 24: #include <sys/stat.h> 25: #include <fstab.h> 26: #include <pwd.h> 27: 28: #define LOGINNAMESIZE 8 29: struct fileusage { 30: struct fileusage *fu_next; 31: struct dqblk fu_dqblk; 32: u_short fu_uid; 33: char fu_name[LOGINNAMESIZE + 1]; 34: }; 35: #define FUHASH 997 36: struct fileusage *fuhead[FUHASH]; 37: struct fileusage *lookup(); 38: struct fileusage *adduid(); 39: int highuid; 40: 41: long done; 42: struct passwd *getpwent(); 43: 44: int vflag; /* verbose */ 45: int aflag; /* all file systems */ 46: 47: char *qfname = "quotas"; 48: struct dqblk zerodqblk; 49: 50: main(argc, argv) 51: int argc; 52: char **argv; 53: { 54: register struct fstab *fs; 55: register struct passwd *pw; 56: register struct fileusage *fup; 57: char quotafile[MAXPATHLEN]; 58: int i, errs = 0; 59: 60: again: 61: argc--, argv++; 62: if (argc > 0 && strcmp(*argv, "-v") == 0) { 63: vflag++; 64: goto again; 65: } 66: if (argc > 0 && strcmp(*argv, "-a") == 0) { 67: aflag++; 68: goto again; 69: } 70: if (argc <= 0 && !aflag) { 71: fprintf(stderr, "Usage:\n\t%s\n\t%s\n", 72: "repquota [-v] -a", 73: "repquota [-v] filesys ..."); 74: exit(1); 75: } 76: setpwent(); 77: while ((pw = getpwent()) != 0) { 78: fup = lookup(pw->pw_uid); 79: if (fup == 0) { 80: fup = adduid(pw->pw_uid); 81: strncpy(fup->fu_name, pw->pw_name, sizeof(fup->fu_name)); 82: } 83: } 84: endpwent(); 85: setfsent(); 86: while ((fs = getfsent()) != NULL) { 87: if (aflag && 88: (fs->fs_type == 0 || strcmp(fs->fs_type, "rq") != 0)) 89: continue; 90: if (!aflag && 91: !(oneof(fs->fs_file, argv, argc) || 92: oneof(fs->fs_spec, argv, argc))) 93: continue; 94: (void) sprintf(quotafile, "%s/%s", fs->fs_file, qfname); 95: errs += repquota(fs->fs_spec, fs->fs_file, quotafile); 96: } 97: endfsent(); 98: for (i = 0; i < argc; i++) 99: if ((done & (1 << i)) == 0) 100: fprintf(stderr, "%s not found in /etc/fstab\n", 101: argv[i]); 102: exit(errs); 103: } 104: 105: repquota(fsdev, fsfile, qffile) 106: char *fsdev; 107: char *fsfile; 108: char *qffile; 109: { 110: register struct fileusage *fup; 111: FILE *qf; 112: u_short uid; 113: struct dqblk dqbuf; 114: struct stat statb; 115: static int warned = 0; 116: extern int errno; 117: 118: if (vflag) 119: fprintf(stdout, "*** Quota report for %s (%s)\n", fsdev, fsfile); 120: qf = fopen(qffile, "r"); 121: if (qf == NULL) { 122: perror(qffile); 123: return (1); 124: } 125: if (fstat(fileno(qf), &statb) < 0) { 126: perror(qffile); 127: fclose(qf); 128: return (1); 129: } 130: if (quota(Q_SYNC, 0, statb.st_dev, 0) < 0 && 131: errno == EINVAL && !warned && vflag) { 132: warned++; 133: fprintf(stdout, 134: "*** Warning: Quotas are not compiled into this kernel\n"); 135: } 136: for (uid = 0; ; uid++) { 137: fread(&dqbuf, sizeof(struct dqblk), 1, qf); 138: if (feof(qf)) 139: break; 140: fup = lookup(uid); 141: if ((fup == 0 || fup->fu_name[0] == 0) && 142: dqbuf.dqb_curinodes == 0 && dqbuf.dqb_curblocks == 0) 143: continue; 144: if (fup == 0) 145: fup = adduid(uid); 146: fup->fu_dqblk = dqbuf; 147: } 148: printf(" Block limits File limits\n"); 149: printf("User used soft hard warn used soft hard warn\n"); 150: for (uid = 0; uid <= highuid; uid++) { 151: fup = lookup(uid); 152: if (fup == 0) 153: continue; 154: if (fup->fu_dqblk.dqb_curinodes == 0 && 155: fup->fu_dqblk.dqb_curblocks == 0) 156: continue; 157: if (fup->fu_name[0] != '\0') 158: printf("%-10s", fup->fu_name); 159: else 160: printf("#%-9d", uid); 161: printf("%c%c%8d%8d%8d %5d %5d %5d %5d %5d\n", 162: fup->fu_dqblk.dqb_bsoftlimit && 163: fup->fu_dqblk.dqb_curblocks >= 164: fup->fu_dqblk.dqb_bsoftlimit ? '+' : '-', 165: fup->fu_dqblk.dqb_isoftlimit && 166: fup->fu_dqblk.dqb_curinodes >= 167: fup->fu_dqblk.dqb_isoftlimit ? '+' : '-', 168: dbtob(fup->fu_dqblk.dqb_curblocks) / 1024, 169: dbtob(fup->fu_dqblk.dqb_bsoftlimit) / 1024, 170: dbtob(fup->fu_dqblk.dqb_bhardlimit) / 1024, 171: fup->fu_dqblk.dqb_bwarn, 172: fup->fu_dqblk.dqb_curinodes, 173: fup->fu_dqblk.dqb_isoftlimit, 174: fup->fu_dqblk.dqb_ihardlimit, 175: fup->fu_dqblk.dqb_iwarn); 176: fup->fu_dqblk = zerodqblk; 177: } 178: fclose(qf); 179: return (0); 180: } 181: 182: oneof(target, list, n) 183: char *target, *list[]; 184: register int n; 185: { 186: register int i; 187: 188: for (i = 0; i < n; i++) 189: if (strcmp(target, list[i]) == 0) { 190: done |= 1 << i; 191: return (1); 192: } 193: return (0); 194: } 195: 196: struct fileusage * 197: lookup(uid) 198: u_short uid; 199: { 200: register struct fileusage *fup; 201: 202: for (fup = fuhead[uid % FUHASH]; fup != 0; fup = fup->fu_next) 203: if (fup->fu_uid == uid) 204: return (fup); 205: return ((struct fileusage *)0); 206: } 207: 208: struct fileusage * 209: adduid(uid) 210: u_short uid; 211: { 212: struct fileusage *fup, **fhp; 213: extern char *calloc(); 214: 215: fup = lookup(uid); 216: if (fup != 0) 217: return (fup); 218: fup = (struct fileusage *)calloc(1, sizeof(struct fileusage)); 219: if (fup == 0) { 220: fprintf(stderr, "out of memory for fileusage structures\n"); 221: exit(1); 222: } 223: fhp = &fuhead[uid % FUHASH]; 224: fup->fu_next = *fhp; 225: *fhp = fup; 226: fup->fu_uid = uid; 227: if (uid > highuid) 228: highuid = uid; 229: return (fup); 230: }