1 #ifndef lint 2 static char sccsid[] = "@(#)quota.c 4.4 (Berkeley, from Melbourne) 06/21/83"; 3 #endif 4 5 /* 6 * Disk quota reporting program. 7 */ 8 #include <stdio.h> 9 #include <fstab.h> 10 #include <ctype.h> 11 #include <pwd.h> 12 13 #include <sys/param.h> 14 #include <sys/quota.h> 15 #include <sys/file.h> 16 #include <sys/stat.h> 17 18 int qflag; 19 int vflag; 20 int done; 21 int morethanone; 22 char *qfname = "quotas"; 23 24 main(argc, argv) 25 char *argv[]; 26 { 27 register char *cp; 28 29 argc--,argv++; 30 while (argc > 0) { 31 if (argv[0][0] == '-') 32 for (cp = &argv[0][1]; *cp; cp++) switch (*cp) { 33 34 case 'v': 35 vflag++; 36 break; 37 38 case 'q': 39 qflag++; 40 break; 41 42 default: 43 fprintf(stderr, "quota: %c: unknown option\n", 44 *cp); 45 exit(1); 46 } 47 else 48 break; 49 argc--, argv++; 50 } 51 morethanone = argc > 1; 52 if (argc == 0) { 53 showuid(getuid()); 54 exit(0); 55 } 56 for (; argc > 0; argc--, argv++) { 57 if (alldigits(*argv)) 58 showuid(atoi(*argv)); 59 else 60 showname(*argv); 61 } 62 } 63 64 showuid(uid) 65 int uid; 66 { 67 struct passwd *pwd = getpwuid(uid); 68 69 if (pwd == NULL) 70 showquotas(uid, "(no account)"); 71 else 72 showquotas(uid, pwd->pw_name); 73 } 74 75 showname(name) 76 char *name; 77 { 78 struct passwd *pwd = getpwnam(name); 79 80 if (pwd == NULL) { 81 fprintf(stderr, "quota: %s: unknown user\n", name); 82 return; 83 } 84 showquotas(pwd->pw_uid, name); 85 } 86 87 showquotas(uid, name) 88 int uid; 89 char *name; 90 { 91 register char c, *p; 92 register struct fstab *fs; 93 int myuid; 94 95 myuid = getuid(); 96 if (uid != myuid && myuid != 0) { 97 printf("quota: %s (uid %d): permission denied\n", name, uid); 98 return; 99 } 100 done = 0; 101 setfsent(); 102 while (fs = getfsent()) { 103 register char *msgi = (char *)0, *msgb = (char *)0; 104 register enab = 1; 105 dev_t fsdev; 106 struct stat statb; 107 struct dqblk dqblk; 108 char qfilename[MAXPATHLEN + 1], iwarn[8], dwarn[8]; 109 110 if (stat(fs->fs_spec, &statb) < 0) 111 continue; 112 fsdev = statb.st_rdev; 113 (void) sprintf(qfilename, "%s/%s", fs->fs_file, qfname); 114 if (stat(qfilename, &statb) < 0 || statb.st_dev != fsdev) 115 continue; 116 if (quota(Q_GETDLIM, uid, fsdev, &dqblk) != 0) { 117 register fd = open(qfilename, O_RDONLY); 118 119 if (fd < 0) 120 continue; 121 lseek(fd, (long)(uid * sizeof (dqblk)), L_SET); 122 if (read(fd, &dqblk, sizeof dqblk) != sizeof (dqblk)) { 123 close(fd); 124 continue; 125 } 126 close(fd); 127 if (dqblk.dqb_isoftlimit == 0 && 128 dqblk.dqb_bsoftlimit == 0) 129 continue; 130 enab = 0; 131 } 132 if (dqblk.dqb_ihardlimit && 133 dqblk.dqb_curinodes >= dqblk.dqb_ihardlimit) 134 msgi = "File count limit reached on %s"; 135 else if (enab && dqblk.dqb_iwarn == 0) 136 msgi = "Out of inode warnings on %s"; 137 else if (dqblk.dqb_isoftlimit && 138 dqblk.dqb_curinodes >= dqblk.dqb_isoftlimit) 139 msgi = "Too many files on %s"; 140 if (dqblk.dqb_bhardlimit && 141 dqblk.dqb_curblocks >= dqblk.dqb_bhardlimit) 142 msgb = "Block limit reached on %s"; 143 else if (enab && dqblk.dqb_bwarn == 0) 144 msgb = "Out of block warnings on %s"; 145 else if (dqblk.dqb_bsoftlimit && 146 dqblk.dqb_curblocks >= dqblk.dqb_bsoftlimit) 147 msgb = "Over disc quota on %s"; 148 if (dqblk.dqb_iwarn < MAX_IQ_WARN) 149 sprintf(iwarn, "%d", dqblk.dqb_iwarn); 150 else 151 iwarn[0] = '\0'; 152 if (dqblk.dqb_bwarn < MAX_DQ_WARN) 153 sprintf(dwarn, "%d", dqblk.dqb_bwarn); 154 else 155 dwarn[0] = '\0'; 156 if (qflag) { 157 if (msgi != (char *)0 || msgb != (char *)0) 158 heading(uid, name); 159 if (msgi != (char *)0) 160 xprintf(msgi, fs->fs_file); 161 if (msgb != (char *)0) 162 xprintf(msgb, fs->fs_file); 163 continue; 164 } 165 if (vflag || dqblk.dqb_curblocks || dqblk.dqb_curinodes) { 166 heading(uid, name); 167 printf("%10s%8d%c%7d%8d%8s%8d%c%7d%8d%8s\n" 168 , fs->fs_file 169 , (dqblk.dqb_curblocks / btodb(1024)) 170 , (msgb == (char *)0) ? ' ' : '*' 171 , (dqblk.dqb_bsoftlimit / btodb(1024)) 172 , (dqblk.dqb_bhardlimit / btodb(1024)) 173 , dwarn 174 , dqblk.dqb_curinodes 175 , (msgi == (char *)0) ? ' ' : '*' 176 , dqblk.dqb_isoftlimit 177 , dqblk.dqb_ihardlimit 178 , iwarn 179 ); 180 } 181 } 182 endfsent(); 183 if (!done && !qflag) { 184 if (morethanone) 185 putchar('\n'); 186 xprintf("Disc quotas for %s (uid %d):", name, uid); 187 xprintf("none."); 188 } 189 xprintf(0); 190 } 191 192 heading(uid, name) 193 int uid; 194 char *name; 195 { 196 197 if (done++) 198 return; 199 xprintf(0); 200 if (qflag) { 201 if (!morethanone) 202 return; 203 xprintf("User %s (uid %d):", name, uid); 204 xprintf(0); 205 return; 206 } 207 putchar('\n'); 208 xprintf("Disc quotas for %s (uid %d):", name, uid); 209 xprintf(0); 210 printf("%10s%8s %7s%8s%8s%8s %7s%8s%8s\n" 211 , "Filsys" 212 , "current" 213 , "quota" 214 , "limit" 215 , "#warns" 216 , "files" 217 , "quota" 218 , "limit" 219 , "#warns" 220 ); 221 } 222 223 xprintf(fmt, arg1, arg2, arg3, arg4, arg5, arg6) 224 char *fmt; 225 { 226 char buf[100]; 227 static int column; 228 229 if (fmt == 0 && column || column >= 40) { 230 putchar('\n'); 231 column = 0; 232 } 233 if (fmt == 0) 234 return; 235 sprintf(buf, fmt, arg1, arg2, arg3, arg4, arg5, arg6); 236 if (column != 0 && strlen(buf) < 39) 237 while (column++ < 40) 238 putchar(' '); 239 else if (column) { 240 putchar('\n'); 241 column = 0; 242 } 243 printf("%s", buf); 244 column += strlen(buf); 245 } 246 247 alldigits(s) 248 register char *s; 249 { 250 register c; 251 252 c = *s++; 253 do { 254 if (!isdigit(c)) 255 return (0); 256 } while (c = *s++); 257 return (1); 258 } 259