v17i007: space - summarize file system usage, Part01/01
Frederic Chauveau
fmc at cnam.cnam.fr
Wed Feb 20 06:45:19 AEST 1991
Submitted-by: Frederic Chauveau <fmc at 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 at 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 at 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 at 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 at 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 at 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 at 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 at uunet.uu.net.
More information about the Comp.sources.misc
mailing list