Files
Arquivotheca.SunOS-4.1.4/usr.etc/rfs/fusage/fusage.c
seta75D ff309bfe1c Init
2021-10-11 18:37:13 -03:00

310 lines
7.2 KiB
C

/* @(#)fusage.c 1.1 94/10/31 SMI */
/* Copyright (c) 1987 Sun Microsystems */
/* ported from System V.3.1 */
/* Copyright (c) 1984 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ident "@(#)fusage:fusage.c 1.15.3.1"
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/vfs.h>
#include <mntent.h>
#include <rfs/rfs_misc.h>
#include <rfs/nserve.h>
#include <rfs/rfs_mnt.h>
#include <ctype.h>
#include <rfs/fumount.h>
#include <rfs/rfsys.h>
#include <errno.h>
#define ADVTAB "/etc/advtab"
char *malloc();
#ifndef SZ_PATH
#define SZ_PATH 128
#endif
struct advlst {
char resrc[SZ_RES+1];
char dir[SZ_PATH+1];
} *advlst;
/* The block size in RFS is 1K instead of 8K. */
#ifndef RFS_BKSIZE
#define RFS_BKSIZE 1024
#endif RFS_BKSIZE
struct clnts *client;
struct mnttab *mnttab;
extern int errno;
main(argc, argv)
int argc;
char *argv[];
{
char str[SZ_RES+SZ_MACH+SZ_PATH+20]; /* hold strings from adv table */
int nadv, clntsum, advsum, local, prtflg, fswant, i, j, k;
int exitcode = 0;
FILE *atab, *mntfilep;
struct mntent *mntentp;
struct stat stbuf;
char myname[32]; /* Host names are limited to 31 chars. */
for (i = 0; i < argc; i++)
if (argv[i][0] == '-') {
fprintf(stderr, "Usage: %s [mounted file system]\n", argv[0]);
fprintf(stderr, " [advertised resource]\n");
fprintf(stderr, " [mounted block special device]\n");
exit(1);
}
/* command fails when RFS not installed in system */
if ((rfsys(RF_RUNSTATE) == -1) && errno == RFS_ENOPKG) {
perror("fusage");
exit(1);
}
gethostname(myname, 31);
myname[31] = '\0'; /* in case name is longer than 31 chars */
printf("\nFILE USAGE REPORT FOR %.8s\n\n", myname);
/* load resource and directory names from /etc/advtab */
if (stat(ADVTAB, &stbuf) == -1) {
nadv = 0;
goto noadv;
}
if ((atab = fopen(ADVTAB, "r")) == 0) {
fprintf(stderr, "fusage: cannot open %s", ADVTAB);
perror("fopen");
exit(1);
}
nadv = 0; /* count lines in advtab */
while (getline(str, sizeof(str), atab) != 0)
nadv++;
if ((nadv != 0) &&
((advlst = (struct advlst *)malloc(nadv * sizeof(struct advlst)))
== 0)) {
fprintf(stderr, "fusage: cannot get memory for advtab\n");
exit(1);
}
freopen(ADVTAB, "r", atab); /* rewind */
/*
* load advlst from advtab.
* We are not going to store the complete line for each entry
* in /etc/advtab. Only the resource name and the path name
* are important here (client names are unnecessary).
*/
i = 0;
while ((getline(str, sizeof(str), atab) != 0) && (i < nadv)) {
loadadvl(str, &advlst[i++]);
}
if (nlload())
exit(1);
/*
* Get mount information by calling getmntent until if returns NULL.
* If the mount is a local file system, find advertised
* resources that are within it. Collect and print data
* on each remote, then print the info for the file system.
* Even though we may be requested to print a subset of the
* mounted resources, we must always execute all of the loop
* in order to get data for items that are printed.
*/
noadv:
mntfilep = setmntent(MOUNTED, "r");
while (mntentp = getmntent(mntfilep)) {
if (strcmp(mntentp->mnt_type, MNTTYPE_42) != 0)
continue;
if (wantprint(argc, argv, mntentp->mnt_fsname,
mntentp->mnt_dir)) {
printf("\n\t%-15s %s\n", mntentp->mnt_fsname,
mntentp->mnt_dir);
fswant++;
} else
fswant = 0;
advsum = 0;
if (stat(mntentp->mnt_dir, &stbuf) < 0)
perror("stat");
for (j = 0; j < nadv; j++) {
if (isinfs(mntentp, advlst[j].dir)) {
prtflg = wantprint(argc, argv, advlst[j].resrc,
advlst[j].dir);
if (prtflg)
printf("\n\t%15s", advlst[j].resrc);
/* get client list */
switch(getnodes(advlst[j].resrc, 0)) {
case 1:
if (prtflg)
printf(" (%s) not in kernel advertise table\n",
advlst[j].dir);
continue;
break;
case 2:
if (prtflg)
printf(
" (%s) ...bad data\n",
advlst[j].dir);
continue;
break;
case 3:
if (prtflg)
printf(
" (%s) ...no clients\n",
advlst[j].dir);
continue;
}
if (prtflg)
printf(" %s\n", advlst[j].dir);
clntsum = 0;
for (k = 0; client[k].flags != EMPTY; k++) {
if (prtflg)
prdat(client[k].node,
client[k].bcount *
RFS_BKSIZE);
clntsum += client[k].bcount;
}
if (prtflg)
prdat("Sub Total",
clntsum * RFS_BKSIZE);
advsum += clntsum;
}
}
if (fswant){
printf("\n\t%15s %s\n", "", mntentp->mnt_dir);
if ((local = getcount(mntentp->mnt_dir)) != -1)
prdat(myname, local * stbuf.st_blksize);
}
if (!wantprint(argc, argv, mntentp->mnt_fsname,
mntentp->mnt_dir))
continue;
if (advsum > 0) {
prdat("Clients", advsum * RFS_BKSIZE);
prdat("TOTAL",
local * stbuf.st_blksize + advsum * RFS_BKSIZE);
}
}
endmntent(mntfilep); /* close MOUNTED */
for (i = 1; i < argc; i++)
if (argv[i][0] != '\0') {
exitcode = 2;
printf("'%s' not found\n", argv[i]);
}
exit(exitcode);
/* NOTREACHED */
}
#define EQ(X, Y) !strcmp(X, Y)
/*
* wantprint returns nonzero if either r1 or r2 is requested to be
* printed in argv[]. It also returns nonzero if argc == 1
* (no argument means to print everything).
*/
wantprint(argc, argv, r1, r2)
int argc;
char *argv[], *r1, *r2;
{
int found, i;
found = 0;
if (argc == 1)
return (1); /* the default is "print everything" */
for (i = 0; i < argc; i++)
if (EQ(r1, argv[i]) || EQ(r2, argv[i])) {
argv[i][0] = '\0'; /* done with this arg */
found++; /* continue scan to find */
} /* duplicate requests */
return (found);
}
/*
* prdat print string s followed by number of kilobytes in nbyte.
*/
prdat(s, nbyte)
char *s;
long nbyte;
{
printf("\t\t\t%15s %10d KB\n", s, nbyte / 1024);
}
/*
* isinfs returns 1 if advdir is in the file system mntentp.
*/
isinfs(mntentp, advdir)
struct mntent *mntentp;
char *advdir;
{
struct stat mpstat, advstat;
stat(mntentp->mnt_dir, &mpstat);
stat(advdir, &advstat);
if (advstat.st_dev == mpstat.st_dev)
return (1);
return (0);
}
/*
* getline reads up to 'len' characters from the file fp (/etc/advtab)
* and toss remaining characters up to a newline. If the last line
* is not terminated with a '\n', the funcion returns failure (0)
* even if some data was read. Since the adv(1M) command always
* terminates the lines with a '\n', this is not a problem.
*/
getline(str, len, fp)
char *str;
int len;
FILE *fp;
{
int i, c;
char *s;
s = str;
i = 1;
for (;;) {
c = getc(fp);
switch (c) {
case EOF:
*s = '\0';
return (0);
case '\n':
*s = '\0';
return (1);
default:
if (i < len)
*s++ = c;
i++;
}
}
}
/*
* loadadvl loads resource and directory fields from string s to
* (struct advlst *)advx.
*/
loadadvl(s, advx)
char *s;
struct advlst *advx;
{
int i;
i = 0;
while (isspace(*s)) s++;
while (!isspace(*s) && (i < SZ_RES)) advx->resrc[i++] = *s++;
advx->resrc[i] = '\0';
i = 0;
while (isspace(*s)) s++;
while (!isspace(*s) && (i < SZ_MACH+SZ_PATH+1)) advx->dir[i++] = *s++;
advx->dir[i] = '\0';
}