home *** CD-ROM | disk | FTP | other *** search
- From: fmc@cnam.cnam.fr (Frederic Chauveau)
- Newsgroups: comp.sources.misc
- Subject: v17i007: space - summarize file system usage, Part01/01
- Message-ID: <1991Feb19.194519.20703@sparky.IMD.Sterling.COM>
- Date: 19 Feb 91 19:45:19 GMT
- Approved: kent@sparky.imd.sterling.com
- X-Checksum-Snefru: b060c9ab 12269837 8b3692a7 e32a229d
-
- Submitted-by: Frederic Chauveau <fmc@cnam.cnam.fr>
- Posting-number: Volume 17, Issue 7
- Archive-name: space/part01
-
- space is a tool which create and update data-bases to watch how much and
- by whom disk space is used. It maintains a record of the used space on
- a per day / per users / per file-system basis.
-
- Frederic Chauveau <fmc@cnam.cnam.fr>
-
- ---- Cut Here and unpack ----
- #!/bin/sh
- # This is space, a shell archive (shar 3.32)
- # made 02/13/1991 11:50 UTC by fmc@cnam.cnam.fr
- # Source directory /users/labinf/fmc/tools/Space
- #
- # existing files will NOT be overwritten
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 9367 -rw-r--r-- space.c
- # 4960 -rw-r--r-- sysdep.c
- # 1649 -rw-r--r-- defs.h
- # 3102 -rw-r--r-- Makefile
- # 1534 -r--r--r-- space.8
- # 4037 -rw-r--r-- INSTALL
- #
- if touch 2>&1 | fgrep 'amc' > /dev/null
- then TOUCH=touch
- else TOUCH=true
- fi
- # ============= space.c ==============
- if test X"$1" != X"-c" -a -f 'space.c'; then
- echo "File already exists: skipping 'space.c'"
- else
- echo "x - extracting space.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > space.c &&
- X/*
- X * space A tool to look out for greedy users
- X * $Header: /users/labinf/fmc/tools/Space/RCS/space.c,v 2.4 91/01/24 15:14:18 fmc Exp $
- X * $Source: /users/labinf/fmc/tools/Space/RCS/space.c,v $
- X * $Locker: $
- X * $State: Exp $
- X * $Log: space.c,v $
- X * Revision 2.4 91/01/24 15:14:18 fmc
- X * Split System dependencies.
- X * Fixed a bug in -tx options.
- X *
- X * Revision 2.3 90/10/13 15:20:38 fmc
- X * Fixed a bug with the -D option (sort by Delta-percentage)
- X * Added a Startday compilation option.
- X * Some mode (final?) cleanup.
- X *
- X * Revision 2.2 90/09/01 11:06:13 fmc
- X * added -d and -D option to sort user by delta or percentage
- X * Some more (final) clean-up.
- X *
- X * Revision 2.1 90/08/30 19:00:36 fmc
- X * Do not log users occupying no space. Added -t option
- X * to look through all file Systems.
- X *
- X * Revision 2.0 90/08/28 18:57:26 fmc
- X * Split the sums by file-systems. Some Clean Up
- X *
- X * Revision 1.3 90/08/27 18:48:16 fmc
- X * Various Bug Fix
- X *
- X * Revision 1.2 90/08/10 16:35:22 fmc
- X * Added -Ln option to have a sorted list with the last n days disk occupation.
- X *
- X * Revision 1.1 90/08/02 13:47:16 fmc
- X * Initial revision
- X *
- X *
- X */
- X
- X#include "defs.h"
- X
- Xstatic char SortFlag = 0;
- Xstatic char DataFile[128];
- Xstatic RecP *Sorted;
- Xstatic short StartDay = STARTDAY;
- X
- Xint SortAllRecs(r1, r2)
- XSuprecP *r1, *r2; {
- X long v1, v2;
- X
- X switch (SortFlag)
- X {
- X case TMAX: v1 = (*r1)->Fmax; v2 = (*r2)->Fmax; break;
- X case TMIN: v1 = (*r1)->Fmin; v2 = (*r2)->Fmin; break;
- X case CUR: v1 = (*r1)->Fcur; v2 = (*r2)->Fcur; break;
- X }
- X if (v1 == v2)
- X return 0;
- X return (v2 > v1) ? 1 : -1;
- X}
- X
- Xint SortUsers(r1, r2)
- XRecP *r1, *r2; {
- X long v1, v2;
- X v1 = (*r1)->blocks[CurrentDay];
- X v2 = (*r2)->blocks[CurrentDay];
- X
- X if (v1 == v2)
- X return 0;
- X return (v2 > v1) ? 1 : -1;
- X}
- X
- Xvoid GetRecords(fn)
- Xchar *fn; {
- X unsigned int fd, i, j;
- X Record tmp;
- X
- X sprintf(DataFile,"%s/space-%s.dat",DATADIR,fn);
- X fd = open(DataFile,0);
- X if (fd < 0) {
- X perror(DataFile);
- X if (log_file && (log_file != stderr))
- X fclose(log_file);
- X exit(1);
- X }
- X
- X for (i = 0; i != MAXUSERS; i++)
- X if (WhatDidTheyDo[i]) {
- X free(WhatDidTheyDo[i]);
- X WhatDidTheyDo[i] = NULL;
- X }
- X while (read(fd, &tmp, sizeof(Record)) == sizeof(Record)) {
- X register unsigned long max = 0L, min = 500000L;
- X if (WhatDidTheyDo[tmp.uid])
- X fprintf(log_file,"Duplicate Record Entry for Uid %d\n",tmp.uid);
- X for (i = 0; i <= CurrentDay; i++) {
- X if (tmp.blocks[i] && (tmp.blocks[i] < min))
- X min = tmp.blocks[i];
- X if (tmp.blocks[i] > max) {
- X max = tmp.blocks[i];
- X }
- X }
- X tmp.dmax = max;
- X tmp.dmin = min;
- X WhatDidTheyDo[tmp.uid] = (RecP) malloc(sizeof(Record));
- X *(WhatDidTheyDo[tmp.uid]) = tmp;
- X MaxUsers++;
- X }
- X close(fd);
- X}
- X
- Xvoid SaveRecords(fn)
- Xchar *fn; {
- X unsigned int fd, i;
- X
- X sprintf(DataFile,"%s/space-%s.dat",DATADIR,fn);
- X close(creat(DataFile,0777));
- X fd = open(DataFile,1);
- X if (fd < 0) {
- X perror(DataFile);
- X if (log_file && (log_file != stderr))
- X fclose(log_file);
- X exit(1);
- X }
- X
- X for (i = 0; i != MAXUSERS; i++)
- X if (WhatDidTheyDo[i] && WhatDidTheyDo[i]->dmax)
- X write(fd, WhatDidTheyDo[i], sizeof(Record));
- X close(fd);
- X}
- X
- Xvoid DispAllFs() {
- X register int i, j;
- X
- X printf(" User ");
- X for (i = 0; i!= MaxFs; i++)
- X printf("%7s",all_fs[i].dev);
- X puts(" Total");
- X for (i = 0; i != MaxAllUsers; i++) {
- X printf("%9s",AllRecs[i]->name);
- X for (j = 0; j != MaxFs; j++) {
- X unsigned long v;
- X v = (SortFlag == CUR) ? AllRecs[i]->current[j] :
- X (SortFlag == TMIN) ? AllRecs[i]->min[j] : AllRecs[i]->max[j];
- X printf("%7lu",v);
- X }
- X printf("%7lu\n",(SortFlag == CUR) ? AllRecs[i]->Fcur :
- X (SortFlag == TMIN) ? AllRecs[i]->Fmin : AllRecs[i]->Fmax);
- X }
- X}
- X
- X
- Xvoid LookRoom(fs)
- X{
- X char dev[80];
- X register int i;
- X
- X sprintf(dev, "/dev/r%s", fs);
- X fprintf(log_file,"Checking %s\n",dev);
- X check(dev);
- X for (i = 0; i != MAXUSERS; i++) {
- X unsigned long j;
- X
- X if (!WhatDidTheyDo[i])
- X continue;
- X j = WhatDidTheyDo[i]->blocks[CurrentDay];
- X WhatDidTheyDo[i]->current = j;
- X if (WhatDidTheyDo[i]->dmin > j)
- X WhatDidTheyDo[i]->dmin = j;
- X else if (WhatDidTheyDo[i]->dmax < j)
- X WhatDidTheyDo[i]->dmax = j;
- X }
- X}
- X
- Xint SortDelta(r1, r2)
- XRecP *r1, *r2; {
- X long v1, v2;
- X v1 = (*r1)->ddel;
- X v2 = (*r2)->ddel;
- X
- X if (v1 == v2)
- X return 0;
- X return (v2 > v1) ? 1 : -1;
- X}
- X
- Xint SortPerc(r1, r2)
- XRecP *r1, *r2; {
- X double v1, v2;
- X v1 = (*r1)->dper;
- X v2 = (*r2)->dper;
- X
- X if (v1 == v2)
- X return 0;
- X return (v2 > v1) ? 1 : -1;
- X}
- X
- Xvoid LookDelta(min,mode) {
- X register int i, j;
- X
- X if (min > CurrentDay) {
- X fprintf(log_file,"Cannot look more than %d days in the past\n",CurrentDay);
- X min=CurrentDay;
- X }
- X Sorted = (RecP *) malloc(MaxUsers * sizeof(RecP));
- X for (i = 0, j = 0; i != MAXUSERS; i++)
- X if (WhatDidTheyDo[i]) {
- X double f;
- X Sorted[j] = WhatDidTheyDo[i];
- X Sorted[j]->ddel = Sorted[j]->current - Sorted[j]->blocks[CurrentDay-min];
- X f = (double) Sorted[j]->blocks[CurrentDay-min];
- X if (f)
- X Sorted[j]->dper = (double) Sorted[j]->current / f;
- X else
- X Sorted[j]->dper = HUGE;
- X j++;
- X }
- X qsort(Sorted, MaxUsers, sizeof(RecP), (mode) ? SortDelta : SortPerc);
- X for (i = 0; i != MaxUsers; i++) {
- X if (!Sorted[i]->ddel)
- X continue;
- X printf("%8s\t%10lu\t%10lu",Sorted[i]->name,Sorted[i]->current,
- X Sorted[i]->blocks[CurrentDay-min]);
- X if (mode)
- X printf("\t%10ld\n",Sorted[i]->ddel);
- X else if (Sorted[i]->dper != HUGE)
- X printf("\t%10.6f%%\n",(Sorted[i]->dper - 1)*100);
- X else
- X printf("\t+ Infini \n");
- X }
- X}
- X
- XInitWDTD() {
- X register short i;
- X FILE *pwd = fopen("/etc/passwd","r");
- X char buf[BUFSIZ], *p, *strchr();
- X int uid;
- X
- X while (fgets(buf,BUFSIZ,pwd)) {
- X if (!*buf || (*buf == '#'))
- X continue;
- X p = strchr(buf,':');
- X if (!p || !*p)
- X continue;
- X *p = '\0';
- X p = strchr(p+1,':');
- X uid = atoi(p+1);
- X if (uid < 0)
- X fprintf(log_file,"Skipping negative uid %d (%s)\n",uid,buf);
- X else if (WhatDidTheyDo[uid])
- X fprintf(log_file,"Duplicate entry uid %d (%s %s)\n",uid,buf,
- X WhatDidTheyDo[uid]->name);
- X else {
- X WhatDidTheyDo[uid] = (RecP) malloc(sizeof(Record));
- X strncpy(WhatDidTheyDo[uid]->name,buf,8);
- X WhatDidTheyDo[uid]->uid = uid;
- X for (i = 0; i != TOKEEP; i++) {
- X WhatDidTheyDo[uid]->blocks[i] = 0L;
- X }
- X MaxUsers++;
- X }
- X }
- X fclose(pwd);
- X}
- X
- Xvoid ShowUser(username)
- Xchar *username; {
- X long first = 0L, min = 0L, max = 0L;
- X register int uid, i, j, k;
- X Record *r;
- X
- X uid = usertouid(username);
- X r = WhatDidTheyDo[uid];
- X if (!r) {
- X fprintf(stderr, "No user %s [%d] on the device\n",username,uid);
- X return;
- X }
- X for (i = 0; i <= CurrentDay; i++) {
- X if (!r->blocks[i])
- X continue;
- X if (!first) {
- X first = r->blocks[i];
- X break;
- X }
- X }
- X printf("User %s (%d) is between %lu and %lu blocks (beginning at %lu)\n",
- X r->name, r->uid, r->dmin, r->dmax, first);
- X if (CurrentDay > 32)
- X k = 32;
- X else
- X k = CurrentDay;
- X printf("Here are the last %d days :",k);
- X for (j = 0, i = CurrentDay - k; i != CurrentDay; i++, j++)
- X if (j & 07)
- X printf("%8lu ",r->blocks[i+1]);
- X else
- X printf("\n%8lu ",r->blocks[i+1]);
- X puts("");
- X}
- X
- Xint CurDay() {
- X time_t t;
- X struct tm *tt;
- X
- X t = time((time_t *) 0);
- X tt = localtime(&t);
- X return (tt->tm_yday - StartDay);
- X}
- X
- XShowList(n) {
- X register int i, j;
- X
- X Sorted = (RecP *) malloc(MaxUsers * sizeof(RecP));
- X for (i = 0, j = 0; i != MAXUSERS; i++)
- X if (WhatDidTheyDo[i])
- X Sorted[j++] = WhatDidTheyDo[i];
- X qsort(Sorted, MaxUsers, sizeof(RecP), SortUsers);
- X if (n > CurrentDay)
- X n = CurrentDay;
- X for (i = 0; i != MaxUsers; i++) {
- X printf("%8s",Sorted[i]->name);
- X for (j = 0; j <= n; j++)
- X printf("%8lu",Sorted[i]->blocks[CurrentDay-j]);
- X puts("");
- X }
- X}
- X
- Xvoid Usage() {
- X fprintf(stderr,"Usage: space -iul device\n");
- X fprintf(stderr," or space -Ldays device\n");
- X fprintf(stderr," or space -s device user1 user2 ...\n");
- X fprintf(stderr," or space -t[cm-M]\n");
- X fprintf(stderr," or space -[dD]days device\n");
- X if (log_file && log_file != stderr) {
- X fclose(log_file);
- X }
- X exit(1);
- X}
- X
- Xmain(argc,argv)
- Xchar **argv; {
- X char *fs;
- X ++argv; --argc;
- X log_file = fopen(LOGFILE,"a");
- X if (!log_file) {
- X perror(LOGFILE);
- X log_file = stderr;
- X fprintf(stderr,"Loggin informations on stderr\n");
- X }
- X if (argc && (**argv == '-')) {
- X CurrentDay = CurDay();
- X switch(argv[0][1]) {
- X case 'i':
- X InitWDTD();
- X LookRoom(argv[1]);
- X SaveRecords(argv[1]);
- X exit();
- X case 'u':
- X GetRecords(argv[1]);
- X LookRoom(argv[1]);
- X SaveRecords(argv[1]);
- X break;
- X case 's':
- X GetRecords(argv[1]);
- X ++argv; --argc;
- X while (++argv, --argc)
- X ShowUser(*argv);
- X break;
- X case 'l':
- X GetRecords(argv[1]);
- X ShowList(0);
- X break;
- X case 'L':
- X GetRecords(argv[1]);
- X ShowList(atoi(*argv+2));
- X break;
- X case 'd':
- X case 'D':
- X GetRecords(argv[1]);
- X LookDelta(atoi(*argv + 2),argv[0][1] == 'd');
- X break;
- X case 't':
- X if (!argv[0][2] || argv[0][2] == 'c')
- X SortFlag = CUR;
- X else if (argv[0][2] == 'm' || argv[0][2] == '-')
- X SortFlag = TMIN;
- X else
- X SortFlag = TMAX;
- X AllFileSystems(CurrentDay);
- X break;
- X default:
- X Usage();
- X }
- X }
- X else
- X Usage();
- X if (log_file && log_file != stderr)
- X fclose(log_file);
- X}
- SHAR_EOF
- $TOUCH -am 0124154791 space.c &&
- chmod 0644 space.c ||
- echo "restore of space.c failed"
- set `wc -c space.c`;Wc_c=$1
- if test "$Wc_c" != "9367"; then
- echo original size 9367, current size $Wc_c
- fi
- fi
- # ============= sysdep.c ==============
- if test X"$1" != X"-c" -a -f 'sysdep.c'; then
- echo "File already exists: skipping 'sysdep.c'"
- else
- echo "x - extracting sysdep.c (Text)"
- sed 's/^X//' << 'SHAR_EOF' > sysdep.c &&
- X/*
- X * space A tool to look out for greedy users
- X * $Header: /users/labinf/fmc/tools/Space/RCS/sysdep.c,v 1.2 91/01/24 15:30:13 fmc Exp $
- X * $Source: /users/labinf/fmc/tools/Space/RCS/sysdep.c,v $
- X * $Locker: $
- X * $State: Exp $
- X * $Log: sysdep.c,v $
- X * Revision 1.2 91/01/24 15:30:13 fmc
- X * Added FSNAME define to check for non-local file-systems.
- X *
- X * Revision 1.1 91/01/24 15:17:50 fmc
- X * Initial revision
- X *
- X */
- X
- X#include "defs.h"
- X
- XRecP WhatDidTheyDo[MAXUSERS];
- XSuprecP TempRecs[MAXUSERS];
- XSuprecP *AllRecs;
- Xint MaxUsers = 0, MaxAllUsers = 0;
- XFsName all_fs[MAXFS];
- Xint MaxFs = 0;
- X
- XFILE *log_file;
- Xshort CurrentDay;
- X
- X/*
- X * User name to UID.
- X */
- X
- Xint usertouid(user)
- Xchar *user;
- X{
- X register struct passwd *pw;
- X struct passwd *getpwent();
- X
- X setpwent();
- X while (pw = getpwent())
- X {
- X if (!strcmp(user,pw->pw_name)) {
- X endpwent();
- X return (pw->pw_uid);
- X }
- X }
- X endpwent();
- X return -1;
- X}
- X
- X/*
- X * UID to user name
- X */
- X
- Xchar *uidtouser(uid)
- Xshort uid;
- X{
- X register struct passwd *pw;
- X struct passwd *getpwent();
- X
- X setpwent();
- X while (pw = getpwent())
- X {
- X if (uid == pw->pw_uid) {
- X endpwent();
- X return (pw->pw_name);
- X }
- X }
- X endpwent();
- X return NULL;
- X}
- X
- X/*
- X * Take inode ino/ip into account. ino (the current inode number) is used only
- X * to log inodes which belongs to no known users.
- X */
- X
- Xvoid acct(ip,ino)
- Xregister struct dinode *ip;
- Xint ino;
- X{
- X int uid = ip->di_uid;
- X
- X if ((ip->di_mode & IFMT) == 0)
- X return;
- X if ((uid >= 0) && (uid < MAXUSERS)) {
- X if (!WhatDidTheyDo[uid]) {
- X register int i;
- X char *n;
- X WhatDidTheyDo[uid] = (RecP) malloc(sizeof(Record));
- X WhatDidTheyDo[uid]->uid = uid;
- X n = uidtouser(uid);
- X if (n)
- X strcpy(WhatDidTheyDo[uid]->name,n);
- X else
- X sprintf(WhatDidTheyDo[uid]->name,"#%d",uid);
- X for (i = 0; i != CurrentDay; i++)
- X WhatDidTheyDo[uid]->blocks[i] = 0L;
- X MaxUsers++;
- X }
- X WhatDidTheyDo[uid]->blocks[CurrentDay] += ip->di_blocks / 2;
- X if (WhatDidTheyDo[uid]->name[0] == '#')
- X fprintf(log_file,"inode %d of %d blocks owned by unknown uid %d\n",
- X ino,ip->di_blocks,uid);
- X }
- X}
- X
- X/*
- X * Block Read. Read block bno of size cnt from file fd into buf.
- X */
- X
- Xvoid bread(fd, bno, buf, cnt)
- Xunsigned bno;
- Xchar *buf;
- X{
- X
- X lseek(fd, (long)bno * DEV_BSIZE, L_SET);
- X if (read(fd, buf, cnt) != cnt) {
- X fprintf(log_file, "\tread error at block %u\n", bno);
- X if (log_file && log_file != stderr)
- X fclose(log_file);
- X exit(1);
- X }
- X}
- X
- Xunion {
- X struct fs u_sblock;
- X char dummy[SBSIZE];
- X} sb_un;
- X#define sblock sb_un.u_sblock
- X
- Xstruct dinode itab[MAXBSIZE/sizeof(struct dinode)];
- Xunsigned ino;
- X
- X/*
- X * Browse the file file_system. file should be the name of a block device
- X * corresponding to a disk partition.
- X */
- X
- Xvoid check(file)
- Xchar *file;
- X{
- X register int i, j, nfiles;
- X daddr_t iblk;
- X int c, fd;
- X
- X fd = open(file, O_RDONLY);
- X if (fd < 0) {
- X fprintf(log_file, "\tCan't access %s\n",file);
- X return;
- X }
- X sync();
- X bread(fd, SBLOCK, (char *)&sblock, SBSIZE);
- X nfiles = sblock.fs_ipg * sblock.fs_ncg;
- X for (ino = 0; ino < nfiles; ) {
- X iblk = fsbtodb(&sblock, itod(&sblock, ino));
- X bread(fd, iblk, (char *)itab, sblock.fs_bsize);
- X for (j = 0; j < INOPB(&sblock) && ino < nfiles; j++, ino++) {
- X if (ino < ROOTINO)
- X continue;
- X acct(&itab[j],ino);
- X }
- X }
- X close(fd);
- X}
- X
- X/*
- X * Browse though all file-systems (using getfsent()) and check all
- X * valid file system (file system of type ufs_name).
- X */
- X
- Xvoid AllFileSystems(day)
- Xshort day;
- X{
- X register struct fstab *fs;
- X register char *cp;
- X char dev[80], *rindex();
- X FsName *fsp;
- X register int i, j;
- X
- X if (setfsent() == 0) {
- X fprintf(log_file, "space: no %s file\n", FSTAB);
- X exit(1);
- X }
- X while (fs = getfsent()) {
- X
- X /*
- X * Make sure we can read the file system.
- X */
- X
- X#ifdef FSNAME
- X if (!strcmp(fs->fs_name,FSNAME))
- X continue;
- X#endif
- X if (strcmp(fs->fs_type, FSTAB_RO) &&
- X strcmp(fs->fs_type, FSTAB_RW) &&
- X strcmp(fs->fs_type, FSTAB_RQ))
- X continue;
- X cp = rindex(fs->fs_spec, '/');
- X if (cp == 0)
- X continue;
- X fsp = all_fs + MaxFs;
- X strcpy(fsp->dev,++cp);
- X fsp->mount_point = (char *) malloc(strlen(fs->fs_file)+1);
- X strcpy(fsp->mount_point,fs->fs_file);
- X GetRecords(cp);
- X for (i = 0; i != MAXUSERS; i++) {
- X RecP rp = WhatDidTheyDo[i];
- X SuprecP sp = TempRecs[i];
- X
- X if (!rp)
- X continue;
- X if (!sp) {
- X sp = TempRecs[i] = (SuprecP) malloc(sizeof(Suprec));
- X sp->uid = rp->uid;
- X strcpy(sp->name,rp->name);
- X MaxAllUsers++;
- X }
- X sp->Fcur += sp->current[MaxFs] = rp->current;
- X sp->Fmin += sp->min[MaxFs] = rp->dmin;
- X sp->Fmax += sp->max[MaxFs] = rp->dmax;
- X }
- X MaxFs++;
- X }
- X endfsent();
- X AllRecs = (SuprecP *) malloc(MaxAllUsers * sizeof(SuprecP));
- X for (i = 0, j = 0; i != MAXUSERS; i++)
- X if (TempRecs[i])
- X AllRecs[j++] = TempRecs[i];
- X qsort(AllRecs,MaxAllUsers,sizeof(SuprecP),SortAllRecs);
- X DispAllFs();
- X}
- X
- SHAR_EOF
- $TOUCH -am 0124154791 sysdep.c &&
- chmod 0644 sysdep.c ||
- echo "restore of sysdep.c failed"
- set `wc -c sysdep.c`;Wc_c=$1
- if test "$Wc_c" != "4960"; then
- echo original size 4960, current size $Wc_c
- fi
- fi
- # ============= defs.h ==============
- if test X"$1" != X"-c" -a -f 'defs.h'; then
- echo "File already exists: skipping 'defs.h'"
- else
- echo "x - extracting defs.h (Text)"
- sed 's/^X//' << 'SHAR_EOF' > defs.h &&
- X/*
- X * defs.h
- X * $Header:
- X * $Source:
- X * $Locker: $
- X * $State: Exp $
- X * $Log:
- X *
- X */
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <signal.h>
- X#include <ctype.h>
- X#include <pwd.h>
- X#include <fstab.h>
- X#include <math.h>
- X#include <sys/time.h>
- X#include <sys/stat.h>
- X#include <sys/param.h>
- X#include <sys/file.h>
- X#include <ufs/fs.h>
- X#ifdef ULTRIX
- X#include <sys/inode.h>
- X#else
- X#include <sys/vnode.h>
- X#include <ufs/inode.h>
- X#endif
- X
- X#ifndef TOKEEP
- X#define TOKEEP 365
- X#endif
- X
- X#define MAXUSERS 9999
- X#define MAXFS 10
- X
- X#define CUR 0
- X#define TMIN 1
- X#define TMAX 2
- X#define FCUR 3
- X#define FMIN 4
- X#define FMAX 5
- X
- Xtypedef unsigned long Blocks[TOKEEP];
- X
- Xtypedef struct {
- X char dev[5];
- X char *mount_point;
- X} FsName;
- X
- Xtypedef struct {
- X short uid;
- X char name[9];
- X unsigned long current[MAXFS], min[MAXFS], max[MAXFS];
- X unsigned long Fcur, Fmin, Fmax;
- X} Suprec, *SuprecP;
- X
- Xtypedef struct {
- X short uid;
- X char name[9];
- X unsigned long current;
- X union {
- X unsigned long min;
- X long delta;
- X } delt;
- X#define dmin delt.min
- X#define ddel delt.delta
- X union {
- X unsigned long max;
- X double perc;
- X } perc;
- X#define dmax perc.max
- X#define dper perc.perc
- X Blocks blocks;
- X} Record, *RecP;
- X
- X
- X#ifndef DATADIR
- X#define DATADIR "/usr/tmp"
- X#endif
- X
- X#ifndef LOGFILE
- X#define LOGFILE "/usr/tmp/space.log"
- X#endif
- X
- X#ifndef STARTDAY
- X#define STARTDAY 0
- X#endif
- X
- Xextern FILE *log_file;
- Xextern short CurrentDay;
- Xextern short StartDay;
- Xextern char SortFlag;
- Xextern RecP WhatDidTheyDo[MAXUSERS];
- Xextern RecP *Sorted;
- Xextern SuprecP TempRecs[MAXUSERS];
- Xextern SuprecP *AllRecs;
- Xextern int MaxUsers, MaxAllUsers;
- Xextern FsName all_fs[MAXFS];
- Xextern int MaxFs;
- X
- Xint SortAllRecs();
- X
- SHAR_EOF
- $TOUCH -am 0124154791 defs.h &&
- chmod 0644 defs.h ||
- echo "restore of defs.h failed"
- set `wc -c defs.h`;Wc_c=$1
- if test "$Wc_c" != "1649"; then
- echo original size 1649, current size $Wc_c
- fi
- fi
- # ============= Makefile ==============
- if test X"$1" != X"-c" -a -f 'Makefile'; then
- echo "File already exists: skipping 'Makefile'"
- else
- echo "x - extracting Makefile (Text)"
- sed 's/^X//' << 'SHAR_EOF' > Makefile &&
- X# $Header:
- X# $Source:
- X# $Locker: $
- X# $State: Exp $
- X# $Log: Makefile,v $
- X# Revision 1.9 91/01/24 15:48:42 fmc
- X# More fixes.
- X#
- X# Revision 1.7 91/01/24 15:28:46 fmc
- X# Added check for make depend.
- X#
- X# Revision 1.6 91/01/24 15:16:42 fmc
- X# moved the system dependent stuff in sysdep.c
- X#
- X# Revision 1.5 90/09/01 11:05:52 fmc
- X# Added install and clean target.
- X#
- X# Revision 1.4 90/08/31 16:26:24 fmc
- X# Added makedepend
- X#
- X# Revision 1.3 90/08/31 16:19:10 fmc
- X# More clean up
- X#
- X# Revision 1.2 90/08/30 19:01:25 fmc
- X# Some cleanup
- X#
- X# Revision 1.1 90/08/08 17:53:12 fmc
- X# Initial revision
- X#
- X
- XDESTDIR=/users/labinf/fmc/bin
- XCC=gcc
- XDEBUGFLAGS= -g
- XOPTFLAGS= -O -fwritable-strings -finline-functions
- XCPPFLAGS=
- X#
- X# For some system you have to define FSNAME as a string
- X# with the type of local file-system.
- X# On Ultrix it should be :
- X# SYSFLAGS= -DFSNAME=\"ufs\" -DULTRIX
- XSYSFLAGS= -DFSNAME=\"ufs\" -DULTRIX -DDATADIR=\"/usr/src\"
- XCFLAGS= $(DEBUGFLAGS) $(CPPFLAGS) $(OPTFLAGS) $(SYSFLAGS)
- XLDFLAGS= $(DEBUGFLAGS)
- XMISC= Makefile space.8 INSTALL
- XSRCS= space.c sysdep.c defs.h
- XOBJS= space.o sysdep.o
- XMAKEDEPEND= makedepend
- X
- Xall: space
- X
- Xspace: $(OBJS)
- X $(CC) $(CFLAGS) $(LDFLAGS) -o space $(OBJS) -lm
- X
- Xinstall: all
- X install space $(DESTDIR)
- X
- Xclean:
- X rm -f *~ #* *.o core space .depend
- X
- Xdepend: $(SRCS)
- X $(MAKEDEPEND) -- $(CPPFLAGS) $(SYSFLAGS) -- $(SRCS)
- X
- Xshar: $(SRCS) $(MISC)
- X shar -n space -a -x -c -o space.shar $(SRCS) $(MISC)
- X
- X
- X# DO NOT DELETE THIS LINE -- make depend depends on it.
- X
- Xspace.o: defs.h /usr/include/stdio.h /usr/include/sys/types.h
- Xspace.o: /usr/include/signal.h /usr/include/ctype.h /usr/include/pwd.h
- Xspace.o: /usr/include/fstab.h /usr/local/lib/gcc-include/math.h
- Xspace.o: /usr/include/sys/time.h /usr/include/sys/stat.h
- Xspace.o: /usr/include/sys/param.h /usr/include/machine/param.h
- Xspace.o: /usr/include/sys/smp_lock.h /usr/include/sys/file.h
- Xspace.o: /usr/include/ufs/fs.h /usr/include/sys/inode.h
- Xspace.o: /usr/include/sys/gnode_common.h /usr/include/ufs/ufs_inode.h
- Xspace.o: /usr/include/sys/gnode.h
- Xsysdep.o: defs.h /usr/include/stdio.h /usr/include/sys/types.h
- Xsysdep.o: /usr/include/signal.h /usr/include/ctype.h /usr/include/pwd.h
- Xsysdep.o: /usr/include/fstab.h /usr/local/lib/gcc-include/math.h
- Xsysdep.o: /usr/include/sys/time.h /usr/include/sys/stat.h
- Xsysdep.o: /usr/include/sys/param.h /usr/include/machine/param.h
- Xsysdep.o: /usr/include/sys/smp_lock.h /usr/include/sys/file.h
- Xsysdep.o: /usr/include/ufs/fs.h /usr/include/sys/inode.h
- Xsysdep.o: /usr/include/sys/gnode_common.h /usr/include/ufs/ufs_inode.h
- Xsysdep.o: /usr/include/sys/gnode.h
- Xdefs.o: /usr/include/stdio.h /usr/include/sys/types.h /usr/include/signal.h
- Xdefs.o: /usr/include/ctype.h /usr/include/pwd.h /usr/include/fstab.h
- Xdefs.o: /usr/local/lib/gcc-include/math.h /usr/include/sys/time.h
- Xdefs.o: /usr/include/sys/stat.h /usr/include/sys/param.h
- Xdefs.o: /usr/include/machine/param.h /usr/include/sys/smp_lock.h
- Xdefs.o: /usr/include/sys/file.h /usr/include/ufs/fs.h
- Xdefs.o: /usr/include/sys/inode.h /usr/include/sys/gnode_common.h
- Xdefs.o: /usr/include/ufs/ufs_inode.h /usr/include/sys/gnode.h
- SHAR_EOF
- $TOUCH -am 0213114991 Makefile &&
- chmod 0644 Makefile ||
- echo "restore of Makefile failed"
- set `wc -c Makefile`;Wc_c=$1
- if test "$Wc_c" != "3102"; then
- echo original size 3102, current size $Wc_c
- fi
- fi
- # ============= space.8 ==============
- if test X"$1" != X"-c" -a -f 'space.8'; then
- echo "File already exists: skipping 'space.8'"
- else
- echo "x - extracting space.8 (Text)"
- sed 's/^X//' << 'SHAR_EOF' > space.8 &&
- X.\" RCSID: @(#)space.8 2.3 11/10/90
- X.TH space 8
- X.SH Name
- Xspace \- summarize file system usage
- X.SH Syntax
- X.B /usr/local/bin/space
- X[ option ] ...
- X[ filesystem ]
- X.SH Description
- X.NXR "space command"
- X.NXR "file system" "disk usage per user"
- XThe
- X.PN space
- Xcommand maintains the disk usage for a file system on a user basis.
- X.SH Options
- X.TP
- X.B \-i filesystem
- XInitialize the data-base associated with the given file system. Only the super user can give this command.
- X.TP
- X.B \-u filesystem
- XUpdate the database for the given file system. Onlu the super user can give this command.
- X.TP
- X.B \-s filesystem user1 user2 ... usern
- XList the disk usage on the given filesystem for each users in arguments.
- X.TP
- X.B \-l filesystem
- XList the current disk usage for the given file system, sorted by most greedy users.
- X.TP
- X.B \-Ln filesystem
- XSame as option \-l but
- X.I n
- Xdays in the past.
- X.TP
- X.B \-dn filesystem
- XList the difference in blocks between current usage and usage
- X.I n
- Xdays in the past.
- X.TP
- X.B \-Dn filesystem
- XList the difference in percentage between current usage and usage
- X.I n
- Xdays in the past.
- X.TP
- X.B \-tx
- XSummarize the disk usage on the whole system, depending on the
- X.I x
- Xletter.
- X.I c
- Xgives the current usage.
- X.I m
- Xgives the minimum usage.
- X.I M
- Xgives the maximum usage.
- X.SH Files
- XFile system names varies with system.
- X.br
- X/etc/passwd to get user names
- X.br
- X/usr/src/space-xxx.data for accumulated data for filesystem xxx
- X.SH See Also
- Xdu(1), ls(1), quot(8)
- X.SH Bugs
- XCertainly a lot. If you find one, send a mail to fmc@cnam.cnam.fr
- X
- SHAR_EOF
- $TOUCH -am 0213114791 space.8 &&
- chmod 0444 space.8 ||
- echo "restore of space.8 failed"
- set `wc -c space.8`;Wc_c=$1
- if test "$Wc_c" != "1534"; then
- echo original size 1534, current size $Wc_c
- fi
- fi
- # ============= INSTALL ==============
- if test X"$1" != X"-c" -a -f 'INSTALL'; then
- echo "File already exists: skipping 'INSTALL'"
- else
- echo "x - extracting INSTALL (Text)"
- sed 's/^X//' << 'SHAR_EOF' > INSTALL &&
- Xspace Version 1.9 Bugs, Gripes, etc... to fmc@cnam.cnam.fr
- X Last Modification: 12 Feb 91
- X
- Xspace is a maintenance tool used to watch disk-space usage on a per
- Xuser per day basis. Be warned that you need :
- X
- X1/ root privilege to update the data-base (not to read it).
- X
- X2/ 1488 bytes per user per file-system, for each user UID possessing a
- X file on a file-system. Here we have around 300 users, 6
- X file-systems are checked, giving us 496 user/fs entries or
- X 738048 bytes.
- X
- X3/ Right now, this usage is ... on a year by year basis. It means that
- X 1/ Each year, you have to re-initialize the DB
- X 2/ The starting point of the record keeping is hard-wired in the
- X code.
- X In fact, the rationale behind STARTDAY definition is not quite
- X clear. It will be used in the futur, but right now, it's only
- X use is to save some space (If you begin checking on the 1st Feb,
- X #define STARTDAY 31 and #define TOKEEP 334).
- X In a (hopefully) near future, space will read a configuration file
- X to determine such parameters.
- X
- X4/ Finally, space haws only be tested on :
- X
- X 1/ A Vax running Ultrix (3.1 and now 4.0) using gcc
- X 2/ A Sony MIPS running sony-os (3.3 and now 4.0) with mips-cc.
- X
- X I think the code in sysdep.c is rather BSD-dependent, but I've no
- X SysV box to test it.
- X
- XHow to Compile.
- X
- XIn the best case do a make depend, followed by a make all and a make install.
- X
- XI think everything system dependent resides in sysdep.c and it's there
- Xyou should check for trouble.
- X
- XCOMPILATION options.
- X
- XThe following #defines resides in defs.h change them if the default
- Xvalue doesn't correspond to your needs/environment :
- X
- Xname default value meaning
- XTOKEEP 365 How many days are stored.
- XMAXUSERS 9999 Maximum number of users (should be enough:-)
- XMAXFS 10 Maximum number of fs checked.
- XDATADIR "/usr/tmp" Where to keep the DBs
- XLOGFILE "/usr/tmp/space.log" The log file name.
- XSTARTDAY 0 First Day in the record (from 1st Jan.)
- XFSNAME not defined To check the fs type for local fs only.
- XDESTDIR /usr/local/bin In the Makefile for make install.
- X
- XHow to Install.
- X
- Xmake install (hopefully). You then must :
- X 1/ Initialize the DBs for each fs checked by :
- X for fs in fs1 fs2 ... fsn ; do space -i $fs ; done
- X space -i fs1 will look for the /dev/rfs1 file.
- X
- X 2/ Make sure the DBs are updated once a day (there's no check
- X to see if the DBs were already updated or not.) by doing
- X for fs in fs1 fs2 ... fsn ; do space -u $f ; done
- X The simplest way is to run it from cron, at night :-)
- X
- XHow to Use.
- X
- XThe most useful option are :
- X
- X -- space -l fs1
- X which will list, by decreasing order, all users with the disk space
- X they are currently using on /dev/rfs1.
- X
- X -- space -dn fs1
- X which will list, by decreasing order, the variation of the disk space
- X used between 'n' days ago and today.
- X
- XOther options include :
- X
- X -- space -s fs1 user1 user2 ... userN
- X last 32 days space usage on /dev/rfs1 for each user name mentionned
- X
- X -- space -Ln fs1
- X last 'n' days space usage on dev/rfs1 for each users.
- X
- X -- space -Dn fs1
- X same as -dn but display percentage instead of difference.
- X
- X -- space -tx
- X display disk usage for everybody on every local fs in /etc/fstab.
- X the 'x' has the following meaning :
- X - space -tc or space -t List Current Usage.
- X - space -tm or space -t- List Minimum Usage.
- X - space -tM or space -t+ List Maximum Usage.
- X Really useful if all file-systems are checked.
- X
- X
- XFutur modifications.
- X
- XThe main modification will be to introduce some sort of config. file
- Xcontaining all parameters wich are now #define'd.
- X
- XI also plane to introduce some sort of "time granularity" to enable
- Xthe check to be done on a 1 hour basis or every 2 days, and so on.
- X
- XI also intend to add code to get ride of old users and extend the
- Xlife time of the DBs for more than a year.
- X
- XAnd, of course, I'll try to fix bugs as they are reported. Space is
- Xrunning on our site for more than a 4 months now without much trouble,
- Xbut it as only be tested on the configuration mentionned above.
- X
- SHAR_EOF
- $TOUCH -am 0213114691 INSTALL &&
- chmod 0644 INSTALL ||
- echo "restore of INSTALL failed"
- set `wc -c INSTALL`;Wc_c=$1
- if test "$Wc_c" != "4037"; then
- echo original size 4037, current size $Wc_c
- fi
- fi
- exit 0
-
- [fmc]
-
- -------------------------------------------------------------------------------
- Frederic Chauveau Conservatoire National des Arts et Metiers
- fmc@cnam.cnam.fr
- -------------------------------------------------------------------------------
- Paradise is exactly like where you are right now, only much, much better.
- William S. Burroughs
- -------------------------------------------------------------------------------
-
- exit 0 # Just in case...
- --
- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM
- Sterling Software, IMD UUCP: uunet!sparky!kent
- Phone: (402) 291-8300 FAX: (402) 291-4362
- Please send comp.sources.misc-related mail to kent@uunet.uu.net.
-