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