quot(1)
John F. Haugh II
jfh at rpp386.Dallas.TX.US
Fri Nov 4 01:42:29 AEST 1988
This has been posted to pubnet.sources before. pubnet does not receive
a wide distribution, so I am reposting it here. This is liable to need
much twiddling, so please hack first and write me second. Better still,
hack several times before writing ;-)
- John.
--
#include <sys/param.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
#include <sys/ino.h>
#include <sys/inode.h>
#include <sys/filsys.h>
#include <pwd.h>
#include <grp.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#undef MAXUID
#define MAXUID 400
#ifndef DEF_FS
#define DEF_FS "/dev/root"
#endif
#define DIR_BLKS 10
#define FILSYS (sizeof (struct filsys))
static char sccsid[] = "@(#)quot.c 1.0";
struct passwd *getpwuid ();
struct group *getgrgid ();
struct ublks {
int u_uid; /* uid of person/group */
long int u_blks; /* total blocks used */
} ublks[MAXUID];
int tflg, /* print totals only */
gflg; /* print groups, not users */
struct dinode *iget (fd, ino)
register int fd,
ino;
{
static long int lastblk = -1;
static struct dinode iblk[4*INOPB];
if ((lastblk >> 2) != (itod (ino) >> 2)) {
lastblk = itod (ino);
lastblk &= ~03;
if (lseek (fd, lastblk << BSHIFT, 0) < 0)
return (0);
if (read (fd, iblk, BSIZE*4) != BSIZE*4)
return (0);
}
return (&iblk[((itod (ino) & 03) * INOPB) + itoo (ino)]);
}
int fsopen (fs, superb)
char *fs;
register struct filsys *superb;
{
register int file;
if (((file = open (fs, O_RDONLY)) < 0) ||
(lseek (file, (long) (SUPERB << BSHIFT), 0) < 0) ||
(read (file, superb, BSIZE) != BSIZE))
return (-1);
else
return (file);
}
int blkcmp (a, b)
struct ublks *a, *b;
{
return (b->u_blks - a->u_blks);
}
usage ()
{
write (2, "usage: quot [ -tug ] [ filesystem ]\n", 36);
exit (1);
}
printtotals (device)
char *device;
{
int user;
struct passwd *pwent;
struct group *grent;
printf ("%s:\n", device);
qsort (ublks, MAXUID, sizeof (struct ublks), blkcmp);
for (user = 0;user < MAXUID;user++)
if (ublks[user].u_blks) {
if (! gflg)
if (pwent = getpwuid (ublks[user].u_uid))
printf ("%8.8s %d\n", pwent->pw_name, ublks[user].u_blks * 2);
else
printf ("%8.8d %d\n", ublks[user].u_uid, ublks[user].u_blks * 2);
else
if (grent = getgrgid (ublks[user].u_uid))
printf ("%8.8s %d\n", grent->gr_name, ublks[user].u_blks * 2);
else
printf ("%8.8d %d\n", ublks[user].u_uid, ublks[user].u_blks * 2);
}
}
blocks (fsize)
long int fsize;
{
long int extra = fsize; /* indirect blocks */
if (fsize <= NINDIR) /* single indirect */
return (fsize + 1);
fsize -= NINDIR;
extra++;
if (fsize <= NINDIR*NINDIR)
return (extra + ((fsize + NINDIR - 1) / NINDIR + 1));
extra += NINDIR + 1;
fsize -= NINDIR*NINDIR;
extra += (fsize + NINDIR - 1) / NINDIR; /* indirect blocks to point to direct blocks */
fsize = (fsize + NINDIR - 1) / NINDIR; /* fsize is now just the indirect block count */
extra += (fsize + NINDIR - 1) / NINDIR; /* double indirects to point to single indirects */
fsize = (fsize + NINDIR - 1) / NINDIR; /* fsize is now just the double indirect count */
extra += (fsize + NINDIR - 1) / NINDIR; /* triple indirect(s) to point to double indirects */
fsize = (fsize + NINDIR - 1) / NINDIR; /* had better just be 1 ... */
return (extra);
}
main (argc, argv)
int argc;
char **argv;
{
struct dinode *dino;
char buf[BSIZE];
struct filsys *superb = (struct filsys *) buf;
register int fd,
ino,
user;
long fsize;
long foobar;
int arg,
c,
maxino;
char *uid;
struct passwd *pwent;
for (user = 0;user < MAXUID;user++) {
ublks[user].u_blks = 0;
ublks[user].u_uid = user;
}
for (arg = 1;arg < argc;arg++) {
if (argv[arg][0] != '-')
break;
for (c = 1;argv[arg][c];c++)
switch (argv[arg][c]) {
case 't':
tflg++;
break;
case 'g':
gflg++;
break;
case 'u':
gflg = 0;
break;
default:
usage ();
}
}
if (argc == arg) {
argv[arg] = DEF_FS;
argc = arg + 1;
}
for (;arg < argc;arg++) {
if ((fd = fsopen (argv[arg], superb)) < 0) {
perror (argv[arg]);
continue;
}
if (! tflg)
for (user = 0;user < MAXUID;user++) {
ublks[user].u_blks = 0;
ublks[user].u_uid = user;
}
maxino = (superb->s_isize) * INOPB;
for (ino = 2;ino < maxino;ino++) {
if (! (dino = iget (fd, ino)))
continue;
if (! dino->di_mode || ! dino->di_nlink)
continue;
if ((dino->di_mode & IFMT) != IFDIR &&
(dino->di_mode & IFMT) != IFREG)
continue;
if (dino->di_size == 0)
continue;
if (gflg)
dino->di_uid = dino->di_gid;
if (dino->di_uid < 0 || dino->di_uid >= MAXUID)
continue;
fsize = (dino->di_size + BSIZE - 1) >> (BSHIFT);
if (fsize <= DIR_BLKS) {
ublks[dino->di_uid].u_blks += fsize;
} else {
ublks[dino->di_uid].u_blks += blocks (fsize - DIR_BLKS) + DIR_BLKS;
}
}
close (fd);
if (! tflg)
printtotals (argv[arg]);
}
if (tflg)
printtotals ("totals");
}
--
John F. Haugh II +----Make believe quote of the week----
VoiceNet: (214) 250-3311 Data: -6272 | Nancy Reagan on Richard Stallman:
InterNet: jfh at rpp386.Dallas.TX.US | "Just say `Gno'"
UucpNet : <backbone>!killer!rpp386!jfh +--------------------------------------
More information about the Alt.sources
mailing list