X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/9bd38ba8a77149ce4c1fc5d5d91977214c4e2a42..0ea8b4459c9719d6ad0055f7b7e65276a0f2492d:/usr/src/usr.bin/fstat/fstat.c diff --git a/usr/src/usr.bin/fstat/fstat.c b/usr/src/usr.bin/fstat/fstat.c index 53291c4052..decfab2ac2 100644 --- a/usr/src/usr.bin/fstat/fstat.c +++ b/usr/src/usr.bin/fstat/fstat.c @@ -1,736 +1,637 @@ /* * Copyright (c) 1987 Regents of the University of California. - * All rights reserved. The Berkeley software License Agreement - * specifies the terms and conditions for redistribution. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef lint char copyright[] = "@(#) Copyright (c) 1987 Regents of the University of California.\n\ All rights reserved.\n"; -#endif not lint +#endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)fstat.c 5.4 (Berkeley) %G%"; -#endif not lint +static char sccsid[] = "@(#)fstat.c 5.16 (Berkeley) %G%"; +#endif /* not lint */ /* * fstat */ -#include -#include -#include -#include +#include + #include -#include -#include #include #include #include -#include -#include #include #include -#include -#include #include #include #include #include #include +#include +#include +#define KERNEL +#include +#undef KERNEL #include #include #include -#include -#define KERNEL -#include -#undef KERNEL +#include +#include +#include +#include +#include "pathnames.h" -#ifdef ULTRIX - /* UFS -> GFS */ +#ifdef ULTRIX + /* UFS -> GFS */ # define inode gnode # define x_iptr x_gptr # define i_dev g_dev # define i_number g_number # define i_mode g_mode # define i_size g_size -#endif ULTRIX +#endif -char *emalloc(); -char *getinetproto(); +#define TEXT -2 +#define WD -1 -#define vprintf if (vflg) printf -#define WD -1 -#define TEXT -2 - -int pcbpf, nswap, kmem, mem, swap, uid, pid; -int uflg, fflg, vflg, nproc, pflg; -int sflg, kflg; /*4.2*/ -int argaddr; /*4.2*/ - -struct devs { +typedef struct devs { struct devs *next; dev_t dev; int inum; -} devs; - -#define clear(x) ((int)x & 0x7fffffff) + char *name; +} DEVS; +DEVS *devs; -struct pte *Sysmap = 0; - -struct nlist nl[] = { +static struct nlist nl[] = { { "_proc" }, #define X_PROC 0 { "_Usrptmap" }, #define X_USRPTMA 1 - { "_usrpt" }, -#define X_USRPT 2 - { "_nswap" }, -#define X_NSWAP 3 { "_nproc" }, -#define X_NPROC 4 - { "_Sysmap" }, -#define SSYSMAP 5 - { "_Syssize" }, -#define SSYSSIZE 6 +#define X_NPROC 2 + { "_usrpt" }, +#define X_USRPT 3 { "" }, }; -char *stypename[] = { - "unused", /* 0 */ - "stream", /* 1 */ - "dgram", /* 2 */ - "raw", /* 3 */ - "rdm", /* 4 */ - "seqpak" /* 5 */ -}; -#define STYPEMAX 5 - -char *uname; - +struct proc *mproc; +struct pte *Usrptma, *usrpt; -struct proc proc[8], *mproc; /* 8 = a few, for less syscalls */ -struct pte *Usrptma, *usrpt; - -int paduser1; /* avoid hardware mem clobbering botch */ union { - struct user user; - char upages[UPAGES][NBPG]; + struct user user; + char upages[UPAGES][NBPG]; } user; -int paduser2; /* avoid hardware mem clobbering botch */ -#define u user.user -char *kmemf, *memf, *swapf, *nlistf; +extern int errno; +static int fflg, vflg; +static int kmem, mem, nproc, swap; +static char *uname; -extern int errno; -char stdoutBuf[BUFSIZ]; +off_t lseek(); main(argc, argv) -char **argv; + int argc; + char **argv; { - register int i, j; - off_t procp; - dev_t dev; - - argv++; - while (*argv) { - if (strcmp(*argv, "-v") == 0) { - vflg++; - argv++; - continue; - } - if (strcmp(*argv, "-u") == 0) { - if (uflg++) + extern char *optarg; + extern int optind; + register struct passwd *passwd; + register int pflg, pid, uflg, uid; + int ch, size; + struct passwd *getpwnam(), *getpwuid(); + long lgetw(); + char *malloc(); + + pflg = uflg = 0; + while ((ch = getopt(argc, argv, "p:u:v")) != EOF) + switch((char)ch) { + case 'p': + if (pflg++) + usage(); + if (!isdigit(*optarg)) { + fputs("fstat: -p option requires a process id.\n", stderr); usage(); - if ((uid = getuname(*(++argv))) < 0) { - fprintf(stderr, "%s: unknown user\n", *argv); - exit(1); } - argv++; - continue; - } - if (strcmp(*argv, "-f") == 0) { - fflg++; - if (getfname(*(++argv)) < 0) { - perror(*argv); + pid = atoi(optarg); + break; + case 'u': + if (uflg++) + usage(); + if (!(passwd = getpwnam(optarg))) { + fprintf(stderr, "%s: unknown uid\n", optarg); exit(1); } - argv++; - continue; + uid = passwd->pw_uid; + uname = passwd->pw_name; + break; + case 'v': /* undocumented: print read error messages */ + vflg++; + break; + case '?': + default: + usage(); } - if (strcmp(*argv, "-p") == 0) { - if (pflg++ || ((pid = Atoi(*(++argv))) <= 0)) { - usage(); - perror(*argv); - exit(1); - } - argv++; - continue; + if (*(argv += optind)) { + for (; *argv; ++argv) { + if (getfname(*argv)) + fflg = 1; } - /* otherwise its a file argument */ - fflg++; - if (getfname(*argv) < 0) { - perror(*argv); + if (!fflg) /* file(s) specified, but none accessable */ exit(1); - } - argv++; - continue; - } - - if (chdir("/dev") < 0) { - perror("/dev"); - exit(1); } - printf("USER\t CMD\t PID FD\tDEVICE\tINODE\t SIZE\tTYPE\n"); openfiles(); - getkvars(); - procp = getw((off_t) nl[X_PROC].n_value); - nproc = getw((off_t) nl[X_NPROC].n_value); - for (i=0; i 8) - j = 8; - j *= sizeof (struct proc); - if (read(kmem, (char *) proc, j) != j) - cantread("proc table", kmemf); - procp += j; - for (j = j / sizeof (struct proc) - 1; j >= 0; j--) { - mproc = &proc[j]; - if (mproc->p_stat == 0) - continue; - doproc(); - } - } - exit(0); -} -long -getw(loc) - off_t loc; -{ - long word; - - lseek(kmem, (long) loc, 0); - if (read(kmem, (char *) &word, sizeof (word)) != sizeof (word)) - vprintf("error reading kmem at %x\n", loc); - return (word); -} - -openfiles() -{ - - kmemf = "kmem"; - kmem = open(kmemf, 0); - if (kmem < 0) { - perror(kmemf); - exit(1); - } - memf = "mem"; - mem = open(memf, 0); - if (mem < 0) { - perror(memf); - exit(1); - } - swapf = "drum"; - swap = open(swapf, 0); - if (swap < 0) { - perror(swapf); + if (nlist(_PATH_UNIX, nl) == -1 || !nl[0].n_type) { + fprintf(stderr, "%s: No namelist\n", _PATH_UNIX); exit(1); } -} - -getkvars() -{ - nlistf = "/vmunix"; - nlist(nlistf, nl); - if (nl[0].n_type == 0) { - fprintf(stderr, "%s: No namelist\n", nlistf); - exit(1); - } - Usrptma = (struct pte *) nl[X_USRPTMA].n_value; + Usrptma = (struct pte *)nl[X_USRPTMA].n_value; usrpt = (struct pte *) nl[X_USRPT].n_value; - lseek(kmem, (long) nl[X_NSWAP].n_value, 0); - if (read(kmem, (char *) &nswap, sizeof (nswap)) != sizeof (nswap)) { - cantread("nswap", kmemf); + nproc = (int)lgetw((off_t)nl[X_NPROC].n_value); + + (void)lseek(kmem, lgetw((off_t)nl[X_PROC].n_value), L_SET); + size = nproc * sizeof(struct proc); + if ((mproc = (struct proc *)malloc((u_int)size)) == NULL) { + fprintf(stderr, "fstat: out of space.\n"); exit(1); } -} - -cantread(what, fromwhat) - char *what, *fromwhat; -{ - - vprintf("fstat: error reading %s from %s", what, fromwhat); -} + if (read(kmem, (char *)mproc, size) != size) + rerr1("proc table", _PATH_KMEM); -doproc() -{ - struct passwd *getpwuid(); - - - if (uflg && mproc->p_uid != uid) - return; - if (pflg && mproc->p_pid != pid) - return; - if (mproc->p_stat != SZOMB && getu() == 0) - return; - uname = getpwuid(mproc->p_uid)->pw_name; - dotext(); - getf(); + printf("USER\t CMD\t PID FD\tDEVICE\tINODE\t SIZE TYPE%s\n", + fflg ? " NAME" : ""); + for (; nproc--; ++mproc) { + if (mproc->p_stat == 0) + continue; + if (pflg && mproc->p_pid != pid) + continue; + if (uflg) { + if (mproc->p_uid != uid) + continue; + } + else + uname = (passwd = getpwuid(mproc->p_uid)) ? + passwd->pw_name : "unknown"; + if (mproc->p_stat != SZOMB && getu() == 0) + continue; + dotext(); + readf(); + } + exit(0); } +static getu() { struct pte *pteaddr, apte; struct pte arguutl[UPAGES+CLSIZE]; register int i; - int ncl, size; + int ncl; - size = sizeof (struct user); if ((mproc->p_flag & SLOAD) == 0) { if (swap < 0) - return (0); - (void) lseek(swap, (long)dtob(mproc->p_swaddr), 0); - if (read(swap, (char *)&user.user, size) != size) { - fprintf(stderr, "ps: cant read u for pid %d from %s\n", - mproc->p_pid, swapf); - return (0); + return(0); + (void)lseek(swap, (off_t)dtob(mproc->p_swaddr), L_SET); + if (read(swap, (char *)&user.user, sizeof(struct user)) + != sizeof(struct user)) { + fprintf(stderr, "fstat: can't read u for pid %d from %s\n", mproc->p_pid, _PATH_SWAP); + return(0); } - pcbpf = 0; - argaddr = 0; - return (1); + return(1); } pteaddr = &Usrptma[btokmx(mproc->p_p0br) + mproc->p_szpt - 1]; - klseek(kmem, (long)pteaddr, 0); + (void)lseek(kmem, (off_t)pteaddr, L_SET); if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) { - printf("fstat: cant read indir pte to get u for pid %d from %s\n", - mproc->p_pid, swapf); - return (0); + printf("fstat: can't read indir pte to get u for pid %d from %s\n", mproc->p_pid, _PATH_SWAP); + return(0); } - klseek(mem, - (long)ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE) * sizeof (struct pte), - 0); + (void)lseek(mem, (off_t)ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE) + * sizeof(struct pte), L_SET); if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) { - printf("fstat: cant read page table for u of pid %d from %s\n", - mproc->p_pid, kmemf); - return (0); + printf("fstat: can't read page table for u of pid %d from %s\n", mproc->p_pid, _PATH_KMEM); + return(0); } - if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum) - argaddr = ctob(arguutl[0].pg_pfnum); - else - argaddr = 0; - pcbpf = arguutl[CLSIZE].pg_pfnum; - ncl = (size + NBPG*CLSIZE - 1) / (NBPG*CLSIZE); + ncl = (sizeof(struct user) + NBPG*CLSIZE - 1) / (NBPG*CLSIZE); while (--ncl >= 0) { i = ncl * CLSIZE; - klseek(mem, (long)ctob(arguutl[CLSIZE+i].pg_pfnum), 0); + (void)lseek(mem, (off_t)ctob(arguutl[CLSIZE+i].pg_pfnum), L_SET); if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) { - printf("fstat: cant read page %d of u of pid %d from %s\n", - arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid, memf); + printf("fstat: can't read page %u of u of pid %d from %s\n", arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid, _PATH_MEM); return(0); } } - return (1); + return(1); } -#define NMAX 8 -#define NUID 2048 - +static dotext() { - struct text text; + struct text text; - lseek(kmem, (long) mproc->p_textp, 0); + (void)lseek(kmem, (off_t)mproc->p_textp, L_SET); if (read(kmem, (char *) &text, sizeof(text)) != sizeof(text)) { - cantread("text table", kmemf); - return; - } - if (text.x_flag == 0) + rerr1("text table", _PATH_KMEM); return; - itrans(DTYPE_INODE, text.x_iptr, TEXT); -} - -char *itypename[] = { - "unk", -#define UNK 0 /* unknown */ - "chr", -#define CHR 1 - "dir", -#define DIR 2 - "blk", -#define BLK 3 - "reg", -#define REG 4 - "lnk", -#define LNK 5 - "soc" -#define SOC 6 -}; - -itype(mode) -{ - switch(mode&IFMT) { - case IFCHR: - return(CHR); - case IFDIR: - return(DIR); - case IFBLK: - return(BLK); - case IFREG: - return(REG); - case IFLNK: - return(LNK); - case IFSOCK: - return(SOC); - default: - return(0); } + if (text.x_flag) + itrans(DTYPE_INODE, text.x_iptr, TEXT); } +static itrans(ftype, g, fno) -struct inode *g; /* if ftype is inode */ + int ftype, fno; + struct inode *g; /* if ftype is inode */ { - struct inode inode; - dev_t idev; - int type; - char *comm; - - if (g == 0 && ! fflg) { - goto skip; - } - lseek(kmem, (long) g, 0); - if (read(kmem, (char *) &inode, sizeof(inode)) - != sizeof(inode)) { - vprintf("error %d reading inode at %x from kmem\n", errno, g); - return; + struct inode inode; + dev_t idev; + char *comm, *itype(); + char *name = (char *)NULL; /* set by devmatch() on a match */ + + if (g || fflg) { + (void)lseek(kmem, (off_t)g, L_SET); + if (read(kmem, (char *)&inode, sizeof(inode)) != sizeof(inode)) { + rerr2(errno, (int)g, "inode"); + return; + } + idev = inode.i_dev; + if (fflg && !devmatch(idev, inode.i_number, &name)) + return; } - idev = inode.i_dev; - if (fflg && !devmatch(idev, inode.i_number)) - return; -skip: if (mproc->p_pid == 0) comm = "swapper"; else if (mproc->p_pid == 2) comm = "pagedaemon"; else - comm = u.u_comm; + comm = user.user.u_comm; printf("%-8.8s %-10.10s %5d ", uname, comm, mproc->p_pid); - if (fno == WD) - printf(" wd"); - else if (fno == TEXT) - printf("text"); - else + + switch(fno) { + case WD: + printf(" wd"); break; + case TEXT: + printf("text"); break; + default: printf("%4d", fno); + } if (g == 0) { printf("* (deallocated)\n"); return; } - if (ftype == DTYPE_INODE) { - type = itype(inode.i_mode); /* determine inode type */ - printf("\t%2d, %2d\t%5d\t%6d\t%3s\n", major(inode.i_dev), minor(inode.i_dev), - inode.i_number, type == SOC?0:inode.i_size, itypename[type]); - } - else if (ftype == DTYPE_SOCKET) { + switch(ftype) { + case DTYPE_INODE: + printf("\t%2d, %2d\t%5lu\t", + major(inode.i_dev), + minor(inode.i_dev), inode.i_number + ); + switch(inode.i_mode & IFMT) { + case IFSOCK: + printf(" 0\t"); + break; + case IFCHR: + printf("%2d, %2d\t", major(inode.i_rdev), minor(inode.i_rdev)); + break; + default: + printf("%6ld\t", inode.i_size); + } + printf("%3s %s\n", itype(inode.i_mode), name ? name : ""); + break; + case DTYPE_SOCKET: socktrans((struct socket *)g); - } + break; #ifdef DTYPE_PORT - else if (ftype == DTYPE_PORT) { + case DTYPE_PORT: printf("* (fifo / named pipe)\n"); - } -#endif DTYPE_PORT - else { + break; +#endif + default: printf("* (unknown file type)\n"); } } -devmatch(idev, inum) -dev_t idev; -int inum; + +static char * +itype(mode) + u_short mode; { - struct devs *d = &devs; - for (d = d->next; d; d = d->next) { - if (d->dev == idev) { - if (d->inum == 0) - return(1); - if (d->inum == inum) - return(1); - } + switch(mode & IFMT) { + case IFCHR: + return("chr"); + case IFDIR: + return("dir"); + case IFBLK: + return("blk"); + case IFREG: + return("reg"); + case IFLNK: + return("lnk"); + case IFSOCK: + return("soc"); + default: + return("unk"); } - return(0); + /*NOTREACHED*/ } +static socktrans(sock) -struct socket *sock; + struct socket *sock; { - struct socket so; - struct protosw proto; - struct domain dom; - char dname[32]; /* domain name, e.g. "inet" */ - char c; - char *cp; - int i; - char *stype; - struct inpcb inpcb; - struct unpcb unpcb; + static char *stypename[] = { + "unused", /* 0 */ + "stream", /* 1 */ + "dgram", /* 2 */ + "raw", /* 3 */ + "rdm", /* 4 */ + "seqpak" /* 5 */ + }; +#define STYPEMAX 5 + struct socket so; + struct protosw proto; + struct domain dom; + struct inpcb inpcb; + struct unpcb unpcb; + int len; + char dname[32], *strcpy(); /* fill in socket */ - lseek(kmem, (long) sock, 0); - if (read(kmem, (char *) &so, sizeof(struct socket)) - != sizeof(struct socket)){ - vprintf("error %d reading socket at %x from kmem\n", errno, sock); + (void)lseek(kmem, (off_t)sock, L_SET); + if (read(kmem, (char *)&so, sizeof(struct socket)) + != sizeof(struct socket)) { + rerr2(errno, (int)sock, "socket"); return; } /* fill in protosw entry */ - lseek(kmem, (long) so.so_proto, 0); - if (read(kmem, (char *) &proto, sizeof(struct protosw)) - != sizeof(struct protosw)){ - vprintf("error %d reading protosw at %x from kmem\n", errno, so.so_proto); + (void)lseek(kmem, (off_t)so.so_proto, L_SET); + if (read(kmem, (char *)&proto, sizeof(struct protosw)) + != sizeof(struct protosw)) { + rerr2(errno, (int)so.so_proto, "protosw"); return; } /* fill in domain */ - lseek(kmem, (long) proto.pr_domain, 0); - if (read(kmem, (char *) &dom, sizeof(struct domain)) - != sizeof(struct domain)){ - vprintf("error %d reading domain at %x from kmem\n", errno, proto.pr_domain); + (void)lseek(kmem, (off_t)proto.pr_domain, L_SET); + if (read(kmem, (char *)&dom, sizeof(struct domain)) + != sizeof(struct domain)) { + rerr2(errno, (int)proto.pr_domain, "domain"); return; } - /* Grab domain name */ - lseek(kmem, (long) dom.dom_name, 0); - for (cp=dname, i=0; i < 30; i++, cp++) { /* 30 leaves room for null byte */ - if (read(kmem, (char *)&c, sizeof(char)) != sizeof(char)) { - vprintf("error %d reading char at %x from kmem\n", errno, dom.dom_name+i); - break; + /* + * grab domain name + * kludge "internet" --> "inet" for brevity + */ + if (dom.dom_family == AF_INET) + (void)strcpy(dname, "inet"); + else { + (void)lseek(kmem, (off_t)dom.dom_name, L_SET); + if ((len = read(kmem, dname, sizeof(dname) - 1)) < 0) { + rerr2(errno, (int)dom.dom_name, "char"); + dname[0] = '\0'; } - if (c == '\0') - break; - *cp = c; + else + dname[len] = '\0'; } - *cp='\0'; - /* kludge "internet" --> "inet" for brevity */ - if (dom.dom_family == AF_INET) - strcpy(dname, "inet"); - - if (so.so_type < 1 || so.so_type > STYPEMAX) { - - stype = emalloc(10); - (void)sprintf(stype,"unk%d", so.so_type); - } else - stype = stypename[so.so_type]; - /* print sock type, sock state, and domain name */ - printf("* (%s %s %x", dname, stype, so.so_state); + if ((u_short)so.so_type > STYPEMAX) + printf("* (%s unk%d %x", dname, so.so_type, so.so_state); + else + printf("* (%s %s %x", dname, stypename[so.so_type], + so.so_state); /* - * protocol specific formating + * protocol specific formatting * - * Try to find interesting things to print. For tcp, the - * interesting thing is the address of the tcpcb, for udp - * and others, just the inpcb (socket pcb). For unix - * domain, its the address of the socket pcb and the address of - * the connected pcb (if connected). Otherwise just print - * the protocol number and address of the socket itself. The - * idea is not to duplicate netstat, but to make available - * enough information for further analysis. + * Try to find interesting things to print. For tcp, the interesting + * thing is the address of the tcpcb, for udp and others, just the + * inpcb (socket pcb). For unix domain, its the address of the socket + * pcb and the address of the connected pcb (if connected). Otherwise + * just print the protocol number and address of the socket itself. + * The idea is not to duplicate netstat, but to make available enough + * information for further analysis. */ - if (dom.dom_family == AF_INET) { - /* print name of protocol number */ - printf(" %s", getinetproto(proto.pr_protocol)); + switch(dom.dom_family) { + case AF_INET: + getinetproto(proto.pr_protocol); if (proto.pr_protocol == IPPROTO_TCP ) { if (so.so_pcb) { - lseek(kmem, (long) so.so_pcb, 0); - if (read(kmem, (char *) &inpcb, sizeof(struct inpcb)) + (void)lseek(kmem, (off_t)so.so_pcb, L_SET); + if (read(kmem, (char *)&inpcb, sizeof(struct inpcb)) != sizeof(struct inpcb)){ - vprintf("error %d reading inpcb at %x from kmem\n", - errno, so.so_pcb); + rerr2(errno, (int)so.so_pcb, "inpcb"); return; } - printf(" %x", inpcb.inp_ppcb); + printf(" %x", (int)inpcb.inp_ppcb); } - } else if (so.so_pcb) { - printf(" %x", so.so_pcb); } - } else if (dom.dom_family == AF_UNIX) { + else if (so.so_pcb) + printf(" %x", (int)so.so_pcb); + break; + case AF_UNIX: /* print address of pcb and connected pcb */ if (so.so_pcb) { - printf(" %x", so.so_pcb); - lseek(kmem, (long) so.so_pcb, 0); - if (read(kmem, (char *) &unpcb, sizeof(struct unpcb)) + printf(" %x", (int)so.so_pcb); + (void)lseek(kmem, (off_t)so.so_pcb, L_SET); + if (read(kmem, (char *)&unpcb, sizeof(struct unpcb)) != sizeof(struct unpcb)){ - vprintf("error %d reading unpcb at %x from kmem\n", - errno, so.so_pcb); + rerr2(errno, (int)so.so_pcb, "unpcb"); return; } if (unpcb.unp_conn) { - char shoconn[4]; *shoconn = 0; + char shoconn[4], *cp; + + cp = shoconn; if (!(so.so_state & SS_CANTRCVMORE)) - strcat(shoconn, "<"); - strcat(shoconn,"-"); + *cp++ = '<'; + *cp++ = '-'; if (!(so.so_state & SS_CANTSENDMORE)) - strcat(shoconn, ">"); - printf(" %s %x", shoconn, unpcb.unp_conn); + *cp++ = '>'; + *cp = '\0'; + printf(" %s %x", shoconn, (int)unpcb.unp_conn); } } - } else { + break; + default: /* print protocol number and socket address */ - printf(" %d %x", proto.pr_protocol, sock); + printf(" %d %x", proto.pr_protocol, (int)sock); } printf(")\n"); } -char * +/* + * getinetproto -- + * print name of protocol number + */ +static getinetproto(number) + int number; { - char *cp; + char *cp; switch(number) { - case 0: return("ip"); - case 1: return("icmp"); - case 2: return("ggp"); - case 6: return("tcp"); - case 8: return("egp"); - case 12: return("pup"); - case 17: return("udp"); - case 22: return("idp"); - case 255: return("raw"); + case IPPROTO_IP: + cp = "ip"; break; + case IPPROTO_ICMP: + cp ="icmp"; break; + case IPPROTO_GGP: + cp ="ggp"; break; + case IPPROTO_TCP: + cp ="tcp"; break; + case IPPROTO_EGP: + cp ="egp"; break; + case IPPROTO_PUP: + cp ="pup"; break; + case IPPROTO_UDP: + cp ="udp"; break; + case IPPROTO_IDP: + cp ="idp"; break; + case IPPROTO_RAW: + cp ="raw"; break; default: - (void)sprintf(emalloc(16),"%d",number); - return(cp); - } -} - -char * -emalloc(size) -{ - char *cp; - cp = (char *)malloc(size); - if (cp < 0) { - fprintf(stderr,"Out of space.\n"); - exit(1); + printf(" %d", number); + return; } - return(cp); + printf(" %s", cp); } -struct file * -getf() +static +readf() { - int i; - struct file file; + struct file lfile; + int i; - itrans(DTYPE_INODE, u.u_cdir, WD); + itrans(DTYPE_INODE, user.user.u_cdir, WD); for (i = 0; i < NOFILE; i++) { - if (u.u_ofile[i] == 0) + if (user.user.u_ofile[i] == 0) continue; - lseek(kmem, (long) u.u_ofile[i], 0); - if (read(kmem, (char *) &file, sizeof(file)) != sizeof(file)) { - cantread("file", kmemf); + (void)lseek(kmem, (off_t)user.user.u_ofile[i], L_SET); + if (read(kmem, (char *)&lfile, sizeof(lfile)) + != sizeof(lfile)) { + rerr1("file", _PATH_KMEM); continue; } - /*printf("flag: %x count: %x ",file.f_flag, file.f_count); - /*fflush(stdout); - */ - itrans(file.f_type, file.f_data, i); + itrans(lfile.f_type, (struct inode *)lfile.f_data, i); } } -usage() +static +devmatch(idev, inum, name) + dev_t idev; + ino_t inum; + char **name; { - fputs("usage: fstat [-u user] [-f filename] [-p pid]\n", stderr); - exit(1); -} + register DEVS *d; -getuname(uname) -char *uname; -{ - struct passwd *passwd, *getpwnam(); - - if ((passwd = getpwnam(uname)) == NULL) - return(-1); - return(passwd->pw_uid); + for (d = devs; d; d = d->next) + if (d->dev == idev && (d->inum == 0 || d->inum == inum)) { + *name = d->name; + return(1); + } + return(0); } +static getfname(filename) -char *filename; + char *filename; { - struct stat statbuf; - struct devs *d, *oldd; - dev_t dev; - int inum; + struct stat statbuf; + DEVS *cur; + char *malloc(); - if (stat(filename, &statbuf) != 0) - return(-1); + if (stat(filename, &statbuf)) { + fprintf(stderr, "fstat: %s: %s\n", strerror(errno), filename); + return(0); + } + if ((cur = (DEVS *)malloc(sizeof(DEVS))) == NULL) { + fprintf(stderr, "fstat: out of space.\n"); + exit(1); + } + cur->next = devs; + devs = cur; - /* - * if file is block special, look for open files on it - */ + /* if file is block special, look for open files on it */ if ((statbuf.st_mode & S_IFMT) != S_IFBLK) { - inum = statbuf.st_ino; - dev = statbuf.st_dev; - } else { - inum = 0; - dev = statbuf.st_rdev; + cur->inum = statbuf.st_ino; + cur->dev = statbuf.st_dev; + } + else { + cur->inum = 0; + cur->dev = statbuf.st_rdev; } - for (d = oldd = &devs; d; oldd = d, d = d->next) - ; - d = (struct devs *)emalloc(sizeof(struct devs)); - oldd->next = d; - d->next = 0; - d->dev = dev; - d->inum = inum; + cur->name = filename; + return(1); } -Atoi(p) -register char *p; +static +openfiles() { - register int n = 0; + if ((kmem = open(_PATH_KMEM, O_RDONLY, 0)) < 0) { + (void)fprintf(stderr, "fstat: %s: %s\n", + strerror(errno), _PATH_KMEM); + exit(1); + } + if ((mem = open(_PATH_MEM, O_RDONLY, 0)) < 0) { + (void)fprintf(stderr, "fstat: %s: %s\n", + strerror(errno), _PATH_MEM); + exit(1); + } + if ((swap = open(_PATH_SWAP, O_RDONLY, 0)) < 0) { + (void)fprintf(stderr, "fstat: %s: %s\n", + strerror(errno), _PATH_SWAP); + exit(1); + } +} - while(*p >= '0' && *p <= '9') - n = n*10 + *p++ - '0'; - return(*p ? -n : n); +static +rerr1(what, fromwhat) + char *what, *fromwhat; +{ + if (vflg) + printf("error reading %s from %s", what, fromwhat); } -klseek(fd, loc, off) - int fd; - long loc; - int off; +static +rerr2(err, address, what) + int err, address; + char *what; { - static int sizeSysmap; + if (vflg) + printf("error %d reading %s at %x from %s\n", + errno, what, address, _PATH_KMEM); +} - if( kflg && Sysmap == 0) - {/* initialize Sysmap */ +static long +lgetw(loc) + off_t loc; +{ + long word; - sizeSysmap = nl[SSYSSIZE].n_value * sizeof( struct pte); - Sysmap = (struct pte *)calloc( sizeSysmap, 1); - lseek( kmem, clear( nl[SSYSMAP].n_value), 0); - if( read( kmem, Sysmap, sizeSysmap) != sizeSysmap) - { - printf( "Cant read system page table\n"); - exit(1); - } - } - if( kflg && (loc&0x80000000)) - {/* do mapping for kernel virtual addresses */ - struct pte *ptep; - - loc &= 0x7fffffff; - ptep = &Sysmap[btop(loc)]; - if( (char *)ptep - (char *)Sysmap > sizeSysmap) - { - printf( "no system pte for %s\n", loc); - exit(1); - } - if( ptep->pg_v == 0) - { - printf( "system pte invalid for %x\n", loc); - exit(1); - } - loc = (off_t)((loc&PGOFSET) + ptob(ptep->pg_pfnum)); - } - (void) lseek(fd, (long)loc, off); + (void)lseek(kmem, (off_t)loc, L_SET); + if (read(kmem, (char *)&word, sizeof(word)) != sizeof(word)) + rerr2(errno, (int)loc, "word"); + return(word); +} + +static +usage() +{ + fputs("usage: fstat [-u user] [-p pid] [filename ...]\n", stderr); + exit(1); }