1*21520Smckusick /* 2*21520Smckusick * Copyright (c) 1980 Regents of the University of California. 3*21520Smckusick * All rights reserved. The Berkeley software License Agreement 4*21520Smckusick * specifies the terms and conditions for redistribution. 5*21520Smckusick */ 6*21520Smckusick 712710Smckusick #ifndef lint 8*21520Smckusick char copyright[] = 9*21520Smckusick "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 10*21520Smckusick All rights reserved.\n"; 11*21520Smckusick #endif not lint 1212710Smckusick 13*21520Smckusick #ifndef lint 14*21520Smckusick static char sccsid[] = "@(#)quota.c 5.1 (Berkeley) 05/30/85"; 15*21520Smckusick #endif not lint 16*21520Smckusick 1712710Smckusick /* 1812710Smckusick * Disk quota reporting program. 1912710Smckusick */ 2012710Smckusick #include <stdio.h> 2112710Smckusick #include <fstab.h> 2212710Smckusick #include <ctype.h> 2312710Smckusick #include <pwd.h> 2421392Smckusick #include <errno.h> 2512710Smckusick 2612710Smckusick #include <sys/param.h> 2712710Smckusick #include <sys/quota.h> 2812710Smckusick #include <sys/file.h> 2912710Smckusick #include <sys/stat.h> 3012710Smckusick 3112710Smckusick int qflag; 3212710Smckusick int vflag; 3312710Smckusick int done; 3412710Smckusick int morethanone; 3512711Smckusick char *qfname = "quotas"; 3612710Smckusick 3712710Smckusick main(argc, argv) 3812710Smckusick char *argv[]; 3912710Smckusick { 4012710Smckusick register char *cp; 4121392Smckusick extern int errno; 4212710Smckusick 4321392Smckusick if (quota(Q_SYNC, 0, 0, 0) < 0 && errno == EINVAL) { 4421392Smckusick fprintf(stderr, "There are no quotas on this system\n"); 4521392Smckusick exit(0); 4621392Smckusick } 4712710Smckusick argc--,argv++; 4812710Smckusick while (argc > 0) { 4912710Smckusick if (argv[0][0] == '-') 5012710Smckusick for (cp = &argv[0][1]; *cp; cp++) switch (*cp) { 5112710Smckusick 5212710Smckusick case 'v': 5312710Smckusick vflag++; 5412710Smckusick break; 5512710Smckusick 5612710Smckusick case 'q': 5712710Smckusick qflag++; 5812710Smckusick break; 5912710Smckusick 6012710Smckusick default: 6112710Smckusick fprintf(stderr, "quota: %c: unknown option\n", 6212710Smckusick *cp); 6312710Smckusick exit(1); 6412710Smckusick } 6512710Smckusick else 6612710Smckusick break; 6712710Smckusick argc--, argv++; 6812710Smckusick } 6912710Smckusick morethanone = argc > 1; 7012710Smckusick if (argc == 0) { 7112710Smckusick showuid(getuid()); 7212710Smckusick exit(0); 7312710Smckusick } 7412710Smckusick for (; argc > 0; argc--, argv++) { 7512710Smckusick if (alldigits(*argv)) 7612710Smckusick showuid(atoi(*argv)); 7712710Smckusick else 7812710Smckusick showname(*argv); 7912710Smckusick } 8012710Smckusick } 8112710Smckusick 8212710Smckusick showuid(uid) 8312710Smckusick int uid; 8412710Smckusick { 8512710Smckusick struct passwd *pwd = getpwuid(uid); 8612710Smckusick 8712710Smckusick if (pwd == NULL) 8812710Smckusick showquotas(uid, "(no account)"); 8912710Smckusick else 9012710Smckusick showquotas(uid, pwd->pw_name); 9112710Smckusick } 9212710Smckusick 9312710Smckusick showname(name) 9412710Smckusick char *name; 9512710Smckusick { 9612710Smckusick struct passwd *pwd = getpwnam(name); 9712710Smckusick 9812710Smckusick if (pwd == NULL) { 9912710Smckusick fprintf(stderr, "quota: %s: unknown user\n", name); 10012710Smckusick return; 10112710Smckusick } 10212710Smckusick showquotas(pwd->pw_uid, name); 10312710Smckusick } 10412710Smckusick 10512710Smckusick showquotas(uid, name) 10612710Smckusick int uid; 10712710Smckusick char *name; 10812710Smckusick { 10912710Smckusick register char c, *p; 11012710Smckusick register struct fstab *fs; 11121392Smckusick register char *msgi = (char *)0, *msgb = (char *)0; 11221392Smckusick register enab = 1; 11321392Smckusick dev_t fsdev; 11421392Smckusick struct stat statb; 11521392Smckusick struct dqblk dqblk; 11621392Smckusick int myuid, fd; 11721392Smckusick char qfilename[MAXPATHLEN + 1], iwarn[8], dwarn[8]; 11812710Smckusick 11912710Smckusick myuid = getuid(); 12012710Smckusick if (uid != myuid && myuid != 0) { 12112710Smckusick printf("quota: %s (uid %d): permission denied\n", name, uid); 12212710Smckusick return; 12312710Smckusick } 12412710Smckusick done = 0; 12512710Smckusick setfsent(); 12612710Smckusick while (fs = getfsent()) { 12712710Smckusick if (stat(fs->fs_spec, &statb) < 0) 12812710Smckusick continue; 12912710Smckusick fsdev = statb.st_rdev; 13012711Smckusick (void) sprintf(qfilename, "%s/%s", fs->fs_file, qfname); 13112711Smckusick if (stat(qfilename, &statb) < 0 || statb.st_dev != fsdev) 13212710Smckusick continue; 13312710Smckusick if (quota(Q_GETDLIM, uid, fsdev, &dqblk) != 0) { 13421392Smckusick fd = open(qfilename, O_RDONLY); 13512710Smckusick if (fd < 0) 13612710Smckusick continue; 13712721Smckusick lseek(fd, (long)(uid * sizeof (dqblk)), L_SET); 13812710Smckusick if (read(fd, &dqblk, sizeof dqblk) != sizeof (dqblk)) { 13912710Smckusick close(fd); 14012710Smckusick continue; 14112710Smckusick } 14212710Smckusick close(fd); 14312710Smckusick if (dqblk.dqb_isoftlimit == 0 && 14412710Smckusick dqblk.dqb_bsoftlimit == 0) 14512710Smckusick continue; 14612710Smckusick enab = 0; 14712710Smckusick } 14812710Smckusick if (dqblk.dqb_ihardlimit && 14912710Smckusick dqblk.dqb_curinodes >= dqblk.dqb_ihardlimit) 15012710Smckusick msgi = "File count limit reached on %s"; 15112710Smckusick else if (enab && dqblk.dqb_iwarn == 0) 15212710Smckusick msgi = "Out of inode warnings on %s"; 15312710Smckusick else if (dqblk.dqb_isoftlimit && 15412710Smckusick dqblk.dqb_curinodes >= dqblk.dqb_isoftlimit) 15512710Smckusick msgi = "Too many files on %s"; 15612710Smckusick if (dqblk.dqb_bhardlimit && 15712710Smckusick dqblk.dqb_curblocks >= dqblk.dqb_bhardlimit) 15812710Smckusick msgb = "Block limit reached on %s"; 15912710Smckusick else if (enab && dqblk.dqb_bwarn == 0) 16012710Smckusick msgb = "Out of block warnings on %s"; 16112710Smckusick else if (dqblk.dqb_bsoftlimit && 16212710Smckusick dqblk.dqb_curblocks >= dqblk.dqb_bsoftlimit) 16312710Smckusick msgb = "Over disc quota on %s"; 16412710Smckusick if (dqblk.dqb_iwarn < MAX_IQ_WARN) 16512710Smckusick sprintf(iwarn, "%d", dqblk.dqb_iwarn); 16612710Smckusick else 16712710Smckusick iwarn[0] = '\0'; 16812710Smckusick if (dqblk.dqb_bwarn < MAX_DQ_WARN) 16912710Smckusick sprintf(dwarn, "%d", dqblk.dqb_bwarn); 17012710Smckusick else 17112710Smckusick dwarn[0] = '\0'; 17212710Smckusick if (qflag) { 17312710Smckusick if (msgi != (char *)0 || msgb != (char *)0) 17412710Smckusick heading(uid, name); 17512710Smckusick if (msgi != (char *)0) 17612710Smckusick xprintf(msgi, fs->fs_file); 17712710Smckusick if (msgb != (char *)0) 17812710Smckusick xprintf(msgb, fs->fs_file); 17912710Smckusick continue; 18012710Smckusick } 18112710Smckusick if (vflag || dqblk.dqb_curblocks || dqblk.dqb_curinodes) { 18212710Smckusick heading(uid, name); 18313222Ssam printf("%10s%8d%c%7d%8d%8s%8d%c%7d%8d%8s\n" 18412710Smckusick , fs->fs_file 18512721Smckusick , (dqblk.dqb_curblocks / btodb(1024)) 18612710Smckusick , (msgb == (char *)0) ? ' ' : '*' 18712721Smckusick , (dqblk.dqb_bsoftlimit / btodb(1024)) 18812721Smckusick , (dqblk.dqb_bhardlimit / btodb(1024)) 18912710Smckusick , dwarn 19012710Smckusick , dqblk.dqb_curinodes 19112710Smckusick , (msgi == (char *)0) ? ' ' : '*' 19212710Smckusick , dqblk.dqb_isoftlimit 19312721Smckusick , dqblk.dqb_ihardlimit 19412710Smckusick , iwarn 19512710Smckusick ); 19612710Smckusick } 19712710Smckusick } 19812710Smckusick endfsent(); 19912710Smckusick if (!done && !qflag) { 20012710Smckusick if (morethanone) 20112710Smckusick putchar('\n'); 20212710Smckusick xprintf("Disc quotas for %s (uid %d):", name, uid); 20312710Smckusick xprintf("none."); 20412710Smckusick } 20512710Smckusick xprintf(0); 20612710Smckusick } 20712710Smckusick 20812710Smckusick heading(uid, name) 20912710Smckusick int uid; 21012710Smckusick char *name; 21112710Smckusick { 21212710Smckusick 21312710Smckusick if (done++) 21412710Smckusick return; 21512710Smckusick xprintf(0); 21612710Smckusick if (qflag) { 21712710Smckusick if (!morethanone) 21812710Smckusick return; 21912710Smckusick xprintf("User %s (uid %d):", name, uid); 22012710Smckusick xprintf(0); 22112710Smckusick return; 22212710Smckusick } 22312710Smckusick putchar('\n'); 22412710Smckusick xprintf("Disc quotas for %s (uid %d):", name, uid); 22512710Smckusick xprintf(0); 22613222Ssam printf("%10s%8s %7s%8s%8s%8s %7s%8s%8s\n" 22712710Smckusick , "Filsys" 22812710Smckusick , "current" 22912710Smckusick , "quota" 23012710Smckusick , "limit" 23112710Smckusick , "#warns" 23212710Smckusick , "files" 23312710Smckusick , "quota" 23412710Smckusick , "limit" 23512710Smckusick , "#warns" 23612710Smckusick ); 23712710Smckusick } 23812710Smckusick 23912710Smckusick xprintf(fmt, arg1, arg2, arg3, arg4, arg5, arg6) 24012710Smckusick char *fmt; 24112710Smckusick { 24212710Smckusick char buf[100]; 24312710Smckusick static int column; 24412710Smckusick 24512710Smckusick if (fmt == 0 && column || column >= 40) { 24612710Smckusick putchar('\n'); 24712710Smckusick column = 0; 24812710Smckusick } 24912710Smckusick if (fmt == 0) 25012710Smckusick return; 25112710Smckusick sprintf(buf, fmt, arg1, arg2, arg3, arg4, arg5, arg6); 25212710Smckusick if (column != 0 && strlen(buf) < 39) 25312710Smckusick while (column++ < 40) 25412710Smckusick putchar(' '); 25512710Smckusick else if (column) { 25612710Smckusick putchar('\n'); 25712710Smckusick column = 0; 25812710Smckusick } 25912710Smckusick printf("%s", buf); 26012710Smckusick column += strlen(buf); 26112710Smckusick } 26212710Smckusick 26312710Smckusick alldigits(s) 26412710Smckusick register char *s; 26512710Smckusick { 26612710Smckusick register c; 26712710Smckusick 26812710Smckusick c = *s++; 26912710Smckusick do { 27012710Smckusick if (!isdigit(c)) 27112710Smckusick return (0); 27212710Smckusick } while (c = *s++); 27312710Smckusick return (1); 27412710Smckusick } 275