112710Smckusick #ifndef lint 2*12721Smckusick static char sccsid[] = "@(#)quota.c 4.3 (Berkeley, from Melbourne) 05/25/83"; 312710Smckusick #endif 412710Smckusick 512710Smckusick /* 612710Smckusick * Disk quota reporting program. 712710Smckusick */ 812710Smckusick #include <stdio.h> 912710Smckusick #include <fstab.h> 1012710Smckusick #include <ctype.h> 1112710Smckusick #include <pwd.h> 1212710Smckusick 1312710Smckusick #include <sys/param.h> 1412710Smckusick #include <sys/quota.h> 1512710Smckusick #include <sys/file.h> 1612710Smckusick #include <sys/stat.h> 1712710Smckusick 1812710Smckusick int qflag; 1912710Smckusick int vflag; 2012710Smckusick int done; 2112710Smckusick int morethanone; 2212711Smckusick char *qfname = "quotas"; 2312710Smckusick 2412710Smckusick main(argc, argv) 2512710Smckusick char *argv[]; 2612710Smckusick { 2712710Smckusick register char *cp; 2812710Smckusick 2912710Smckusick argc--,argv++; 3012710Smckusick while (argc > 0) { 3112710Smckusick if (argv[0][0] == '-') 3212710Smckusick for (cp = &argv[0][1]; *cp; cp++) switch (*cp) { 3312710Smckusick 3412710Smckusick case 'v': 3512710Smckusick vflag++; 3612710Smckusick break; 3712710Smckusick 3812710Smckusick case 'q': 3912710Smckusick qflag++; 4012710Smckusick break; 4112710Smckusick 4212710Smckusick default: 4312710Smckusick fprintf(stderr, "quota: %c: unknown option\n", 4412710Smckusick *cp); 4512710Smckusick exit(1); 4612710Smckusick } 4712710Smckusick else 4812710Smckusick break; 4912710Smckusick argc--, argv++; 5012710Smckusick } 5112710Smckusick morethanone = argc > 1; 5212710Smckusick if (argc == 0) { 5312710Smckusick showuid(getuid()); 5412710Smckusick exit(0); 5512710Smckusick } 5612710Smckusick for (; argc > 0; argc--, argv++) { 5712710Smckusick if (alldigits(*argv)) 5812710Smckusick showuid(atoi(*argv)); 5912710Smckusick else 6012710Smckusick showname(*argv); 6112710Smckusick } 6212710Smckusick } 6312710Smckusick 6412710Smckusick showuid(uid) 6512710Smckusick int uid; 6612710Smckusick { 6712710Smckusick struct passwd *pwd = getpwuid(uid); 6812710Smckusick 6912710Smckusick if (pwd == NULL) 7012710Smckusick showquotas(uid, "(no account)"); 7112710Smckusick else 7212710Smckusick showquotas(uid, pwd->pw_name); 7312710Smckusick } 7412710Smckusick 7512710Smckusick showname(name) 7612710Smckusick char *name; 7712710Smckusick { 7812710Smckusick struct passwd *pwd = getpwnam(name); 7912710Smckusick 8012710Smckusick if (pwd == NULL) { 8112710Smckusick fprintf(stderr, "quota: %s: unknown user\n", name); 8212710Smckusick return; 8312710Smckusick } 8412710Smckusick showquotas(pwd->pw_uid, name); 8512710Smckusick } 8612710Smckusick 8712710Smckusick showquotas(uid, name) 8812710Smckusick int uid; 8912710Smckusick char *name; 9012710Smckusick { 9112710Smckusick register char c, *p; 9212710Smckusick register struct fstab *fs; 9312710Smckusick int myuid; 9412710Smckusick 9512710Smckusick myuid = getuid(); 9612710Smckusick if (uid != myuid && myuid != 0) { 9712710Smckusick printf("quota: %s (uid %d): permission denied\n", name, uid); 9812710Smckusick return; 9912710Smckusick } 10012710Smckusick done = 0; 10112710Smckusick setfsent(); 10212710Smckusick while (fs = getfsent()) { 10312710Smckusick register char *msgi = (char *)0, *msgb = (char *)0; 10412710Smckusick register enab = 1; 10512710Smckusick dev_t fsdev; 10612710Smckusick struct stat statb; 10712710Smckusick struct dqblk dqblk; 10812711Smckusick char qfilename[MAXPATHLEN + 1], iwarn[8], dwarn[8]; 10912710Smckusick 11012710Smckusick if (stat(fs->fs_spec, &statb) < 0) 11112710Smckusick continue; 11212710Smckusick fsdev = statb.st_rdev; 11312711Smckusick (void) sprintf(qfilename, "%s/%s", fs->fs_file, qfname); 11412711Smckusick if (stat(qfilename, &statb) < 0 || statb.st_dev != fsdev) 11512710Smckusick continue; 11612710Smckusick if (quota(Q_GETDLIM, uid, fsdev, &dqblk) != 0) { 117*12721Smckusick register fd = open(qfilename, O_RDONLY); 11812710Smckusick 11912710Smckusick if (fd < 0) 12012710Smckusick continue; 121*12721Smckusick lseek(fd, (long)(uid * sizeof (dqblk)), L_SET); 12212710Smckusick if (read(fd, &dqblk, sizeof dqblk) != sizeof (dqblk)) { 12312710Smckusick close(fd); 12412710Smckusick continue; 12512710Smckusick } 12612710Smckusick close(fd); 12712710Smckusick if (dqblk.dqb_isoftlimit == 0 && 12812710Smckusick dqblk.dqb_bsoftlimit == 0) 12912710Smckusick continue; 13012710Smckusick enab = 0; 13112710Smckusick } 13212710Smckusick if (dqblk.dqb_ihardlimit && 13312710Smckusick dqblk.dqb_curinodes >= dqblk.dqb_ihardlimit) 13412710Smckusick msgi = "File count limit reached on %s"; 13512710Smckusick else if (enab && dqblk.dqb_iwarn == 0) 13612710Smckusick msgi = "Out of inode warnings on %s"; 13712710Smckusick else if (dqblk.dqb_isoftlimit && 13812710Smckusick dqblk.dqb_curinodes >= dqblk.dqb_isoftlimit) 13912710Smckusick msgi = "Too many files on %s"; 14012710Smckusick if (dqblk.dqb_bhardlimit && 14112710Smckusick dqblk.dqb_curblocks >= dqblk.dqb_bhardlimit) 14212710Smckusick msgb = "Block limit reached on %s"; 14312710Smckusick else if (enab && dqblk.dqb_bwarn == 0) 14412710Smckusick msgb = "Out of block warnings on %s"; 14512710Smckusick else if (dqblk.dqb_bsoftlimit && 14612710Smckusick dqblk.dqb_curblocks >= dqblk.dqb_bsoftlimit) 14712710Smckusick msgb = "Over disc quota on %s"; 14812710Smckusick if (dqblk.dqb_iwarn < MAX_IQ_WARN) 14912710Smckusick sprintf(iwarn, "%d", dqblk.dqb_iwarn); 15012710Smckusick else 15112710Smckusick iwarn[0] = '\0'; 15212710Smckusick if (dqblk.dqb_bwarn < MAX_DQ_WARN) 15312710Smckusick sprintf(dwarn, "%d", dqblk.dqb_bwarn); 15412710Smckusick else 15512710Smckusick dwarn[0] = '\0'; 15612710Smckusick if (qflag) { 15712710Smckusick if (msgi != (char *)0 || msgb != (char *)0) 15812710Smckusick heading(uid, name); 15912710Smckusick if (msgi != (char *)0) 16012710Smckusick xprintf(msgi, fs->fs_file); 16112710Smckusick if (msgb != (char *)0) 16212710Smckusick xprintf(msgb, fs->fs_file); 16312710Smckusick continue; 16412710Smckusick } 16512710Smckusick if (vflag || dqblk.dqb_curblocks || dqblk.dqb_curinodes) { 16612710Smckusick heading(uid, name); 16712710Smckusick printf("%8s%8d%c%7d%8d%8s%8d%c%7d%8d%8s\n" 16812710Smckusick , fs->fs_file 169*12721Smckusick , (dqblk.dqb_curblocks / btodb(1024)) 17012710Smckusick , (msgb == (char *)0) ? ' ' : '*' 171*12721Smckusick , (dqblk.dqb_bsoftlimit / btodb(1024)) 172*12721Smckusick , (dqblk.dqb_bhardlimit / btodb(1024)) 17312710Smckusick , dwarn 17412710Smckusick , dqblk.dqb_curinodes 17512710Smckusick , (msgi == (char *)0) ? ' ' : '*' 17612710Smckusick , dqblk.dqb_isoftlimit 177*12721Smckusick , dqblk.dqb_ihardlimit 17812710Smckusick , iwarn 17912710Smckusick ); 18012710Smckusick } 18112710Smckusick } 18212710Smckusick endfsent(); 18312710Smckusick if (!done && !qflag) { 18412710Smckusick if (morethanone) 18512710Smckusick putchar('\n'); 18612710Smckusick xprintf("Disc quotas for %s (uid %d):", name, uid); 18712710Smckusick xprintf("none."); 18812710Smckusick } 18912710Smckusick xprintf(0); 19012710Smckusick } 19112710Smckusick 19212710Smckusick heading(uid, name) 19312710Smckusick int uid; 19412710Smckusick char *name; 19512710Smckusick { 19612710Smckusick 19712710Smckusick if (done++) 19812710Smckusick return; 19912710Smckusick xprintf(0); 20012710Smckusick if (qflag) { 20112710Smckusick if (!morethanone) 20212710Smckusick return; 20312710Smckusick xprintf("User %s (uid %d):", name, uid); 20412710Smckusick xprintf(0); 20512710Smckusick return; 20612710Smckusick } 20712710Smckusick putchar('\n'); 20812710Smckusick xprintf("Disc quotas for %s (uid %d):", name, uid); 20912710Smckusick xprintf(0); 21012710Smckusick printf("%8s%8s %7s%8s%8s%8s %7s%8s%8s\n" 21112710Smckusick , "Filsys" 21212710Smckusick , "current" 21312710Smckusick , "quota" 21412710Smckusick , "limit" 21512710Smckusick , "#warns" 21612710Smckusick , "files" 21712710Smckusick , "quota" 21812710Smckusick , "limit" 21912710Smckusick , "#warns" 22012710Smckusick ); 22112710Smckusick } 22212710Smckusick 22312710Smckusick xprintf(fmt, arg1, arg2, arg3, arg4, arg5, arg6) 22412710Smckusick char *fmt; 22512710Smckusick { 22612710Smckusick char buf[100]; 22712710Smckusick static int column; 22812710Smckusick 22912710Smckusick if (fmt == 0 && column || column >= 40) { 23012710Smckusick putchar('\n'); 23112710Smckusick column = 0; 23212710Smckusick } 23312710Smckusick if (fmt == 0) 23412710Smckusick return; 23512710Smckusick sprintf(buf, fmt, arg1, arg2, arg3, arg4, arg5, arg6); 23612710Smckusick if (column != 0 && strlen(buf) < 39) 23712710Smckusick while (column++ < 40) 23812710Smckusick putchar(' '); 23912710Smckusick else if (column) { 24012710Smckusick putchar('\n'); 24112710Smckusick column = 0; 24212710Smckusick } 24312710Smckusick printf("%s", buf); 24412710Smckusick column += strlen(buf); 24512710Smckusick } 24612710Smckusick 24712710Smckusick alldigits(s) 24812710Smckusick register char *s; 24912710Smckusick { 25012710Smckusick register c; 25112710Smckusick 25212710Smckusick c = *s++; 25312710Smckusick do { 25412710Smckusick if (!isdigit(c)) 25512710Smckusick return (0); 25612710Smckusick } while (c = *s++); 25712710Smckusick return (1); 25812710Smckusick } 259