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