home *** CD-ROM | disk | FTP | other *** search
- /* ofiles.c
- *
- * ofiles [-D ] [-k nlist core] [-n] [-p] [-f|d|m] args
- *
- * Show owner of open file or network connection.
- *
- * Reports owner, process ID, access type, command and inode number.
- *
- * -D select verbose debugging output
- *
- * -k nlist core specifies alternative name list and core files
- * (DYNIX only)
- *
- * -n interpret names as network connection, hexadecimal
- * Protocol Control Block (PCB) addresses
- *
- * -p gives brief (pids only) report
- *
- * -i print inode number (ommitted by default)
- *
- * -m force argument to be considered as a mount point
- *
- * -f force argument to be considered as a regular file
- *
- * -d force argument to be considered as a device
- *
- * names file names, file system names or network connection
- * PCB addresses
- *
- * Stat each file or file system argument and scan the process table,
- * looking for a match in the associated user structure's file lists.
- *
- * Follow each PCB arg to the Internet Protocol Control Block (INPCB),
- * thence to the socket; then scan the file table to find the file
- * structure address associated with the socket; finally, scan the
- * process table, looking for a nacth in the associated user structure's
- * file lists.
- *
- * Now handles remote NFS files.
- */
-
- /*
- * Authors:
- *
- * The orignal author is:
- *
- * C. Spencer
- *
- * Contributors include:
- *
- * Michael Ditto
- * Tom Dunigan
- * Alexander Dupuy
- * Greg Nebbett
- * Richard Tobin
- *
- * From the Purdue University Computing Center:
- *
- * Mike Spitzer converted to 4.3BSD, DYNIX 3.0.1[24]
- * Ray Moody SunOS 4.0 and ULTRIX 2.2
- * Vik Lall
- *
- * Vic Abell added socket option and removed lint
- *
- * From INRIA Rocquencourt (France)
- * Robert Ehrlich completely revisited in order to:
- * - make it work on DECSTATIONs 3100, Pyramid
- * OSX, Sony NewsOS 3.5 4.0 risc 68k
- * - make it work on pre 4.0 SunOS (yes,
- * my workstation runs 3.5 !)
- * - find executable text files, mapped files
- * under SunOS 4.0
- * - make it work on remote NFS file-systems
- * - simplify
- */
-
- #ifndef lint
- static char rcsid[]="$Header: /usr/src/local/etc/ofiles/RCS/ofiles.c,v 1.8 89/03/21 12:29:30 abe Exp Locker: abe $";
- #endif /* lint */
-
- #include <sys/param.h>
- #include <sys/dir.h>
- #include <sys/signal.h>
- #if ! BSD || BSD < 43
- #include <sys/time.h>
- #endif
- #include <sys/user.h>
-
- #ifdef sun
- #if ! defined _user_h && ! defined _sys_user_h
- #define SunOS 3
- #else
- #define SunOS 4
- #ifdef _sys_user_h
- #define SunOSrel 1
- #else
- define SunOSrel 0
- #endif /* _sys_user_h */
- #endif /* _user_h */
- #endif /* sun */
-
- #ifdef sequent
- #define DYNIX
- #endif
-
- #if defined DYNIX || defined sun || defined pyr || defined sony
- #define NFS
- #endif
-
- #ifdef DYNIX
- #define KERNEL
- #include <sys/file.h>
- #include <sys/vnode.h>
- #include <sys/inode.h>
- #undef KERNEL
- #else
- #define KERNEL
- #include <sys/file.h>
- #ifndef NFS
- #include <sys/inode.h>
- #include <sys/mount.h>
- #undef KERNEL
- #else
- #undef KERNEL
- #include <sys/vfs.h>
- #include <rpc/types.h>
- #include <sys/vnode.h>
- #include <ufs/inode.h>
- #include <nfs/nfs.h>
- #include <nfs/rnode.h>
- #include <ufs/mount.h>
- #endif
- #endif
-
- #include <sys/stat.h>
- #ifndef pyr
- #include <machine/pte.h>
- #else
- #include <sys/pte.h>
- #include <sys/immu.h>
- #endif pyr
-
- #if !defined(ultrix) && !defined(sun) && ! defined DYNIX && ! defined pyr
- #include <machine/machparam.h>
- #endif
- #include <sys/proc.h>
- #include <nlist.h>
- #ifndef O_NDELAY
- #include <sys/fcntl.h>
- #endif
- #include <pwd.h>
- #include <fstab.h>
- #include <sys/vmmac.h>
- #include <stdio.h>
-
- #ifdef NFS
- struct snode {
- struct snode *s_next;
- struct vnode s_vnode;
- struct vnode *s_realvp;
- struct vnode *s_bdevvp;
- u_short s_flag;
- dev_t s_dev;
- };
- #endif NFS
-
- #if defined sun && SunOS >= 4
- #include <kvm.h>
- kvm_t *kd;
- #endif
-
- #ifdef _nfs_rnode_h /* _nfs_rnode_h only defined on recent versions of NFS */
- #define r_nfsattr r_attr /* the names of these fields changed vith new version of NFS */
- #define nfsfattr vattr
- #define na_nodeid va_nodeid
- #endif /* NFS version */
-
- #ifdef ultrix
- #include <sys/gnode.h>
- #include <sys/gnode_common.h>
- #include <machine/param.h>
- #define i_number g_number
- #endif
-
- #include <sys/socket.h>
- #include <sys/socketvar.h>
- #include <net/route.h>
- #include <netinet/in.h>
- #include <netinet/in_pcb.h>
- #include <netinet/tcp.h>
- #include <netinet/tcp_fsm.h>
- #include <netinet/tcp_timer.h>
- #include <netinet/tcp_var.h>
-
- #define CDIR 01
- #define OFILE 02
- #define RDIR 04
- #define SHFILE 010
- #define EXFILE 020
- #define SOCKET 040
-
- #if (! defined sun || SunOS < 4) && ! defined DYNIX && ! defined pyr
- /* no more text struct in these systems */
- #include <sys/text.h>
- #endif
-
- #ifdef pyr /* maybe for all SYS V ? */
- #undef r_lock
- #include <sys/region.h>
- #endif
- /* defines for unix BSD whitout NFS */
- #define x_ptr x_iptr
- #define node inode
- #define DTYPE_NODE DTYPE_INODE
- #define FSID struct fs *
- #define _fsid i_fs
- #define ISROOT(n) ((n)->i_number == ROOTINO)
- #define ISBDEV(n) (((n)->i_mode&IFMT) == IFBLK)
- #define ISDEV(n) (((n)->i_mode&IFMT) == IFBLK || ((n)->i_mode&IFMT) == IFCHR)
- #define TYPEWORD(n) ((n)->i_mode)
- #define TYPEBITS(m) ((m)&IFMT)
- #define NODETYPE_T unsigned short
- #define TREG IFREG
- #define TDIR IFDIR
- #define TCHR IFCHR
- #define TBLK IFBLK
-
- #ifdef ultrix
- /* defines for ultrix, i.e. DEC gfs variant of NFS */
- #undef x_ptr
- #undef node
-
- #define x_ptr x_gptr
- #define node gnode
- #undef FSID
- #define FSID struct mount *
- #define i_fs g_mp
- #undef ISROOT
- #define ISROOT(n) ((n)->g_number == ROOTINO || isroot(n))
- #define i_number g_number
- #define i_mode g_mode
- #define i_rdev g_rdev
- #undef TREG
- #undef TDIR
- #undef TCHR
- #undef TBLK
- #define TREG GFREG
- #define TDIR GFDIR
- #define TCHR GFCHR
- #define TBLK GFBLK
- #include <sys/mount.h>
- #define m_inodp m_gnodp
- #undef NFS /* ultrix implememtetion of NFS doesn't fit with my defines */
- #if defined P_DYING /* ultrix 4.1 */
- #define p_flag p_sched
- #endif /* ultrix 4.1 */
- #endif ultrix
-
- #if defined sun || defined NFS
- /* defines for unix systems with NFS a la SUN */
- #undef x_ptr
- #undef node
- #undef DTYPE_NODE
-
- #define x_ptr x_vptr
- #define node vnode
- #define DTYPE_NODE DTYPE_VNODE
-
- #undef FSID
- #undef _fsid
- #define FSID struct vfs *
- #define _fsid v_vfsp
-
- #undef ISROOT
- #undef ISBDEV
- #undef ISDEV
- #define ISROOT(n) ((n)->v_flag & VROOT)
- #define ISBDEV(n) (((n)->v_type) == VBLK)
- #define ISDEV(n) (((n)->v_type) == VBLK || ((n)->v_type) == VCHR)
-
- #undef TYPEWORD
- #undef TYPEBITS
- #undef NODETYPE_T
- #undef TREG
- #undef TDIR
- #undef TCHR
- #undef TBLK
- #define TYPEWORD(n) ((n)->v_type)
- #define TYPEBITS(m) m
- #define NODETYPE_T enum vtype
- #define TREG VREG
- #define TDIR VDIR
- #define TCHR VCHR
- #define TBLK VBLK
-
- #endif sun || NFS
-
- #define TYPE(n) (TYPEBITS(TYPEWORD(n)))
-
- typedef FSID myfsid_t;
- typedef NODETYPE_T nodetype_t;
-
- #define XFILE 0100
- #define MAPPED 0200
- #define MOUNTP 0400
-
-
- #define STR(s) "s"
-
- #if defined sun && SunOS >= 4
- #include <vm/seg_vn.h>
- #include <vm/seg.h>
- #if SunOSrel > 0
- #include <vm/hat.h>
- #endif
- #include <vm/as.h>
-
- #endif SunOS >= 4
-
- /*
- * PEEK variants:
- * KM: from /dev/kmem
- * M: from /dev/mem
- * A: 2nd arg is an array, don't take its address, take its size
- * P: 2nd arg is a pointer, don't take its address, take size of pointed data
- * E: return 0 on error instead of aborting
- */
-
- #define KMPEEK(fromwhere, intowhat) \
- (void)peek(kmem, (ls_t)(fromwhere), (char *)(&intowhat), sizeof intowhat, "intowhat", __LINE__, 0)
- #define KMAPEEK(fromwhere, intowhat) \
- (void)peek(kmem, (ls_t)(fromwhere), (char *)(intowhat), sizeof intowhat, "intowhat", __LINE__, 0)
- #define KMPPEEK(fromwhere, intowhat) \
- (void)peek(kmem, (ls_t)(fromwhere), (char *)(intowhat), sizeof *intowhat, "intowhat", __LINE__, 0)
- #define MPPEEK(fromwhere, intowhat) \
- (void)peek(mem, (ls_t)(fromwhere), (char *)(intowhat), sizeof *intowhat, "intowhat", __LINE__, 0)
- #define EKMAPEEK(fromwhere, intowhat) \
- peek(kmem, (ls_t)(fromwhere), (char *)(intowhat), sizeof intowhat, "intowhat", __LINE__, 1)
- #define EMPPEEK(fromwhere, intowhat) \
- peek(mem, (ls_t)(fromwhere), (char *)(intowhat), sizeof *intowhat, "intowhat", __LINE__, 1)
-
- #if !defined NFS && ! defined ROOTINO
- #ifdef ultrix
- #include <ufs/fs.h>
- #else
- #include <sys/fs.h>
- #endif
- #endif
-
- char *namelist;
- char *corefile;
- int k_opt = 0;
- #ifdef pyr
- int dflg = 0;
- #endif pyr
- int n_opt = 0;
-
- #if defined ultrix || ( defined sun && SunOS < 4)
- #define ls_t long
- #else
- #define ls_t off_t
- #endif
-
- #ifdef sun
- char *sprintf();
- #endif
-
- ls_t lseek(), vtophys();
-
- #ifdef ultrix
- void exit(), nlist(), perror();
- #endif
-
- int nproc; /* number of entries in proc table */
- int mem; /* fd for /dev/mem */
- int kmem;
- int swap; /* fd for /dev/swap */
- struct proc *procbase, *procNPROC;
- int ppid = -1; /* previously display PID */
-
- int pids_only = 0; /* if non-zero, only output process ids */
- int iflag = 0; /* i-numbers wanted */
-
- char *progname;
- struct nlist nl[] = {
- #ifndef mips
- #define SYM(s) STR(_/**/s)
- #else
- #define SYM(s) STR(s)
- #endif
- #define X_PROC 0
- { SYM(proc) },
- #define X_PROCNPROC 1
- { SYM(procNPROC) },
- #define X_SYSMAP 2
- { SYM(Sysmap) },
- #define SFIL 3
- { SYM(file) },
- #define SNFILE 4
- { SYM(nfile) },
- #define X_U 5
- #if sun && SunOS >= 4 && SunOSrel >= 1
- { SYM(uunix) },
- #else
- { SYM(u) },
- #endif /* SunOS >= 4.1 */
- #if defined NFS
- #define X_ROOTVFS 6
- { SYM(rootvfs) },
- #else
- #define X_MOUNT 6
- { SYM(mount) },
- #endif
- #ifdef NFS
- #define X_UFSVNOPS 7
- { SYM(ufs_vnodeops) },
- #define X_NFSVNOPS 8
- { SYM(nfs_vnodeops) },
- #define X_SPECVNOPS 9
- { SYM(spec_vnodeops) },
- #endif NFS
- { "" }
- };
-
- #if sun && SunOS >= 4 && SunOSrel >= 1
- #define U_ADDR uunix
- struct user *uunix;
- struct file **ofilep;
- struct file *ofile_arr[NOFILE];
- int nofile;
- #undef NOFILE
- #define NOFILE nofile
- #define ofile(x) ofilep[x]
- #else
- #define U_ADDR ((struct user *)(nl[X_U].n_value))
- #endif
-
- #ifdef pyr
- #define DELTA_U ((char *)u -(char *)U_ADDR)
- #define ofile(x) (((struct file **)(((char *)(u->u_ofile))+DELTA_U))[x])
- #endif
-
- #ifdef DYNIX
- #define ofile(x) u->u_lofile[x].of_file
- #undef NOFILE
- #define NOFILE u->u_nofile
- #endif
-
- #ifndef ofile
- /* normal case, "standard " unix */
- #define ofile(x) u->u_ofile[x]
- #endif /* normal case */
-
- int debug;
- char *filename, *fsname;
- struct node *argnodep, argnode;
- dev_t argdev;
- nodetype_t argtype;
-
- onalarm() {}
-
- #ifdef ultrix
-
- isroot(np)
- struct node *np;
- {
- struct node *mp;
- KMPEEK(&(np->g_mp->m_gnodp), mp);
- return (mp == argnodep);
- }
- #endif ultrix
-
- #if (defined ultrix || defined sony) && defined mips
- uread(from, to)
- unsigned int from, *to;
- {
- struct pte *paddr;
- struct proc *procp;
- #if 0
- int pte;
- #else
- struct pte pte;
- #endif
- short pid, mypid;
- mypid = getpid();
- for (procp = procbase + 2; procp < procNPROC; ++procp) {
- KMPEEK(&(procp->p_pid), pid);
- if (pid == mypid) goto found;
- }
- error("My pid is not in proc table !\n");
- found:
- KMPEEK(&(procp->p_addr), paddr);
- KMPEEK(&paddr[(from-UADDR)>>PGSHIFT], pte);
- #if 0
- MPPEEK((pte&PG_PFNUM) | (from & PGOFSET), to);
- #else
- MPPEEK((pte.pg_pfnum << PGSHIFT) | (from & PGOFSET), to);
- #endif
- }
-
-
- #endif
-
- ismountdev(s)
- char *s;
- {
- register struct fstab *fs;
-
- if ((fs = getfsspec(s)) != NULL) {
- fsname = fs->fs_file;
- return 1;
- }
- return 0;
- }
-
- getmountdev(s)
- char *s;
- {
- register struct fstab *fs;
-
- if ((fs = getfsfile(s)) != NULL)
- filename = fs->fs_spec;
- }
-
- struct proc p;
-
- ino_t inum;
- #ifdef NFS
- struct snode *vdata;
- #endif
-
- int type;
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
-
- struct user *u, *getuser();
- struct proc *procp;
- register int filen, flags;
- char *getsockfp(), *rindex();
- struct file *fp;
- int ax, err, findf, nmct;
- char *ap;
- int exitval = 0;
- struct mount *mountp;
-
- #ifdef lint
- /*
- * The following code satisfies lint for KERNEL symbols.
- * This program is lint-free under 4.3BSD, DYNIX 3.0.1[24], SunOS 4.0
- * and ULTRIX 2.2, using the lint libraries of the systems at the
- * Purdue University Computing Center.
- */
- #if !defined(ultrix) && !defined(DYNIX) && !defined(sun)
- long lintlong;
- #endif
- #ifdef ultrix
- struct nch *lintnch;
- float lintfloat;
- #endif
- #if !defined(DYNIX)
- file = fileNFILE = NULL;
- fp = file;
- fp = fileNFILE;
- nfile = 0;
- filen = nfile;
- #endif
- #if !defined(ultrix) && !defined(DYNIX) && !defined(sun)
- inode = inodeNINODE = rootdir = NULL;
- i = inode;
- i = inodeNINODE;
- i = rootdir;
- ninode = 0;
- nextinodeid = 0l;
- lintlong = nextinodeid;
- nextinodeid = lintlong;
- filen = ninode;
- #endif
- #if defined sun && SunOS >= 4
- tcp_ttl = 0;
- filen = tcp_ttl;
- #endif
- #ifdef ultrix
- nch = NULL;
- lintnch = nch;
- nch = lintnch;
- nchsize = 0;
- filen = nchsize;
- tcp_alpha = tcp_beta = 0.0;
- lintfloat = tcp_alpha;
- lintfloat = tcp_beta;
- tcp_alpha = lintfloat;
- #endif
- #endif /* lint */
-
- if ((progname = rindex(argv[0], '/')))
- progname++;
- else
- progname = argv[0];
-
- if (argc == 1) {
-
- usage:
-
- #ifdef DYNIX
- (void) fprintf(stderr,
- "usage: %s [-D ] [-k nlist core] [-n] [-p] [-d|-n|-p] names\n",
- progname);
- #else
- (void) fprintf(stderr,
- "usage: %s [-D ] [-n] [-p] [-d|-n|-p] names\n", progname);
- #endif
- (void) fprintf(stderr, "\t-D = select verbose debugging output\n");
- #ifdef DYNIX
- (void) fprintf(stderr,
- "\t-k = use specified nlist and core files\n");
- #endif
- (void) fprintf(stderr,
- "\t-n = interpret names as network connection, hexadecimal,\n");
- (void) fprintf(stderr,
- "\t Protocol Control Block (PCB) addresses, as supplied\n");
- (void) fprintf(stderr,
- "\t by netstat's -A option\n");
- (void) fprintf(stderr, "\t-p = print only process IDs\n");
- (void) fprintf(stderr,
- "\tnames = file names or PCB addresses\n");
- (void) fprintf(stderr, "\t-d\n\t-m\n\t-f force name to be considered respectiveley\n");
- (void) fprintf(stderr, "\t\t as a device, mount point or regular file\n");
- exit(exitval);
- }
-
- /* check for switches */
- for (err = 0, ax = 1; ax < argc; ax++) {
- ap = argv[ax];
- if (*ap++ != '-')
- break;
- while (*ap) {
- type = 0;
- switch (*ap++) {
-
- case 'D':
- debug = 1;
- break;
- #if defined DYNIX || defined pyr
- case 'k':
- if ((ax + 2) >= argc) {
- (void) fprintf(stderr,
- "%s: no nlist/core after -k\n",
- progname);
- err++;
- } else {
- namelist = argv[++ax];
- corefile = argv[++ax];
- k_opt = 1;
- #ifdef pyr
- if (ap[1] == 'd')
- dflg = 1;
- #endif pyr
- continue;
- }
- break;
- #endif DYNIX || pyr
- case 'n':
- n_opt++;
- break;
-
- case 'p':
- pids_only = 1;
- break;
- case 'i':
- iflag = 1;
- break;
-
- case 'm':
- case 'f':
- case 'd':
- type = ap[-1];
- break;
- default:
- (void) fprintf(stderr,
- "%s: unknown switch - %c\n",
- progname, *(ap - 1));
- err++;
- }
- }
- }
- if (ax >= argc) {
- (void) fprintf(stderr, "%s: no names specified\n", progname);
- err++;
- }
- if (err) {
- exitval = 1;
- goto usage;
- }
-
- #if defined sun && SunOS >= 4
- if ((kd = kvm_open (NULL, NULL, NULL, O_RDONLY)) == 0) {
- (void) fprintf(stderr, "%s: can't access memory: ",
- progname);
- perror ("");
- exit(1);
- }
- #endif
- if ((mem = open("/dev/mem", 0)) < 0) {
- (void) fprintf(stderr, "%s: /dev/mem: ", progname);
- perror("");
- exit(1);
- }
- if (k_opt) {
- if ((kmem = open(corefile, 0)) < 0) {
- (void) fprintf(stderr, "%s: %s: ",
- progname, corefile);
- perror("");
- exit(1);
- }
- mem = kmem;
- #ifdef pyr
- if (dflg)
- setdump();
- #endif pyr
- } else {
- if ((kmem = open("/dev/kmem", 0)) < 0) {
- (void) fprintf(stderr, "%s: /dev/kmem: ", progname);
- perror("");
- exit(1);
- }
- }
- #ifndef pyr
- if (!k_opt)
- if ((swap = open("/dev/drum", 0)) < 0) {
- (void) fprintf(stderr, "%s: /dev/drum: ", progname);
- perror("");
- exit(1);
- }
- #endif pyr
- getsyms();
-
- for (err = 0, nmct = argc - ax; ax < argc; ax++) {
- /* if -n, then arg is a PCB */
- if (n_opt) {
- if ((filename = getsockfp(argv[ax], &fp)) == NULL) {
- err++;
- continue;
- }
- fsname = "";
- } else {
- int argfd;
- char buf[100];
-
- filename = argv[ax];
- fsname = filename;
- retry:
- signal(SIGALRM,onalarm);
- alarm(1);
- argfd = open(fsname, O_RDONLY|O_NDELAY);
- alarm(0);
- if (argfd == -1) {
- extern int errno;
- extern char *sys_errlist[];
- struct stat bufstat;
- if (stat(fsname, &bufstat) != -1)
- switch (bufstat.st_mode & IFMT) {
- case IFBLK:
- argtype = TBLK;
- break;
- case IFCHR:
- argtype = TCHR;
- break;
- default:
- goto bad;
- }
- else
- goto bad;
- argdev = bufstat.st_rdev;
- type = 'd';
- goto skip;
- bad:
- (void) sprintf(buf, "open failed for %s (%s)\n", fsname, sys_errlist[errno]);
- error(buf);
-
- }
- #if defined pyr || defined sun && SunOS >= 4 && SunOSrel >=1
- #define OFILEPTR
- {
- struct file **ofp;
- #if defined sun
- KMPEEK(nl[X_U].n_value, uunix);
- #endif
- KMPEEK(&(U_ADDR->u_ofile), ofp);
- KMPEEK(ofp+argfd, fp);
- }
- #endif OFILEPTR
-
- #if defined mips && (defined ultrix || defined sony)
- /* ultrix & sony mips have no access via kmem to its own user struct ! */
- uread(&((U_ADDR->u_ofile)[argfd]), &fp);
- #endif
-
-
- #if !defined OFILEPTR && !((defined ultrix || defined sony) && defined mips)
- /* the "normal case " */
- KMPEEK(U_ADDR->u_ofile+argfd, fp);
- #endif /* normal case */
- KMPEEK(&(fp->f_data), argnodep);
- KMPEEK(argnodep, argnode);
- (void)close(argfd);
- switch(type) {
- case 0:
- if (ISROOT(&argnode)) {
- type = 'm';
- getmountdev(filename);
- } else if (ISDEV(&argnode))
- if (ismountdev(fsname)) {
- type = 'm';
- goto retry;
- } else {
- type = 'd';
- fsname = "";
- }
- else {
- type = 'f';
- fsname = "";
- }
- break;
- case 'f':
- switch(TYPE(&argnode)) {
- case TREG:
- case TDIR:
- case TCHR:
- case TBLK:
- break;
- default:
- (void)sprintf(buf,
- "invalid %s type for arg type '%c' arg %s\n",
- STR(node),
- type,
- argv[ax]);
- error(buf);
- }
- break;
- case 'm':
- if (!ISROOT(&argnode)) {
- if (ismountdev(fsname))
- goto retry;
- (void)sprintf(buf,
- "%s is not a root\n",
- fsname);
- error(buf);
- }
- if (fsname == filename)
- getmountdev(filename);
- break;
- case 'd':
- if(!ISDEV(&argnode)) {
- (void)sprintf(buf,
- "%s is not a device\n",
- filename);
- error(buf);
- }
- fsname = "";
- break;
- }
- if (type == 'd')
- #ifdef NFS
- KMPEEK(&(((struct snode *)(argnode.v_data))->s_dev), argdev);
- #else
- argdev = argnode.i_rdev;
- #endif NFS
- argtype = TYPE(&argnode);
- }
- if (iflag && type == 'f') {
- #ifdef NFS
- struct node *i;
-
- if (ISDEV(&argnode)) {
- KMPEEK(&(((struct snode *)argnode.v_data)->s_realvp), i);
- KMPEEK(&(i->v_data), vdata);
- } else {
- if ((int)argnode.v_op == nl[X_UFSVNOPS].n_value)
- KMPEEK(&(((struct inode *)argnode.v_data)->i_number), inum);
- else if ((int)argnode.v_op == nl[X_NFSVNOPS].n_value)
- KMPEEK(&(((struct rnode *)argnode.v_data)->r_nfsattr.na_nodeid), inum);
- else
- inum = 0;
- }
- #else
- inum = argnode.i_number;
- #endif
- }
- skip:
- if (! pids_only) {
- (void) printf("%s\t%s", filename, fsname);
- if (!n_opt) {
- if (type == 'f')
- if (TYPE(&argnode) == TDIR)
- (void) printf(" (directory)");
- else
- (void) printf(" (regular file)");
- else if (type == 'm')
- (void) printf(" (mount point)");
- else
- (void) printf(" (device)");
-
- }
- (void) printf("\n%-8.8s %5s %-6.6s FD %-14.14s",
- "USER", "PID", "TYPE", "CMD");
- if (!n_opt && iflag)
- (void) printf(" INODE");
- (void) printf("\n");
- }
- if (!n_opt) {
- struct node *i;
- #if defined NFS
- struct vfs *vfsp;
- KMPEEK(nl[X_ROOTVFS].n_value, vfsp);
- for (; vfsp; KMPEEK(&(vfsp->vfs_next), vfsp)) {
- KMPEEK(&(vfsp->vfs_vnodecovered), i);
- if(!i) continue;
- if (check(i, type))
- gotone(0,0,-1,MOUNTP,i);
- }
- #else
- mountp = (struct mount *)nl[X_MOUNT].n_value;
- for (;;) {
- KMPEEK(&(mountp->m_inodp), i);
- if (!i) break;
- if (check(i, type))
- gotone(0,0,-1,MOUNTP,i);
- ++mountp;
- }
- #endif NFS
- }
-
- for (procp = procbase, findf = 0; procp < procNPROC; ++procp) {
- KMPEEK(procp, p);
- flags = 0;
- if (p.p_stat == 0 || p.p_stat == SZOMB)
- continue;
- #if defined sun && SunOS >= 4
- u = kvm_getu(kd, &p);
- #if SunOSrel >= 1
- getuofiles(u, p.p_segu);
- #endif
- #else
- u = getuser(&p);
- #endif
-
- if ( u == (struct user *)NULL)
- continue;
- if (debug)
- (void) printf("pid %d uid %d cmd %s\n", p.p_pid,
- p.p_uid, u->u_comm);
- if (!n_opt) {
- struct node *txtnode;
-
- if (check(u->u_rdir, type)) {
- gotone(u, &p, -1, RDIR, u->u_rdir);
- findf++;
- }
- if (check(u->u_cdir, type)) {
- gotone(u, &p, -1, CDIR, u->u_cdir);
- findf++;
- }
- /* check text files */
- #if (! defined sun || SunOS < 4) && !defined pyr
- #ifndef DYNIX
- if (p.p_textp) {
- KMPEEK(&(p.p_textp->x_ptr), txtnode);
- if (check(txtnode, type)) {
- gotone(u, &p, -1, XFILE, txtnode);
- findf++;
- }
- }
- #endif DYNIX
- #endif
- #ifdef pyr
- {
- struct pregion *prp = p.p_region;
- struct region *rp;
- struct node *lastv = 0;
- int nreg;
-
- for (nreg = 0; nreg <= p.p_nregion; ++nreg) {
- KMPEEK(&(prp->p_reg), rp);
- KMPEEK(&(rp->r_vptr), txtnode);
- if (txtnode == lastv) continue;
- if (check(txtnode, type)) {
- gotone(u, &p, -1, XFILE, txtnode);
- findf++;
- }
- lastv = txtnode;
- }
- }
- #endif pyr
- #if defined sun && SunOS >= 4
- /* in SunOS >= 4 and DYNIX, text files are mapped files */
- if (p.p_as) {
- struct seg *segp, *segnext;
- struct segvn_data *svd;
- struct vnode *lastv = 0;
-
- KMPEEK(&(p.p_as->a_segs), segp);
- if (!segp) goto noseg;
- segnext = segp;
- do {
- KMPEEK(&((struct segvn_data *)(segnext->s_data)), svd);
- if (!svd) continue;
- KMPEEK(&(svd->vp), txtnode);
- if(txtnode == lastv) continue;
- #if defined sun
- if(((int)txtnode&0xff00000) != 0xff00000
- ) continue;
- #endif sun
- if (check(txtnode, type)) {
- gotone(u, &p, -1, MAPPED, txtnode);
- findf++;
- lastv = txtnode;
- }
-
- } while(KMPEEK(&((struct segvn_data *)(segnext->s_next)), segnext),
- segnext != segp);
- noseg: ;
- }
- #endif SunOS < 4
- }
- for (filen = 0; filen < NOFILE; filen++)
- {
- struct file f;
-
- flags = 0;
- if (n_opt) {
- if (ofile(filen) != fp)
- continue;
- } else {
- if (ofile(filen) == NULL)
- continue;
- }
-
- KMPEEK(ofile(filen), f);
-
- if (f.f_count > 0) {
- if (n_opt && f.f_type == DTYPE_SOCKET) {
- gotone(u, &p, filen, SOCKET, 0);
- findf++;
- continue;
- }
- if (f.f_type != DTYPE_NODE)
- continue;
-
- if (check((struct node *)f.f_data,
- type)) {
- flags |= OFILE;
- if (f.f_flag & FEXLOCK) {
- flags |= EXFILE;
- }
- if (f.f_flag & FSHLOCK) {
- flags |= SHFILE;
- }
- gotone(u, &p, filen, flags, (struct node *)f.f_data);
- findf++;
- }
- }
- }
- }
- if (findf)
- nmct--;
- if (! pids_only) {
- (void) printf("\n");
- (void) fflush(stdout);
- }
- }
- if (pids_only && ppid != -1) {
- (void) printf("\n");
- (void) fflush(stdout);
- }
- exitval = (err || nmct) ? 1 : 0;
- exit(exitval);
- }
-
-
- /*
- * print the name of the user owning process "p" and the pid of that process
- */
- gotone(u, p, fd, f, i)
- struct user *u;
- struct proc *p;
- int fd;
- int f;
- struct node *i;
- {
- char *ty, tybuf[8], *strcat(), *strcpy();
- struct passwd *getpwuid();
- register struct passwd *pw;
-
- /* only print pids and return */
- if (pids_only) {
- if (!p) return;
- if (ppid != p->p_pid) {
- if (ppid != -1)
- (void) printf(" ");
- (void) printf("%d", p->p_pid);
- (void) fflush(stdout);
- ppid = p->p_pid;
- }
- return;
- }
- if (p) {
- pw = getpwuid((int)p->p_uid);
- if (pw)
- (void) printf("%-8.8s ", pw->pw_name );
- else
- (void) printf("%-8d ", p->p_uid);
- (void) printf("%5d ", p->p_pid);
- if (f & OFILE) {
- (void) strcpy(tybuf, "file");
- ty = tybuf;
- if (f & SHFILE)
- (void) strcat(ty, "/s");
- else if (f & EXFILE)
- (void) strcat(ty, "/x");
- } else if (f & CDIR)
- ty = "cwd";
- else if (f & RDIR)
- ty = "rdir";
- else if (f & SOCKET)
- ty = "sock";
- #if SunOS < 4
- else if (f & XFILE)
- ty = "text";
- #else /* SunOS >= 4 */
- else if (f & MAPPED)
- ty = "mapped";
- #endif /* SunOS */
- else
- ty = "";
- } else {
- printf(" ");
- if (f & MOUNTP)
- ty = "mntpnt";
- }
- (void) printf("%-6.6s ", ty);
- if (fd >= 0)
- (void) printf("%2d ", fd);
- else
- (void) printf(" ");
- (void) printf("%-14.14s", u?u->u_comm:"");
- if (iflag && i) {
- if (type != 'f') {
- #ifdef NFS
- struct vnodeops *vopp;
-
- if (type != 'd')
- KMPEEK(&(i->v_data), vdata);
- KMPEEK(&(i->v_op), vopp);
- if ((int)vopp == nl[X_UFSVNOPS].n_value)
- KMPEEK(&(((struct inode *)vdata)->i_number), inum);
- else if ((int)vopp == nl[X_NFSVNOPS].n_value)
- KMPEEK(&(((struct rnode *)vdata)->r_nfsattr.na_nodeid), inum);
- else if ((int)vopp == nl[X_SPECVNOPS].n_value) {
- KMPEEK(&(vdata)->s_realvp, i);
- KMPEEK(&(i->v_data), vdata);
- KMPEEK(&(((struct inode *)vdata)->i_number), inum);
- } else
- inum = 0;
- #else
- KMPEEK(&(i->i_number), inum);
- #endif
- }
- printf(" %5d", inum);
- }
-
- (void) printf("\n");
- return;
- }
-
- /*
- * is [igv]node "i"
- - on the filesystem of argnode when type == 'm'
- - identical to argnode when type = 'f'
- - the same device as argnode when type == 'd'
- ?
- returns TRUE or FALSE
- */
-
-
- check(i, type)
- struct node *i;
- {
- myfsid_t fsid;
- dev_t dev;
- nodetype_t tword;
-
- if (type == 'f') return (i == argnodep);
- if (i == (struct node *)NULL)
- return 0;
- if (type == 'm') {
- KMPEEK(&(i->_fsid), fsid);
- return (argnode._fsid == fsid);
- }
- KMPEEK(&TYPEWORD(i),tword);
- if (TYPEBITS(tword) != argtype) return 0;
- #ifndef NFS
- KMPEEK(&(i->i_rdev), dev);
- #else
- KMPEEK(&(i->v_data), vdata);
- KMPEEK(&(vdata->s_dev), dev);
- #endif
- return (argdev == dev);
- }
-
-
- #if !defined(sun) || SunOS < 4
- /*
- * get user page for proc "p" from core or swap
- * return pointer to user struct
- */
- #ifdef DYNIX
- struct user *
- getuser(p)
- struct proc *p;
- {
- int btr;
- ls_t sp;
- static struct user *u = NULL;
- char *valloc();
-
- if (u == NULL) {
- if ((u = (struct user *) valloc(ctob(UPAGES))) == NULL) {
- (void) fprintf(stderr,
- "%s: can't allocate space for user structure\n", progname);
- exit(1);
- }
- }
- btr = ctob(UPAGES);
- if ((p->p_flag & SLOAD) == 0) {
- if (k_opt)
- return (struct user *)NULL;
- sp = (ls_t) dtob(p->p_swaddr);
- if (lseek(swap, sp, 0) != sp) {
- if (debug) {
- (void) fprintf(stderr,
- "%s: error seeking to swap for %d: ",
- progname, p->p_pid);
- perror("");
- }
- return (struct user *)NULL;
- }
- if (read(swap, (char*)u, btr) != btr) {
- if (debug) {
- (void) fprintf(stderr,
- "%s: error reading swap for %d: ",
- progname, p->p_pid);
- perror("");
- }
- return (struct user *)NULL;
- }
- if (debug)
- (void) printf("read swap\n");
- } else {
- KMPPEEK(p->p_uarea, u);
- }
- return u;
- }
- #endif
-
- #ifdef pyr
- struct user *
- getuser(p)
- struct proc *p;
- {
- static union uuser {
- struct user u_user;
- char u_bytes[UPAGES*NBPG];
- } uuser;
-
- if (readublk(p->p_pid, &uuser))
- return 0;
- else
- return &uuser.u_user;
- }
-
- #endif pyr
-
- #if ! defined DYNIX && ! defined pyr
- struct user *
- getuser(p)
- struct proc *p;
- {
- #define USERPAGES ((sizeof (struct user) + NBPG -1)/NBPG)
- struct pte mypgtbl[USERPAGES];
- int upage;
- ls_t sp;
- typedef struct { char bytes[NBPG] } page;
- page *up;
- static union uuser {
- struct user u_user;
- char u_bytes[USERPAGES*NBPG];
- } uuser;
- #define User uuser.u_user
-
- /* easy way */
- if ((p->p_flag & SLOAD) == 0) {
- if (k_opt)
- return (struct user *)NULL;
- #if defined ultrix && defined P_DYING /* ultrix 4.1 */
- if (p->p_smap == 0)
- return (struct user *)NULL;
- {
- struct dmap l_dmap;
- int ublkno;
- KMPEEK(p->p_smap, l_dmap);
- KMPEEK(l_dmap.dm_ptdaddr, ublkno);
- sp = (ls_t)dtob(ublkno);
- }
- #else
- sp = (ls_t)dtob(p->p_swaddr);
- #endif /* ultrix 4.1 */
- if(!peek(swap, sp, (char *)&User, sizeof(union uuser),
- "swapped user page(s)", __LINE__, -1))
- return (struct user *)NULL;
- if (debug)
- (void) printf("read swap\n");
- } else { /* boo */
- /* now get this user's page table */
- if (! EKMAPEEK(p->p_addr, mypgtbl)) {
- (void) fprintf(stderr,
- "%s: can't get mypgtbl.\n", progname);
- return (struct user *)NULL;
- }
- /* now collect various pages of u area */
- for (upage = 0, up = (page *)&User; upage < USERPAGES; upage++) {
- if(! EMPPEEK(ctob(mypgtbl[upage].pg_pfnum), up)) {
- (void) fprintf(stderr,
- "%s: can't get page %d of user area.\n",
- progname, upage);
- return(NULL);
- }
- ++up;
- }
- }
- return &User;
- }
-
- #endif /* ! DYNIX */
- #endif /* SunOS < 4 */
-
-
- /*
- * print mesg "s", don't exit if we are processing a core,
- * so that corrupt entries don't prevent further uncorrupted
- * entries from showing up.
- */
- error(s)
- char *s;
- {
- if (s && !k_opt)
- (void) fprintf(stderr, "%s: %s", progname, s);
- if (!k_opt)
- exit(1);
- }
-
- /*
- * get some symbols form the kernel
- */
- getsyms()
- {
- register i;
-
- if (k_opt) {
- #ifdef ultrix
- (void) nlist(namelist, nl);
- #else /* not ultrix */
- if (nlist(namelist, nl) == -1) {
- (void) fprintf(stderr,
- "%s: can't get name list from %s\n",
- progname, namelist);
- exit(1);
- }
- #endif /* ultrix */
- } else {
- #ifdef ultrix
- (void) nlist("/vmunix", nl);
- #else /* not ultrix */
- #ifdef DYNIX
- if (nlist("/dynix", nl) == -1)
- #else /* not DYNIX */
- if (nlist("/vmunix", nl) == -1)
- #endif /* DYNIX */
- {
- (void) fprintf(stderr,
- "%s: can't get name list from %s\n",
- #ifdef DYNIX
- progname, "/dynix");
- #else /* not DYNIX */
- progname, "/vmunix");
- #endif /* DYNIX */
- exit(1);
- }
- #endif /* ultrix */
- }
-
- for (i = 0; i < (sizeof(nl)/sizeof(nl[0]))-1; i++)
- if (nl[i].n_value == 0) {
- (void) fprintf(stderr, "%s: can't nlist symbol %s\n",
- progname, nl[i].n_name);
- exit(1);
- }
-
- KMPEEK(nl[X_PROC].n_value, procbase);
- KMPEEK(nl[X_PROCNPROC].n_value, procNPROC);
-
- return;
- }
-
- /*
- * When looking at kernel data space through /dev/mem or
- * with a core file, do virtual memory mapping.
- */
- ls_t
- vtophys(vaddr)
- #ifdef pyr
- ;
- #else
- ls_t vaddr;
- {
- u_int paddr;
-
- #ifdef i386
- if (vaddr < 8192)
- return vaddr;
- #endif
- paddr = nl[X_SYSMAP].n_value;
- peek(kmem, (ls_t)paddr, &paddr, sizeof paddr, "level 1 page table", __LINE__);
- paddr = (int)((int *)paddr + (vaddr / NBPG));
- peek(kmem, (ls_t)paddr, &paddr, sizeof paddr, "level 2 page table", __LINE__);
- (void) read(kmem, (char *)&paddr, sizeof paddr);
- #ifndef i386
- # define PTBITS 0x1ff /* 512 byte pages */
- #else
- # define PTBITS 0xfff /* 4096 byte pages */
- #endif
-
- return ((ls_t)(paddr & ~PTBITS) | (vaddr & PTBITS));
- }
- #endif pyr /* vtophys in a separate file for pyramid */
-
- /*
- * get file pointer for socket
- */
- char *
- getsockfp(cba, pfp)
- char *cba;
- struct file **pfp;
- {
- register char *cp;
- struct file *socktofile();
- struct inpcb inpcb;
- static char nmbuf[128];
- struct socket sock;
- struct tcpcb tcpcb;
- long x;
-
- /*
- * Convert PCB address from ASCII to hex.
- */
- for (cp = cba, x = 0l; *cp; cp++) {
- x <<= 4;
- if (*cp >= '0' && *cp <= '9')
- x += *cp - '0';
- else if (*cp >= 'a' && *cp <= 'f')
- x += *cp - 'a' + 10;
- else if (*cp >= 'A' && *cp <= 'F')
- x += *cp - 'A' + 10;
- else {
- (void) fprintf(stderr,
- "%s: non-hex address, %s\n", progname, cba);
- return(NULL);
- }
- }
- /*
- * Read PCB and make sure it is in LISTEN or ESTABLISHED state.
- */
- KMPEEK(x, tcpcb);
- if (tcpcb.t_state < TCPS_LISTEN || tcpcb.t_state > TCPS_ESTABLISHED) {
- (void) fprintf(stderr,
- "%s: PCB %x not in LISTEN to ESTABLISHED state\n",
- progname, x);
- return(NULL);
- }
- if (tcpcb.t_inpcb == (struct inpcb *)0) {
- (void) fprintf(stderr,
- "%s: PCB %x has no INPCB\n",
- progname, x);
- return(NULL);
- }
- /*
- * Read INPCB for PCB and make sure it points back to the PCB.
- */
- KMPEEK(tcpcb.t_inpcb, inpcb);
- if ((caddr_t)x != inpcb.inp_ppcb) {
- (void) fprintf(stderr,
- "%s: INPCB for PCB %x not linked to it\n",
- progname, x);
- return(NULL);
- }
- /*
- * Read the socket and make sure it points back to the INPCB.
- */
- KMPEEK(inpcb.inp_socket, sock);
- if (sock.so_pcb != (caddr_t)tcpcb.t_inpcb) {
- (void) fprintf(stderr,
- "%s: socket not linked to INPCB for PCB %x\n",
- progname, x);
- return(NULL);
- }
- /*
- * Find the file structure that is linked to the socket.
- */
- if ((*pfp = socktofile((caddr_t)inpcb.inp_socket)) == NULL) {
- (void) fprintf(stderr,
- "%s: no file structure for socket of PCB %x\n",
- progname, x);
- return(NULL);
- }
- /*
- * Construct a pseudo file name and return it.
- */
- (void) sprintf(nmbuf,
- "file %lx of socket %lx of INPCB %lx of PCB %lx",
- (long)*pfp, (long)inpcb.inp_socket, (long)tcpcb.t_inpcb, x);
- return(nmbuf);
- }
-
- /*
- * Convert a socket address to a file address.
- */
- struct file *
- socktofile(s)
- caddr_t s;
- {
- register struct file *afile;
- char *calloc();
- register struct file *fp;
- static struct file *ftp;
- static int nfile = -1;
- static struct file *xfile = NULL;
- /*
- * Read the size of file table, allocate space
- * for it, and read the file table pointer (once).
- */
- if (nfile < 0) {
- KMPEEK(nl[SNFILE].n_value, nfile);
- xfile = (struct file *) calloc((unsigned)nfile, sizeof (struct file));
- KMPEEK(nl[SFIL].n_value, ftp);
- }
- /*
- * Read the file table and search for an in-use
- * socket file with a matching data address.
- */
- (void)peek(kmem, (ls_t)ftp, (char *)xfile, nfile * sizeof(struct file), "_file",
- __LINE__, 0);
- for (fp = xfile, afile = ftp; fp < &xfile[nfile]; fp++, afile++) {
- if (fp->f_count && fp->f_type == DTYPE_SOCKET
- && s == fp->f_data)
- return(afile);
- }
- return(NULL);
- }
-
- peek(file, fromwhere, intowhat, size, msg, line, errflg)
- char *intowhat, *msg;
- ls_t fromwhere;
- {
- extern errno;
- extern char *sys_errlist[];
- int n;
-
- #if defined sun && SunOS >= 4
- if (file == kmem) {
- if ((n = kvm_read(kd,
- (unsigned long)(fromwhere),
- (char *)(intowhat),
- size
-
- )) == -1
- ) goto bad;
- return n;
- }
- #endif
- if (lseek(file, k_opt?vtophys(fromwhere):fromwhere, 0) == -1) goto bad;
- if ((n = read(file, intowhat, size)) == -1) goto bad;
- return n;
- bad:
- if (errflg > 0) return 0;
- (void)fprintf (
- stderr,
- "%s: peek from 0x%x into 0x%x failed for %s at line %d (%s)\n",
- progname,
- fromwhere,
- intowhat,
- msg,
- line,
- sys_errlist[errno]
- );
- if (error == 0) exit(1);
- return 0;
- }
-
- #if defined sun && SunOS >= 4 && SunOSrel >= 1
- getuofiles(locu, segu)
- register struct user *locu;
- register struct seguser *segu;
- {
- nofile = locu->u_lastfile + 1;
- if (nofile <= 0) return;
- ofilep = locu->u_ofile;
- if (ofilep == segu->segu_u.u_ofile_arr)
- ofilep = locu->u_ofile_arr;
- else {
- (void)peek(kmem, (ls_t)(ofilep), (char *)(ofile_arr),
- nofile*sizeof (struct file *), "ofile_arr", __LINE__, 0);
- ofilep = ofile_arr;
- }
- }
- #endif
-