quot.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 445 行
C
445 行
#ifndef lintstatic char *sccsid = "@(#)quot.c 4.1 ULTRIX 7/2/90";#endif/************************************************************************ * * * Copyright (c) 1984 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//* * MODIFICATION HISTORY * * 13-Jul-88 -- prs * Added a check that verifies we are running on a local file * system. * * 24-Jun-88 -- prs * Fixed a bug, where quot would dump core if a negative uid owned * a file in the file system. * * 23-Jun-86 -- Koehler * disk inodes now have time stored as struct timeval rather than * time_t. Changed to reflect the new time * *//* * quot */#include <stdio.h>#include <ctype.h>#include <sys/param.h>#include <sys/inode.h>#include <sys/fs.h>#include <sys/file.h>#define ISIZ (MAXBSIZE/sizeof(struct dinode))union { struct fs u_sblock; char dummy[SBSIZE];} sb_un;#define sblock sb_un.u_sblockstruct dinode itab[MAXBSIZE/sizeof(struct dinode)];struct du { struct du *next; long blocks; long blocks30; long blocks60; long blocks90; long nfiles; int uid;#define NDU 2048} du[NDU];int ndu;#define DUHASH 8209 /* smallest prime >= 4 * NDU */#define HASH(u) ((u) % DUHASH)struct du *duhash[DUHASH];#define TSIZE 500int sizes[TSIZE];long overflow;int nflg;int fflg;int cflg;int vflg;int hflg;long now;unsigned ino;char *malloc();char *getname();main(argc, argv) int argc; char *argv[];{ register int n; now = time(0); argc--, argv++; while (argc > 0 && argv[0][0] == '-') { register char *cp; for (cp = &argv[0][1]; *cp; cp++) switch (*cp) { case 'n': nflg++; break; case 'f': fflg++; break; case 'c': cflg++; break; case 'v': vflg++; break; case 'h': hflg++; break; default: fprintf(stderr, "usage: quot [ -nfcvh ] [ device ... ]\n"); exit(1); } argc--, argv++; } if (argc == 0) quotall(); while (argc-- > 0) if (check(*argv++) == 0) report(); exit (0);}#include <fstab.h>quotall(){ register struct fstab *fs; register char *cp; char dev[80], *rindex(); char *ufs_name = "ufs"; if (setfsent() == 0) { fprintf(stderr, "quot: no %s file\n", FSTAB); exit(1); } while (fs = getfsent()) { if (strcmp(fs->fs_type, FSTAB_RO) && strcmp(fs->fs_type, FSTAB_RW) && strcmp(fs->fs_type, FSTAB_RQ)) continue; /* * Make sure we are a local file system. */ if (strcmp(fs->fs_name, ufs_name)) continue; cp = rindex(fs->fs_spec, '/'); if (cp == 0) continue; sprintf(dev, "/dev/r%s", cp + 1); if (check(dev) == 0) report(); } endfsent();}check(file) char *file;{ register int i, j, nfiles; register struct du **dp; daddr_t iblk; int c, fd; /* * Initialize tables between checks; * because of the qsort done in report() * the hash tables must be rebuilt each time. */ for (i = 0; i < TSIZE; i++) sizes[i] = 0; overflow = 0; for (dp = duhash; dp < &duhash[DUHASH]; dp++) *dp = 0; ndu = 0; fd = open(file, O_RDONLY); if (fd < 0) { fprintf(stderr, "quot: "); perror(file); return (-1); } printf("%s:\n", file); sync(); bread(fd, SBLOCK, (char *)&sblock, SBSIZE); if (nflg) { if (isdigit(c = getchar())) ungetc(c, stdin); else while (c != '\n' && c != EOF) c = getchar(); } nfiles = sblock.fs_ipg * sblock.fs_ncg; for (ino = 0; ino < nfiles; ) { iblk = fsbtodb(&sblock, itod(&sblock, ino)); bread(fd, iblk, (char *)itab, sblock.fs_bsize); for (j = 0; j < INOPB(&sblock) && ino < nfiles; j++, ino++) { if (ino < ROOTINO) continue; acct(&itab[j]); } } close(fd);}acct(ip) register struct dinode *ip;{ register struct du *dp; struct du **hp; long blks, frags, size; char n; static fino; if ((ip->di_mode & IFMT) == 0) return; /* * If the uid is less than zero, an example would be nobody * (uid = -2), return. */ if (ip->di_uid < 0) return; /* * By default, take block count in inode. Otherwise (-h), * take the size field and estimate the blocks allocated. * The latter does not account for holes in files. */ if (!hflg) size = ip->di_blocks / 2; else { blks = lblkno(&sblock, ip->di_size); frags = blks * sblock.fs_frag + numfrags(&sblock, dblksize(&sblock, ip, blks)); size = frags * sblock.fs_fsize / 1024; } if (cflg) { if ((ip->di_mode&IFMT) != IFDIR && (ip->di_mode&IFMT) != IFREG) return; if (size >= TSIZE) { overflow += size; size = TSIZE-1; } sizes[size]++; return; } hp = &duhash[HASH(ip->di_uid)]; for (dp = *hp; dp; dp = dp->next) if (dp->uid == ip->di_uid) break; if (dp == 0) { if (ndu >= NDU) return; dp = &du[ndu++]; dp->next = *hp; *hp = dp; dp->uid = ip->di_uid; dp->nfiles = 0; dp->blocks = 0; dp->blocks30 = 0; dp->blocks60 = 0; dp->blocks90 = 0; } dp->blocks += size;#define DAY (60 * 60 * 24) /* seconds per day */ if (now - ip->di_atime.tv_sec > 30 * DAY) dp->blocks30 += size; if (now - ip->di_atime.tv_sec > 60 * DAY) dp->blocks60 += size; if (now - ip->di_atime.tv_sec > 90 * DAY) dp->blocks90 += size; dp->nfiles++; while (nflg) { register char *np; if (fino == 0) if (scanf("%d", &fino) <= 0) return; if (fino > ino) return; if (fino < ino) { while ((n = getchar()) != '\n' && n != EOF) ; fino = 0; continue; } if (np = getname(dp->uid)) printf("%.7s ", np); else printf("%d ", ip->di_uid); while ((n = getchar()) == ' ' || n == '\t') ; putchar(n); while (n != EOF && n != '\n') { n = getchar(); putchar(n); } fino = 0; break; }}bread(fd, bno, buf, cnt) unsigned bno; char *buf;{ lseek(fd, (long)bno * DEV_BSIZE, L_SET); if (read(fd, buf, cnt) != cnt) { fprintf(stderr, "quot: read error at block %u\n", bno); exit(1); }}qcmp(p1, p2) register struct du *p1, *p2;{ char *s1, *s2; if (p1->blocks > p2->blocks) return (-1); if (p1->blocks < p2->blocks) return (1); s1 = getname(p1->uid); if (s1 == 0) return (0); s2 = getname(p2->uid); if (s2 == 0) return (0); return (strcmp(s1, s2));}report(){ register i; register struct du *dp; if (nflg) return; if (cflg) { register long t = 0; for (i = 0; i < TSIZE - 1; i++) if (sizes[i]) { t += i*sizes[i]; printf("%d %d %D\n", i, sizes[i], t); } printf("%d %d %D\n", TSIZE - 1, sizes[TSIZE - 1], overflow + t); return; } qsort(du, ndu, sizeof (du[0]), qcmp); for (dp = du; dp < &du[ndu]; dp++) { register char *cp; if (dp->blocks == 0) return; printf("%5D\t", dp->blocks); if (fflg) printf("%5D\t", dp->nfiles); if (cp = getname(dp->uid)) printf("%-8.8s", cp); else printf("#%-8d", dp->uid); if (vflg) printf("\t%5D\t%5D\t%5D", dp->blocks30, dp->blocks60, dp->blocks90); printf("\n"); }}#include <pwd.h>#include <utmp.h>struct utmp utmp;#define NUID 2048#define NMAX (sizeof (utmp.ut_name))char names[NUID][NMAX+1];char outrangename[NMAX+1];int outrangeuid = -1;char *getname(uid) int uid;{ register struct passwd *pw; static init; struct passwd *getpwent(); if (uid >= 0 && uid < NUID && names[uid][0]) return (&names[uid][0]); if (uid >= 0 && uid == outrangeuid) return (outrangename);rescan: if (init == 2) { if (uid < NUID) return (0); setpwent(); while (pw = getpwent()) { if (pw->pw_uid != uid) continue; outrangeuid = pw->pw_uid; strncpy(outrangename, pw->pw_name, NMAX); endpwent(); return (outrangename); } endpwent(); return (0); } if (init == 0) setpwent(), init = 1; while (pw = getpwent()) { if (pw->pw_uid < 0 || pw->pw_uid >= NUID) { if (pw->pw_uid == uid) { outrangeuid = pw->pw_uid; strncpy(outrangename, pw->pw_name, NMAX); return (outrangename); } continue; } if (names[pw->pw_uid][0]) continue; strncpy(names[pw->pw_uid], pw->pw_name, NMAX); if (pw->pw_uid == uid) return (&names[uid][0]); } init = 2; goto rescan;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?