home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume25 / ofiles2 / ofiles.c < prev    next >
C/C++ Source or Header  |  1991-12-19  |  35KB  |  1,628 lines

  1. /*    ofiles.c
  2.  *
  3.  *    ofiles [-D ] [-k nlist core] [-n] [-p] [-f|d|m] args
  4.  *
  5.  *    Show owner of open file or network connection.
  6.  *
  7.  *    Reports owner, process ID, access type, command and inode number.
  8.  *
  9.  *    -D        select verbose debugging output
  10.  *
  11.  *    -k nlist core    specifies alternative name list and core files
  12.  *            (DYNIX only)
  13.  *
  14.  *    -n        interpret names as network connection, hexadecimal
  15.  *            Protocol Control Block (PCB) addresses
  16.  *
  17.  *    -p          gives brief (pids only) report
  18.  *
  19.  *    -i        print inode number (ommitted by default)
  20.  *
  21.  *    -m        force argument to be considered as a mount point
  22.  *
  23.  *    -f        force argument to be considered as a regular file
  24.  *
  25.  *    -d        force argument to be considered as a device
  26.  *
  27.  *    names        file names, file system names or network connection
  28.  *            PCB addresses
  29.  *
  30.  *    Stat each file or file system argument and scan the process table,
  31.  *    looking for a match in the associated user structure's file lists.
  32.  *
  33.  *    Follow each PCB arg to the Internet Protocol Control Block (INPCB),
  34.  *    thence to the socket; then scan the file table to find the file
  35.  *    structure address associated with the socket; finally, scan the
  36.  *    process table, looking for a nacth in the associated user structure's
  37.  *    file lists.
  38.  *
  39.  *    Now handles remote NFS files.
  40.  */
  41.  
  42. /*
  43.  *    Authors:
  44.  *
  45.  *    The orignal author is:
  46.  *
  47.  *        C. Spencer
  48.  *
  49.  *    Contributors include:
  50.  *
  51.  *        Michael Ditto
  52.  *        Tom Dunigan
  53.  *        Alexander Dupuy
  54.  *        Greg Nebbett
  55.  *        Richard Tobin
  56.  *
  57.  *    From the Purdue University Computing Center:
  58.  *
  59.  *        Mike Spitzer         converted to 4.3BSD, DYNIX 3.0.1[24]
  60.  *        Ray Moody        SunOS 4.0 and ULTRIX 2.2
  61.  *        Vik Lall
  62.  *
  63.  *        Vic Abell        added socket option and removed lint
  64.  *    
  65.  *    From INRIA Rocquencourt    (France)
  66.  *        Robert Ehrlich        completely revisited in order to:
  67.  *                - make it work on DECSTATIONs 3100, Pyramid
  68.  *                    OSX, Sony NewsOS 3.5 4.0 risc 68k
  69.  *                - make it work on pre 4.0 SunOS (yes,
  70.  *                    my workstation runs 3.5 !)
  71.  *                - find executable text files, mapped files
  72.  *                    under SunOS 4.0
  73.  *                - make it work on remote NFS file-systems
  74.  *                - simplify
  75.  */
  76.  
  77. #ifndef lint
  78. 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 $";
  79. #endif /* lint */
  80.  
  81. #include <sys/param.h>
  82. #include <sys/dir.h>
  83. #include <sys/signal.h>
  84. #if ! BSD || BSD < 43
  85. #include <sys/time.h>
  86. #endif
  87. #include <sys/user.h>
  88.  
  89. #ifdef sun
  90. #if ! defined _user_h && ! defined _sys_user_h
  91. #define SunOS 3
  92. #else
  93. #define SunOS 4
  94. #ifdef _sys_user_h
  95. #define SunOSrel 1
  96. #else
  97. define SunOSrel 0
  98. #endif /* _sys_user_h */
  99. #endif /* _user_h */
  100. #endif /* sun */
  101.  
  102. #ifdef sequent
  103. #define DYNIX
  104. #endif
  105.  
  106. #if defined DYNIX || defined sun || defined pyr || defined sony
  107. #define NFS
  108. #endif
  109.  
  110. #ifdef DYNIX
  111. #define KERNEL
  112. #include <sys/file.h>
  113. #include <sys/vnode.h>
  114. #include <sys/inode.h>
  115. #undef KERNEL
  116. #else
  117. #define KERNEL
  118. #include <sys/file.h>
  119. #ifndef NFS
  120. #include <sys/inode.h>
  121. #include <sys/mount.h>
  122. #undef KERNEL
  123. #else
  124. #undef KERNEL
  125. #include <sys/vfs.h>
  126. #include <rpc/types.h>
  127. #include <sys/vnode.h>
  128. #include <ufs/inode.h>
  129. #include <nfs/nfs.h>
  130. #include <nfs/rnode.h>
  131. #include <ufs/mount.h>
  132. #endif
  133. #endif
  134.  
  135. #include <sys/stat.h>
  136. #ifndef pyr
  137. #include <machine/pte.h>
  138. #else
  139. #include <sys/pte.h>
  140. #include <sys/immu.h>
  141. #endif pyr
  142.  
  143. #if !defined(ultrix) && !defined(sun) && ! defined DYNIX && ! defined pyr
  144. #include <machine/machparam.h>
  145. #endif
  146. #include <sys/proc.h>
  147. #include <nlist.h>
  148. #ifndef O_NDELAY
  149. #include <sys/fcntl.h>
  150. #endif
  151. #include <pwd.h>
  152. #include <fstab.h>
  153. #include <sys/vmmac.h>
  154. #include <stdio.h>
  155.  
  156. #ifdef NFS
  157. struct snode {
  158.     struct snode *s_next;
  159.     struct vnode s_vnode;
  160.     struct vnode *s_realvp;
  161.     struct vnode *s_bdevvp;
  162.     u_short s_flag;
  163.     dev_t s_dev;
  164. };
  165. #endif NFS
  166.  
  167. #if defined sun && SunOS >= 4
  168. #include <kvm.h>
  169. kvm_t    *kd;
  170. #endif
  171.  
  172. #ifdef _nfs_rnode_h        /* _nfs_rnode_h only defined on recent versions of NFS */
  173. #define r_nfsattr r_attr    /* the names of these fields changed vith new version of NFS */
  174. #define nfsfattr vattr
  175. #define na_nodeid va_nodeid
  176. #endif    /* NFS version */
  177.  
  178. #ifdef ultrix
  179. #include <sys/gnode.h>
  180. #include <sys/gnode_common.h>
  181. #include <machine/param.h>
  182. #define i_number g_number
  183. #endif
  184.  
  185. #include <sys/socket.h>
  186. #include <sys/socketvar.h>
  187. #include <net/route.h>
  188. #include <netinet/in.h>
  189. #include <netinet/in_pcb.h>
  190. #include <netinet/tcp.h>
  191. #include <netinet/tcp_fsm.h>
  192. #include <netinet/tcp_timer.h>
  193. #include <netinet/tcp_var.h>
  194.  
  195. #define CDIR    01
  196. #define OFILE    02
  197. #define RDIR    04
  198. #define SHFILE    010
  199. #define EXFILE    020
  200. #define SOCKET  040
  201.  
  202. #if (! defined sun || SunOS < 4) && ! defined DYNIX && ! defined pyr
  203.     /* no more text struct in these systems */
  204. #include <sys/text.h>
  205. #endif
  206.  
  207. #ifdef pyr    /* maybe for all SYS V ? */
  208. #undef r_lock
  209. #include <sys/region.h>
  210. #endif
  211.     /* defines for unix BSD whitout NFS */
  212. #define x_ptr x_iptr
  213. #define node inode
  214. #define DTYPE_NODE DTYPE_INODE
  215. #define FSID struct fs *
  216. #define _fsid i_fs
  217. #define ISROOT(n) ((n)->i_number == ROOTINO)
  218. #define ISBDEV(n) (((n)->i_mode&IFMT) == IFBLK)
  219. #define ISDEV(n) (((n)->i_mode&IFMT) == IFBLK || ((n)->i_mode&IFMT) == IFCHR)
  220. #define TYPEWORD(n) ((n)->i_mode)
  221. #define TYPEBITS(m) ((m)&IFMT)
  222. #define NODETYPE_T unsigned short
  223. #define TREG IFREG
  224. #define TDIR IFDIR
  225. #define TCHR IFCHR
  226. #define TBLK IFBLK
  227.  
  228. #ifdef ultrix
  229.     /* defines for ultrix, i.e. DEC gfs variant of NFS */
  230. #undef x_ptr
  231. #undef node
  232.  
  233. #define x_ptr    x_gptr
  234. #define node gnode
  235. #undef FSID
  236. #define FSID struct mount *
  237. #define i_fs g_mp
  238. #undef ISROOT
  239. #define ISROOT(n) ((n)->g_number == ROOTINO || isroot(n))
  240. #define i_number g_number
  241. #define i_mode g_mode
  242. #define i_rdev g_rdev
  243. #undef TREG
  244. #undef TDIR
  245. #undef TCHR
  246. #undef TBLK
  247. #define TREG GFREG
  248. #define TDIR GFDIR
  249. #define TCHR GFCHR
  250. #define TBLK GFBLK
  251. #include <sys/mount.h>
  252. #define m_inodp m_gnodp
  253. #undef NFS    /* ultrix implememtetion of NFS doesn't fit with my defines */
  254. #if defined P_DYING    /* ultrix 4.1 */
  255. #define p_flag p_sched
  256. #endif            /* ultrix 4.1 */
  257. #endif ultrix
  258.  
  259. #if defined sun || defined NFS
  260.     /* defines for unix systems with NFS a la SUN */
  261. #undef x_ptr
  262. #undef node
  263. #undef DTYPE_NODE
  264.  
  265. #define x_ptr x_vptr
  266. #define node vnode
  267. #define DTYPE_NODE DTYPE_VNODE
  268.  
  269. #undef FSID
  270. #undef _fsid
  271. #define FSID struct vfs *
  272. #define _fsid v_vfsp
  273.  
  274. #undef ISROOT
  275. #undef ISBDEV
  276. #undef ISDEV
  277. #define ISROOT(n) ((n)->v_flag & VROOT)
  278. #define ISBDEV(n) (((n)->v_type) == VBLK)
  279. #define ISDEV(n) (((n)->v_type) == VBLK || ((n)->v_type) == VCHR)
  280.  
  281. #undef TYPEWORD
  282. #undef TYPEBITS
  283. #undef NODETYPE_T
  284. #undef TREG
  285. #undef TDIR
  286. #undef TCHR
  287. #undef TBLK
  288. #define TYPEWORD(n) ((n)->v_type)
  289. #define TYPEBITS(m) m
  290. #define NODETYPE_T enum vtype
  291. #define TREG VREG
  292. #define TDIR VDIR
  293. #define TCHR VCHR
  294. #define TBLK VBLK
  295.  
  296. #endif sun || NFS
  297.  
  298. #define TYPE(n) (TYPEBITS(TYPEWORD(n)))
  299.  
  300. typedef FSID myfsid_t;
  301. typedef NODETYPE_T nodetype_t;
  302.  
  303. #define XFILE    0100
  304. #define MAPPED    0200
  305. #define MOUNTP    0400
  306.  
  307.  
  308. #define STR(s) "s"
  309.  
  310. #if defined sun && SunOS >= 4 
  311. #include <vm/seg_vn.h>
  312. #include <vm/seg.h>
  313. #if SunOSrel > 0
  314. #include <vm/hat.h>
  315. #endif
  316. #include <vm/as.h>
  317.  
  318. #endif SunOS >= 4
  319.  
  320. /*
  321.  * PEEK variants:
  322.  *    KM: from /dev/kmem
  323.  *    M:  from /dev/mem
  324.  *    A:  2nd arg is an array, don't take its address, take its size
  325.  *    P:  2nd arg is a pointer, don't take its address, take size of pointed data
  326.  *    E:  return 0 on error instead of aborting
  327.  */
  328.  
  329. #define KMPEEK(fromwhere, intowhat) \
  330.     (void)peek(kmem, (ls_t)(fromwhere), (char *)(&intowhat), sizeof intowhat, "intowhat", __LINE__, 0)
  331. #define KMAPEEK(fromwhere, intowhat) \
  332.     (void)peek(kmem, (ls_t)(fromwhere), (char *)(intowhat), sizeof intowhat, "intowhat", __LINE__, 0)
  333. #define KMPPEEK(fromwhere, intowhat) \
  334.     (void)peek(kmem, (ls_t)(fromwhere), (char *)(intowhat), sizeof *intowhat, "intowhat", __LINE__, 0)
  335. #define MPPEEK(fromwhere, intowhat) \
  336.     (void)peek(mem, (ls_t)(fromwhere), (char *)(intowhat), sizeof *intowhat, "intowhat", __LINE__, 0)
  337. #define EKMAPEEK(fromwhere, intowhat) \
  338.     peek(kmem, (ls_t)(fromwhere), (char *)(intowhat), sizeof intowhat, "intowhat", __LINE__, 1)
  339. #define EMPPEEK(fromwhere, intowhat) \
  340.     peek(mem, (ls_t)(fromwhere), (char *)(intowhat), sizeof *intowhat, "intowhat", __LINE__, 1)
  341.  
  342. #if !defined NFS && ! defined ROOTINO
  343. #ifdef ultrix
  344. #include <ufs/fs.h>
  345. #else
  346. #include <sys/fs.h>
  347. #endif
  348. #endif
  349.  
  350. char *namelist;
  351. char *corefile;
  352. int k_opt = 0;
  353. #ifdef pyr
  354. int dflg = 0;
  355. #endif pyr
  356. int n_opt = 0;
  357.  
  358. #if defined    ultrix || ( defined sun && SunOS < 4)
  359. #define    ls_t    long
  360. #else
  361. #define ls_t    off_t
  362. #endif
  363.  
  364. #ifdef    sun
  365. char    *sprintf();
  366. #endif
  367.  
  368. ls_t lseek(), vtophys();
  369.  
  370. #ifdef    ultrix
  371. void exit(), nlist(), perror();
  372. #endif
  373.  
  374. int nproc;        /* number of entries in proc table         */
  375. int mem;        /* fd for /dev/mem                */
  376. int kmem;
  377. int swap;        /* fd for /dev/swap                */
  378. struct proc  *procbase, *procNPROC;
  379. int ppid = -1;        /* previously display PID */
  380.  
  381. int pids_only = 0;    /* if non-zero, only output process ids    */
  382. int iflag = 0;        /* i-numbers wanted */
  383.  
  384. char *progname;
  385. struct nlist nl[] = {
  386. #ifndef mips
  387. #define SYM(s) STR(_/**/s)
  388. #else
  389. #define SYM(s) STR(s)
  390. #endif
  391. #define    X_PROC        0
  392.     { SYM(proc) },
  393. #define X_PROCNPROC     1
  394.     { SYM(procNPROC) },
  395. #define X_SYSMAP    2
  396.     { SYM(Sysmap) },
  397. #define    SFIL        3
  398.     {  SYM(file)  },
  399. #define    SNFILE        4
  400.     {  SYM(nfile)  },
  401. #define X_U        5
  402. #if sun && SunOS >= 4 && SunOSrel >= 1
  403.     { SYM(uunix) },
  404. #else
  405.     { SYM(u) },
  406. #endif /* SunOS >= 4.1 */
  407. #if defined NFS
  408. #define X_ROOTVFS    6
  409.     { SYM(rootvfs) },
  410. #else
  411. #define X_MOUNT        6
  412.     { SYM(mount) },
  413. #endif
  414. #ifdef NFS
  415. #define X_UFSVNOPS    7
  416.     { SYM(ufs_vnodeops) },
  417. #define X_NFSVNOPS    8
  418.     { SYM(nfs_vnodeops) },
  419. #define X_SPECVNOPS    9
  420.     { SYM(spec_vnodeops) },
  421. #endif NFS
  422.     { "" }
  423. };
  424.  
  425. #if sun && SunOS >= 4 && SunOSrel >= 1
  426. #define U_ADDR uunix
  427. struct user *uunix;
  428. struct file **ofilep;
  429. struct file *ofile_arr[NOFILE];
  430. int nofile;
  431. #undef NOFILE
  432. #define NOFILE nofile
  433. #define ofile(x) ofilep[x]
  434. #else
  435. #define U_ADDR ((struct user *)(nl[X_U].n_value))
  436. #endif
  437.  
  438. #ifdef pyr
  439. #define DELTA_U    ((char *)u -(char *)U_ADDR)
  440. #define ofile(x) (((struct file **)(((char *)(u->u_ofile))+DELTA_U))[x])
  441. #endif
  442.  
  443. #ifdef    DYNIX
  444. #define ofile(x) u->u_lofile[x].of_file
  445. #undef NOFILE
  446. #define NOFILE u->u_nofile
  447. #endif
  448.  
  449. #ifndef ofile
  450.     /* normal case, "standard " unix */
  451. #define ofile(x) u->u_ofile[x]
  452. #endif /* normal case */
  453.  
  454. int debug;
  455. char *filename, *fsname;
  456. struct node *argnodep, argnode;
  457. dev_t argdev;
  458. nodetype_t argtype;
  459.  
  460. onalarm() {}
  461.  
  462. #ifdef ultrix
  463.  
  464. isroot(np)
  465. struct node *np;
  466. {
  467.     struct node *mp;
  468.     KMPEEK(&(np->g_mp->m_gnodp), mp);
  469.     return (mp == argnodep);
  470. }
  471. #endif ultrix
  472.  
  473. #if (defined ultrix || defined sony) && defined mips
  474. uread(from, to)
  475. unsigned int from, *to;
  476. {
  477.     struct pte *paddr;
  478.     struct proc *procp;
  479. #if 0
  480.     int pte;
  481. #else
  482.     struct pte pte;
  483. #endif
  484.     short pid, mypid;
  485.     mypid = getpid();
  486.     for (procp = procbase + 2; procp < procNPROC; ++procp) {
  487.         KMPEEK(&(procp->p_pid), pid);
  488.         if (pid == mypid) goto found;
  489.     }
  490.     error("My pid is not in proc table !\n");
  491. found:
  492.     KMPEEK(&(procp->p_addr), paddr);
  493.     KMPEEK(&paddr[(from-UADDR)>>PGSHIFT], pte);
  494. #if 0
  495.     MPPEEK((pte&PG_PFNUM) | (from & PGOFSET), to);
  496. #else
  497.     MPPEEK((pte.pg_pfnum << PGSHIFT) | (from & PGOFSET), to);
  498. #endif
  499. }
  500.  
  501.  
  502. #endif 
  503.  
  504. ismountdev(s)
  505. char *s;
  506. {
  507.     register struct fstab *fs;
  508.     
  509.     if ((fs = getfsspec(s)) != NULL) {
  510.         fsname = fs->fs_file;
  511.         return 1;
  512.     }
  513.     return 0;
  514. }
  515.  
  516. getmountdev(s)
  517. char *s;
  518. {
  519.     register struct fstab *fs;
  520.  
  521.     if ((fs = getfsfile(s)) != NULL)
  522.         filename = fs->fs_spec;
  523. }
  524.  
  525. struct proc p;
  526.  
  527. ino_t inum;
  528. #ifdef NFS
  529. struct snode *vdata;
  530. #endif
  531.  
  532. int type;
  533.  
  534. main(argc, argv)
  535.     int     argc;
  536.     char    *argv[];
  537. {
  538.  
  539.     struct user *u, *getuser();
  540.     struct proc *procp;
  541.     register int filen, flags;
  542.     char *getsockfp(), *rindex();
  543.     struct file *fp;
  544.     int ax, err, findf, nmct;
  545.     char *ap;
  546.     int exitval = 0;
  547.     struct mount *mountp;
  548.  
  549. #ifdef    lint
  550. /*
  551.  * The following code satisfies lint for KERNEL symbols.
  552.  * This program is lint-free under 4.3BSD, DYNIX 3.0.1[24], SunOS 4.0
  553.  * and ULTRIX 2.2, using the lint libraries of the systems at the
  554.  * Purdue University Computing Center.
  555.  */
  556. #if    !defined(ultrix) && !defined(DYNIX) && !defined(sun)
  557.     long lintlong;
  558. #endif
  559. #ifdef    ultrix
  560.     struct nch *lintnch;
  561.     float lintfloat;
  562. #endif
  563. #if    !defined(DYNIX)
  564.     file = fileNFILE = NULL;
  565.     fp = file;
  566.     fp = fileNFILE;
  567.     nfile = 0;
  568.     filen = nfile;
  569. #endif
  570. #if    !defined(ultrix) && !defined(DYNIX) && !defined(sun)
  571.     inode = inodeNINODE = rootdir = NULL;
  572.     i = inode;
  573.     i = inodeNINODE;
  574.     i = rootdir;
  575.     ninode = 0;
  576.     nextinodeid = 0l;
  577.     lintlong = nextinodeid;
  578.     nextinodeid = lintlong;
  579.     filen = ninode;
  580. #endif
  581. #if defined sun && SunOS >= 4
  582.     tcp_ttl = 0;
  583.     filen  = tcp_ttl;
  584. #endif
  585. #ifdef    ultrix
  586.     nch = NULL;
  587.     lintnch = nch;
  588.     nch = lintnch;
  589.     nchsize = 0;
  590.     filen = nchsize;
  591.     tcp_alpha = tcp_beta = 0.0;
  592.     lintfloat = tcp_alpha;
  593.     lintfloat = tcp_beta;
  594.     tcp_alpha = lintfloat;
  595. #endif
  596. #endif    /* lint */
  597.  
  598.     if ((progname = rindex(argv[0], '/')))
  599.         progname++;
  600.     else
  601.         progname = argv[0];
  602.  
  603.     if (argc == 1) {
  604.  
  605. usage:
  606.  
  607. #ifdef    DYNIX
  608.         (void) fprintf(stderr,
  609.             "usage: %s [-D ] [-k nlist core] [-n] [-p] [-d|-n|-p]  names\n",
  610.             progname);
  611. #else
  612.         (void) fprintf(stderr,
  613.             "usage: %s [-D ] [-n] [-p] [-d|-n|-p] names\n", progname);
  614. #endif
  615.         (void) fprintf(stderr, "\t-D    = select verbose debugging output\n");
  616. #ifdef    DYNIX
  617.         (void) fprintf(stderr,
  618.             "\t-k    = use specified nlist and core files\n");
  619. #endif
  620.         (void) fprintf(stderr,
  621.             "\t-n    = interpret names as network connection, hexadecimal,\n");
  622.         (void) fprintf(stderr,
  623.             "\t        Protocol Control Block (PCB) addresses, as supplied\n");
  624.         (void) fprintf(stderr,
  625.             "\t        by netstat's -A option\n");
  626.         (void) fprintf(stderr, "\t-p    = print only process IDs\n");
  627.         (void) fprintf(stderr,
  628.             "\tnames = file names or PCB addresses\n");
  629.         (void) fprintf(stderr, "\t-d\n\t-m\n\t-f      force name to be considered respectiveley\n");
  630.         (void) fprintf(stderr, "\t\t as a device, mount point or regular file\n");
  631.         exit(exitval);
  632.     }
  633.  
  634.     /* check for switches */
  635.     for (err = 0, ax = 1; ax < argc; ax++) {
  636.         ap = argv[ax];
  637.         if (*ap++ != '-')
  638.             break;
  639.         while (*ap) {
  640.             type = 0;
  641.             switch (*ap++) {
  642.  
  643.             case 'D':
  644.                 debug = 1;
  645.                 break;
  646. #if defined DYNIX || defined pyr
  647.             case 'k':
  648.                 if ((ax + 2) >= argc) {
  649.                     (void) fprintf(stderr,
  650.                         "%s: no nlist/core after -k\n",
  651.                         progname);
  652.                     err++;
  653.                 } else {
  654.                     namelist = argv[++ax];
  655.                     corefile = argv[++ax];
  656.                     k_opt = 1;
  657. #ifdef pyr
  658.                     if (ap[1] == 'd')
  659.                         dflg = 1;
  660. #endif pyr
  661.                     continue;
  662.                 }
  663.                 break;
  664. #endif DYNIX || pyr
  665.             case 'n':
  666.                 n_opt++;
  667.                 break;
  668.  
  669.             case 'p':
  670.                 pids_only = 1;
  671.                 break;
  672.             case 'i':
  673.                 iflag = 1;
  674.                 break;
  675.  
  676.             case 'm':
  677.             case 'f':
  678.             case 'd':
  679.                 type = ap[-1];
  680.                 break;
  681.             default:
  682.                 (void) fprintf(stderr,
  683.                     "%s: unknown switch - %c\n",
  684.                     progname, *(ap - 1));
  685.                 err++;
  686.             }
  687.         }
  688.     }
  689.     if (ax >= argc) {
  690.         (void) fprintf(stderr, "%s: no names specified\n", progname);
  691.         err++;
  692.     }
  693.     if (err) {
  694.         exitval = 1;
  695.         goto usage;
  696.     }
  697.  
  698. #if defined sun && SunOS >= 4
  699.         if ((kd = kvm_open (NULL, NULL, NULL, O_RDONLY)) == 0) {
  700.         (void) fprintf(stderr, "%s: can't access memory: ",
  701.             progname);
  702.             perror ("");
  703.         exit(1);
  704.     }
  705. #endif
  706.     if ((mem = open("/dev/mem", 0)) < 0) {
  707.         (void) fprintf(stderr, "%s: /dev/mem: ", progname);
  708.         perror("");
  709.         exit(1);
  710.     }
  711.     if (k_opt) {
  712.         if ((kmem = open(corefile, 0)) < 0) {
  713.             (void) fprintf(stderr, "%s: %s: ",
  714.                 progname, corefile);
  715.             perror("");
  716.             exit(1);
  717.         }
  718.         mem = kmem;
  719. #ifdef pyr
  720.         if (dflg)
  721.             setdump();
  722. #endif pyr
  723.     } else {
  724.         if ((kmem = open("/dev/kmem", 0)) < 0) {
  725.             (void) fprintf(stderr, "%s: /dev/kmem: ", progname);
  726.             perror("");
  727.             exit(1);
  728.         }
  729.     }
  730. #ifndef pyr
  731.     if (!k_opt) 
  732.         if ((swap = open("/dev/drum", 0)) < 0) {
  733.             (void) fprintf(stderr, "%s: /dev/drum: ", progname);
  734.             perror("");
  735.             exit(1);
  736.         }
  737. #endif pyr
  738.     getsyms();
  739.  
  740.     for (err = 0, nmct = argc - ax; ax < argc; ax++) {
  741.         /* if -n, then arg is a PCB */
  742.         if (n_opt) {
  743.             if ((filename = getsockfp(argv[ax], &fp)) == NULL) {
  744.                 err++;
  745.                 continue;
  746.             }
  747.             fsname = "";
  748.         } else {
  749.             int argfd;
  750.             char buf[100];
  751.  
  752.             filename = argv[ax];
  753.             fsname = filename;
  754. retry:
  755.             signal(SIGALRM,onalarm);
  756.             alarm(1);
  757.             argfd = open(fsname, O_RDONLY|O_NDELAY);
  758.             alarm(0);
  759.             if (argfd == -1) {
  760.                 extern int errno;
  761.                 extern char *sys_errlist[];
  762.                 struct stat bufstat;
  763.                 if (stat(fsname, &bufstat) != -1)
  764.                     switch (bufstat.st_mode & IFMT) {
  765.                         case IFBLK:
  766.                             argtype = TBLK;
  767.                             break;
  768.                         case IFCHR:
  769.                             argtype = TCHR;
  770.                             break;    
  771.                         default:
  772.                             goto bad;
  773.                     }
  774.                 else
  775.                     goto bad;
  776.                 argdev = bufstat.st_rdev;
  777.                 type = 'd';
  778.                 goto skip;
  779. bad:
  780.                 (void) sprintf(buf, "open failed for %s (%s)\n", fsname, sys_errlist[errno]);
  781.                 error(buf);
  782.  
  783.             }
  784. #if defined pyr || defined sun && SunOS >= 4 && SunOSrel >=1
  785. #define OFILEPTR
  786.             {
  787.             struct file **ofp;
  788. #if defined sun
  789.             KMPEEK(nl[X_U].n_value, uunix);
  790. #endif
  791.             KMPEEK(&(U_ADDR->u_ofile), ofp);
  792.             KMPEEK(ofp+argfd, fp);
  793.             }
  794. #endif OFILEPTR
  795.  
  796. #if defined mips && (defined ultrix || defined sony)
  797.     /* ultrix & sony mips have no access via kmem to its own user struct ! */
  798.             uread(&((U_ADDR->u_ofile)[argfd]), &fp);
  799. #endif
  800.  
  801.  
  802. #if !defined OFILEPTR && !((defined ultrix || defined sony) && defined mips)
  803.     /* the "normal case " */
  804.             KMPEEK(U_ADDR->u_ofile+argfd, fp);
  805. #endif /* normal case */
  806.             KMPEEK(&(fp->f_data), argnodep);
  807.             KMPEEK(argnodep, argnode);
  808.             (void)close(argfd);
  809.             switch(type) {
  810.                 case 0:
  811.                     if (ISROOT(&argnode)) {
  812.                         type = 'm';
  813.                         getmountdev(filename);
  814.                     } else if (ISDEV(&argnode))
  815.                         if (ismountdev(fsname)) {
  816.                             type = 'm';
  817.                             goto retry;
  818.                         } else {
  819.                             type = 'd';
  820.                             fsname = "";
  821.                         }
  822.                     else {
  823.                         type = 'f';
  824.                         fsname = "";
  825.                     }
  826.                     break;
  827.                 case 'f':
  828.                     switch(TYPE(&argnode)) {
  829.                         case TREG:
  830.                         case TDIR:
  831.                         case TCHR:
  832.                         case TBLK:
  833.                             break;
  834.                         default:
  835.                             (void)sprintf(buf,
  836.                                 "invalid %s type for arg type '%c' arg %s\n",
  837.                                 STR(node),
  838.                                 type,
  839.                                 argv[ax]);
  840.                             error(buf);
  841.                     }
  842.                     break;
  843.                 case 'm':
  844.                     if (!ISROOT(&argnode)) {
  845.                         if (ismountdev(fsname))
  846.                             goto retry;
  847.                         (void)sprintf(buf,
  848.                             "%s is not a root\n",
  849.                             fsname);
  850.                         error(buf);
  851.                     }
  852.                     if (fsname == filename)
  853.                         getmountdev(filename);
  854.                     break;
  855.                 case 'd':
  856.                     if(!ISDEV(&argnode)) {
  857.                         (void)sprintf(buf,
  858.                             "%s is not a device\n",
  859.                             filename);
  860.                         error(buf);
  861.                     }
  862.                     fsname = "";
  863.                     break;
  864.             }
  865.             if (type == 'd')
  866. #ifdef NFS
  867.                 KMPEEK(&(((struct snode *)(argnode.v_data))->s_dev), argdev);
  868. #else
  869.                 argdev = argnode.i_rdev;
  870. #endif NFS
  871.                 argtype = TYPE(&argnode);
  872.         }
  873.         if (iflag && type == 'f') {
  874. #ifdef NFS
  875.             struct node *i;
  876.  
  877.             if (ISDEV(&argnode)) {
  878.                 KMPEEK(&(((struct snode *)argnode.v_data)->s_realvp), i);
  879.                 KMPEEK(&(i->v_data), vdata);
  880.             } else {
  881.                 if ((int)argnode.v_op == nl[X_UFSVNOPS].n_value)
  882.                     KMPEEK(&(((struct inode *)argnode.v_data)->i_number), inum);
  883.                 else if ((int)argnode.v_op == nl[X_NFSVNOPS].n_value)
  884.                     KMPEEK(&(((struct rnode *)argnode.v_data)->r_nfsattr.na_nodeid), inum);
  885.                 else
  886.                     inum = 0;
  887.             }
  888. #else
  889.             inum = argnode.i_number;
  890. #endif
  891.         }
  892. skip:
  893.         if (! pids_only) {
  894.             (void) printf("%s\t%s", filename, fsname);
  895.             if (!n_opt) {
  896.                 if (type == 'f')
  897.                     if (TYPE(&argnode) == TDIR)
  898.                         (void) printf(" (directory)");
  899.                     else
  900.                         (void) printf(" (regular file)");
  901.                 else if (type == 'm')
  902.                     (void) printf(" (mount point)");
  903.                 else
  904.                     (void) printf(" (device)");
  905.                     
  906.             }
  907.             (void) printf("\n%-8.8s  %5s  %-6.6s  FD  %-14.14s",
  908.                 "USER", "PID", "TYPE", "CMD");
  909.             if (!n_opt && iflag)
  910.                 (void) printf("  INODE");
  911.             (void) printf("\n");
  912.         }
  913.         if (!n_opt) {
  914.             struct node *i;
  915. #if defined NFS
  916.             struct vfs *vfsp;
  917.             KMPEEK(nl[X_ROOTVFS].n_value, vfsp);
  918.             for (; vfsp; KMPEEK(&(vfsp->vfs_next), vfsp)) {
  919.                 KMPEEK(&(vfsp->vfs_vnodecovered), i);
  920.                 if(!i) continue;
  921.                 if (check(i, type))
  922.                     gotone(0,0,-1,MOUNTP,i);
  923.             }
  924. #else
  925.             mountp = (struct mount *)nl[X_MOUNT].n_value;
  926.             for (;;) {
  927.                 KMPEEK(&(mountp->m_inodp), i);
  928.                 if (!i) break;
  929.                 if (check(i, type))
  930.                     gotone(0,0,-1,MOUNTP,i);
  931.                 ++mountp;
  932.             }
  933. #endif NFS
  934.         }
  935.  
  936.         for (procp = procbase, findf = 0; procp < procNPROC; ++procp) {
  937.             KMPEEK(procp, p);
  938.             flags = 0;
  939.             if (p.p_stat == 0 || p.p_stat == SZOMB) 
  940.                 continue;
  941. #if defined sun && SunOS >= 4
  942.             u = kvm_getu(kd, &p);
  943. #if SunOSrel >= 1
  944.             getuofiles(u, p.p_segu);
  945. #endif
  946. #else
  947.             u = getuser(&p);
  948. #endif
  949.  
  950.             if ( u == (struct user *)NULL)
  951.                 continue;
  952.             if (debug)
  953.                 (void) printf("pid %d uid %d cmd %s\n", p.p_pid,
  954.                     p.p_uid, u->u_comm);
  955.             if (!n_opt) {
  956.                 struct node *txtnode;
  957.  
  958.                 if (check(u->u_rdir, type)) {
  959.                     gotone(u, &p, -1, RDIR, u->u_rdir);
  960.                     findf++;
  961.                 }
  962.                 if (check(u->u_cdir, type)) {
  963.                     gotone(u, &p, -1, CDIR, u->u_cdir);
  964.                     findf++;
  965.                 }
  966.         /* check text files */
  967. #if (! defined sun || SunOS < 4) && !defined pyr
  968. #ifndef DYNIX
  969.                 if (p.p_textp) {
  970.                     KMPEEK(&(p.p_textp->x_ptr), txtnode);
  971.                     if (check(txtnode, type)) {
  972.                         gotone(u, &p, -1, XFILE, txtnode);
  973.                         findf++;
  974.                     }
  975.                 }
  976. #endif DYNIX
  977. #endif
  978. #ifdef pyr
  979.                 {
  980.                     struct pregion *prp = p.p_region;
  981.                     struct region *rp;
  982.                     struct node *lastv = 0;
  983.                     int nreg;
  984.  
  985.                     for (nreg = 0; nreg <= p.p_nregion; ++nreg) {
  986.                         KMPEEK(&(prp->p_reg), rp);
  987.                         KMPEEK(&(rp->r_vptr), txtnode);
  988.                         if (txtnode == lastv) continue;
  989.                         if (check(txtnode, type)) {
  990.                             gotone(u, &p, -1, XFILE, txtnode);
  991.                             findf++;
  992.                         }
  993.                         lastv = txtnode;
  994.                     }
  995.                 }
  996. #endif pyr
  997. #if defined sun && SunOS >= 4
  998.         /* in SunOS >= 4 and DYNIX, text files are mapped files */
  999.                 if (p.p_as) {
  1000.                     struct seg *segp, *segnext;
  1001.                     struct  segvn_data *svd;
  1002.                     struct vnode *lastv = 0;
  1003.  
  1004.                     KMPEEK(&(p.p_as->a_segs), segp);
  1005.                     if (!segp) goto noseg;
  1006.                     segnext = segp;
  1007.                     do {
  1008.                         KMPEEK(&((struct  segvn_data *)(segnext->s_data)), svd);
  1009.                         if (!svd) continue;
  1010.                         KMPEEK(&(svd->vp), txtnode);
  1011.                         if(txtnode == lastv) continue;
  1012. #if defined sun
  1013.                         if(((int)txtnode&0xff00000) != 0xff00000
  1014. ) continue;
  1015. #endif sun
  1016.                         if (check(txtnode, type)) {
  1017.                             gotone(u, &p, -1, MAPPED, txtnode);
  1018.                             findf++;
  1019.                             lastv = txtnode;
  1020.                         }
  1021.                         
  1022.                     } while(KMPEEK(&((struct  segvn_data *)(segnext->s_next)), segnext),
  1023.                         segnext != segp);
  1024.                     noseg: ;
  1025.                 }
  1026. #endif SunOS < 4
  1027.             }
  1028.             for (filen = 0; filen < NOFILE; filen++)
  1029.             {
  1030.                 struct file f;
  1031.  
  1032.                 flags = 0;
  1033.                 if (n_opt) {
  1034.                     if (ofile(filen) != fp)
  1035.                         continue;
  1036.                 } else {
  1037.                     if (ofile(filen) == NULL)
  1038.                         continue;
  1039.                 }
  1040.  
  1041.                 KMPEEK(ofile(filen), f);
  1042.  
  1043.                 if (f.f_count > 0) {
  1044.                     if (n_opt && f.f_type == DTYPE_SOCKET) {
  1045.                         gotone(u, &p, filen, SOCKET, 0);
  1046.                         findf++;
  1047.                         continue;
  1048.                     }
  1049.                     if (f.f_type != DTYPE_NODE)
  1050.                         continue;
  1051.  
  1052.                     if (check((struct node *)f.f_data,
  1053.                         type)) {
  1054.                         flags |= OFILE;
  1055.                         if (f.f_flag & FEXLOCK) {
  1056.                             flags |= EXFILE;
  1057.                         }
  1058.                         if (f.f_flag & FSHLOCK) {
  1059.                             flags |= SHFILE;
  1060.                         }
  1061.                         gotone(u, &p, filen, flags, (struct node *)f.f_data);
  1062.                         findf++;
  1063.                     }
  1064.                 }
  1065.             }
  1066.         }
  1067.         if (findf)
  1068.             nmct--;
  1069.         if (! pids_only) {
  1070.                 (void) printf("\n");
  1071.             (void) fflush(stdout);
  1072.         }
  1073.     }
  1074.     if (pids_only && ppid != -1) {
  1075.         (void) printf("\n");
  1076.         (void) fflush(stdout);
  1077.     }
  1078.     exitval = (err || nmct) ? 1 : 0;
  1079.     exit(exitval);
  1080. }
  1081.  
  1082.  
  1083. /*
  1084.  * print the name of the user owning process "p" and the pid of that process
  1085.  */
  1086. gotone(u, p, fd, f, i)
  1087.     struct user *u;
  1088.     struct proc *p;
  1089.     int fd;
  1090.     int f;
  1091.     struct node *i;
  1092. {
  1093.     char *ty, tybuf[8], *strcat(), *strcpy();
  1094.     struct passwd *getpwuid();
  1095.     register struct passwd *pw;
  1096.  
  1097.     /* only print pids and return */
  1098.     if (pids_only) {
  1099.         if (!p) return;
  1100.         if (ppid != p->p_pid) {
  1101.             if (ppid != -1)
  1102.                 (void) printf(" ");
  1103.             (void) printf("%d", p->p_pid);
  1104.             (void) fflush(stdout);
  1105.             ppid = p->p_pid;
  1106.         }
  1107.         return;
  1108.     }
  1109.     if (p) {
  1110.         pw = getpwuid((int)p->p_uid);
  1111.         if (pw)
  1112.             (void) printf("%-8.8s  ", pw->pw_name );
  1113.         else
  1114.             (void) printf("%-8d  ", p->p_uid);
  1115.         (void) printf("%5d  ", p->p_pid);
  1116.         if (f & OFILE) {
  1117.             (void) strcpy(tybuf, "file");
  1118.             ty = tybuf;
  1119.             if (f & SHFILE)
  1120.                 (void) strcat(ty, "/s");
  1121.             else if (f & EXFILE)
  1122.                 (void) strcat(ty, "/x");
  1123.         } else if (f & CDIR)
  1124.             ty = "cwd";
  1125.         else if (f & RDIR)
  1126.             ty = "rdir";
  1127.         else if (f & SOCKET)
  1128.             ty = "sock";
  1129. #if SunOS < 4
  1130.         else if (f & XFILE)
  1131.             ty = "text";
  1132. #else /* SunOS >= 4 */
  1133.         else if (f & MAPPED)
  1134.             ty = "mapped";
  1135. #endif /* SunOS */
  1136.         else
  1137.             ty = "";
  1138.     } else {
  1139.         printf("                 ");
  1140.         if (f & MOUNTP)
  1141.         ty = "mntpnt";
  1142.     }
  1143.     (void) printf("%-6.6s  ", ty);
  1144.     if (fd >= 0)
  1145.         (void) printf("%2d  ", fd);
  1146.     else
  1147.         (void) printf("    ");
  1148.     (void) printf("%-14.14s", u?u->u_comm:"");
  1149.     if (iflag && i) {
  1150.         if (type != 'f') {
  1151. #ifdef NFS
  1152.             struct vnodeops *vopp;
  1153.  
  1154.             if (type != 'd')
  1155.                 KMPEEK(&(i->v_data), vdata);
  1156.             KMPEEK(&(i->v_op), vopp);
  1157.             if ((int)vopp == nl[X_UFSVNOPS].n_value)
  1158.                 KMPEEK(&(((struct inode *)vdata)->i_number), inum);
  1159.             else if ((int)vopp == nl[X_NFSVNOPS].n_value)
  1160.                 KMPEEK(&(((struct rnode *)vdata)->r_nfsattr.na_nodeid), inum);
  1161.             else if ((int)vopp == nl[X_SPECVNOPS].n_value) {
  1162.                 KMPEEK(&(vdata)->s_realvp, i);
  1163.                 KMPEEK(&(i->v_data), vdata);
  1164.                 KMPEEK(&(((struct inode *)vdata)->i_number), inum);
  1165.             } else
  1166.                 inum = 0;
  1167. #else
  1168.             KMPEEK(&(i->i_number), inum);
  1169. #endif
  1170.         }
  1171.         printf("  %5d", inum);
  1172.     }
  1173.  
  1174.     (void) printf("\n");
  1175.     return;
  1176. }
  1177.  
  1178. /*
  1179.  * is [igv]node "i"
  1180.       - on the filesystem of argnode when type == 'm'
  1181.      - identical to argnode when type = 'f'
  1182.      - the same device as argnode when type == 'd'
  1183.    ?
  1184.    returns TRUE or FALSE 
  1185.  */
  1186.  
  1187.  
  1188. check(i, type)
  1189.     struct node *i;
  1190. {
  1191.     myfsid_t fsid;
  1192.     dev_t dev;
  1193.     nodetype_t tword;
  1194.  
  1195.     if (type == 'f') return (i == argnodep);
  1196.     if (i == (struct node *)NULL)
  1197.         return 0;
  1198.     if (type == 'm') {
  1199.         KMPEEK(&(i->_fsid), fsid);
  1200.         return (argnode._fsid == fsid);
  1201.     }
  1202.     KMPEEK(&TYPEWORD(i),tword);
  1203.     if (TYPEBITS(tword) != argtype) return 0;
  1204. #ifndef NFS
  1205.     KMPEEK(&(i->i_rdev), dev);
  1206. #else
  1207.     KMPEEK(&(i->v_data), vdata);
  1208.     KMPEEK(&(vdata->s_dev), dev);
  1209. #endif
  1210.     return (argdev == dev);
  1211. }
  1212.  
  1213.  
  1214. #if !defined(sun) || SunOS < 4
  1215. /* 
  1216.  * get user page for proc "p" from core or swap
  1217.  * return pointer to user struct
  1218.  */
  1219. #ifdef    DYNIX
  1220. struct user *
  1221. getuser(p)
  1222.     struct proc *p;
  1223. {
  1224.     int btr;
  1225.     ls_t sp;
  1226.     static struct user *u = NULL;
  1227.     char *valloc();
  1228.  
  1229.     if (u == NULL) {
  1230.         if ((u = (struct user *) valloc(ctob(UPAGES))) == NULL) {
  1231.             (void) fprintf(stderr,
  1232.                 "%s: can't allocate space for user structure\n",                progname);
  1233.             exit(1);
  1234.         }
  1235.     }
  1236.     btr = ctob(UPAGES);
  1237.     if ((p->p_flag & SLOAD) == 0) {
  1238.         if (k_opt)
  1239.             return (struct user *)NULL;
  1240.         sp = (ls_t) dtob(p->p_swaddr);
  1241.         if (lseek(swap, sp, 0) != sp) {
  1242.             if (debug) {
  1243.                 (void) fprintf(stderr,
  1244.                     "%s: error seeking to swap for %d: ",
  1245.                     progname, p->p_pid);
  1246.                 perror("");
  1247.             }
  1248.             return (struct user *)NULL;
  1249.         }
  1250.         if (read(swap, (char*)u, btr) != btr) {
  1251.             if (debug) {
  1252.                 (void) fprintf(stderr,
  1253.                     "%s: error reading swap for %d: ",
  1254.                     progname, p->p_pid);
  1255.                 perror("");
  1256.             }
  1257.             return (struct user *)NULL;
  1258.         }
  1259.         if (debug)
  1260.             (void) printf("read swap\n");
  1261.     } else {
  1262.         KMPPEEK(p->p_uarea, u);
  1263.     }
  1264.     return u;
  1265. }
  1266. #endif
  1267.  
  1268. #ifdef pyr
  1269. struct user *
  1270. getuser(p)
  1271.     struct proc *p;
  1272. {
  1273.     static union uuser {
  1274.         struct user u_user;
  1275.         char u_bytes[UPAGES*NBPG];
  1276.     } uuser;
  1277.  
  1278.     if (readublk(p->p_pid, &uuser))
  1279.         return 0;
  1280.     else
  1281.         return &uuser.u_user;
  1282. }
  1283.  
  1284. #endif pyr
  1285.  
  1286. #if ! defined DYNIX && ! defined pyr
  1287. struct user *
  1288. getuser(p)
  1289.     struct proc *p;
  1290. {
  1291. #define USERPAGES ((sizeof (struct user) + NBPG -1)/NBPG)
  1292.     struct pte mypgtbl[USERPAGES];
  1293.     int upage;
  1294.     ls_t sp;
  1295.     typedef struct { char bytes[NBPG] } page;
  1296.     page *up;
  1297.     static union uuser {
  1298.         struct user u_user;
  1299.         char u_bytes[USERPAGES*NBPG];
  1300.     } uuser;
  1301. #define User uuser.u_user
  1302.  
  1303.     /* easy way */
  1304.     if ((p->p_flag & SLOAD) == 0) {
  1305.         if (k_opt)
  1306.             return (struct user *)NULL;
  1307. #if defined ultrix && defined P_DYING        /* ultrix 4.1 */
  1308.         if (p->p_smap == 0)
  1309.             return (struct user *)NULL;
  1310.         {
  1311.         struct dmap l_dmap;
  1312.         int ublkno;
  1313.         KMPEEK(p->p_smap, l_dmap);
  1314.         KMPEEK(l_dmap.dm_ptdaddr, ublkno);
  1315.         sp = (ls_t)dtob(ublkno);
  1316.         }
  1317. #else
  1318.         sp = (ls_t)dtob(p->p_swaddr);
  1319. #endif /* ultrix 4.1 */
  1320.         if(!peek(swap,  sp, (char *)&User, sizeof(union uuser),
  1321.             "swapped user page(s)", __LINE__, -1))
  1322.             return (struct user *)NULL;
  1323.         if (debug)
  1324.             (void) printf("read swap\n");
  1325.     } else {     /* boo */
  1326.         /* now get this user's page table */
  1327.         if (! EKMAPEEK(p->p_addr, mypgtbl)) {
  1328.             (void) fprintf(stderr,
  1329.                 "%s: can't get mypgtbl.\n", progname);
  1330.             return (struct user *)NULL;
  1331.         }
  1332.         /* now collect various pages of u area */
  1333.         for (upage = 0, up = (page *)&User; upage < USERPAGES; upage++) {
  1334.         if(! EMPPEEK(ctob(mypgtbl[upage].pg_pfnum), up)) {
  1335.                 (void) fprintf(stderr,
  1336.                     "%s: can't get page %d of user area.\n",
  1337.                     progname, upage);
  1338.                 return(NULL);
  1339.             }
  1340.             ++up;
  1341.         }
  1342.     }
  1343.     return &User;
  1344. }
  1345.  
  1346. #endif /* ! DYNIX */
  1347. #endif /* SunOS < 4 */
  1348.  
  1349.  
  1350. /*
  1351.  * print mesg "s", don't exit if we are processing a core, 
  1352.  * so that corrupt entries don't prevent further uncorrupted
  1353.  * entries from showing up.
  1354.  */
  1355. error(s)
  1356.     char *s;
  1357. {
  1358.     if (s && !k_opt)
  1359.         (void) fprintf(stderr, "%s: %s", progname, s);
  1360.     if (!k_opt)
  1361.         exit(1);
  1362. }
  1363.  
  1364. /*
  1365.  * get some symbols form the kernel
  1366.  */
  1367. getsyms()
  1368. {
  1369.     register i;
  1370.  
  1371.     if (k_opt) {
  1372. #ifdef    ultrix
  1373.         (void) nlist(namelist, nl);
  1374. #else    /* not ultrix */
  1375.         if (nlist(namelist, nl) == -1) {
  1376.             (void) fprintf(stderr,
  1377.                 "%s: can't get name list from %s\n",
  1378.                 progname, namelist);
  1379.             exit(1);
  1380.         }
  1381. #endif    /* ultrix */
  1382.     } else {
  1383. #ifdef    ultrix
  1384.         (void) nlist("/vmunix", nl);
  1385. #else    /* not ultrix */
  1386. #ifdef    DYNIX
  1387.         if (nlist("/dynix", nl) == -1)
  1388. #else    /* not DYNIX */
  1389.         if (nlist("/vmunix", nl) == -1)
  1390. #endif    /* DYNIX */
  1391.         {
  1392.             (void) fprintf(stderr,
  1393.                 "%s: can't get name list from %s\n",
  1394. #ifdef    DYNIX
  1395.                 progname, "/dynix");
  1396. #else    /* not DYNIX */
  1397.                 progname, "/vmunix");
  1398. #endif    /* DYNIX */
  1399.             exit(1);
  1400.         }
  1401. #endif    /* ultrix */
  1402.     }
  1403.  
  1404.     for (i = 0; i < (sizeof(nl)/sizeof(nl[0]))-1; i++)
  1405.         if (nl[i].n_value == 0) {
  1406.             (void) fprintf(stderr, "%s: can't nlist symbol %s\n",
  1407.                 progname, nl[i].n_name);
  1408.             exit(1);
  1409.         }
  1410.  
  1411.     KMPEEK(nl[X_PROC].n_value, procbase);
  1412.     KMPEEK(nl[X_PROCNPROC].n_value, procNPROC);
  1413.  
  1414.     return;
  1415. }
  1416.  
  1417. /*
  1418.  * When looking at kernel data space through /dev/mem or
  1419.  * with a core file, do virtual memory mapping.
  1420.  */
  1421. ls_t
  1422. vtophys(vaddr)
  1423. #ifdef pyr
  1424.     ;
  1425. #else
  1426.     ls_t vaddr;
  1427. {
  1428.     u_int paddr;
  1429.     
  1430. #ifdef    i386
  1431.     if (vaddr < 8192)
  1432.         return vaddr;
  1433. #endif
  1434.     paddr = nl[X_SYSMAP].n_value;
  1435.     peek(kmem, (ls_t)paddr, &paddr, sizeof paddr, "level 1 page table", __LINE__);
  1436.     paddr = (int)((int *)paddr + (vaddr / NBPG));
  1437.     peek(kmem, (ls_t)paddr, &paddr, sizeof paddr, "level 2 page table", __LINE__);
  1438.     (void) read(kmem, (char *)&paddr, sizeof paddr);
  1439. #ifndef    i386
  1440. # define    PTBITS    0x1ff    /* 512 byte pages */
  1441. #else
  1442. # define    PTBITS    0xfff    /* 4096 byte pages */
  1443. #endif
  1444.  
  1445.     return ((ls_t)(paddr & ~PTBITS) | (vaddr & PTBITS));
  1446. }
  1447. #endif pyr    /* vtophys in a separate file for pyramid */
  1448.  
  1449. /*
  1450.  * get file pointer for socket
  1451.  */
  1452. char *
  1453. getsockfp(cba, pfp)
  1454.     char *cba;
  1455.     struct file **pfp;
  1456. {
  1457.     register char *cp;
  1458.     struct file *socktofile();
  1459.     struct inpcb inpcb;
  1460.     static char nmbuf[128];
  1461.     struct socket sock;
  1462.     struct tcpcb tcpcb;
  1463.     long x;
  1464.  
  1465. /*
  1466.  * Convert PCB address from ASCII to hex.
  1467.  */
  1468.     for (cp = cba, x = 0l; *cp; cp++) {
  1469.         x <<= 4;
  1470.         if (*cp >= '0' && *cp <= '9')
  1471.             x += *cp - '0';
  1472.         else if (*cp >= 'a' && *cp <= 'f')
  1473.             x += *cp - 'a' + 10;
  1474.         else if (*cp >= 'A' && *cp <= 'F')
  1475.             x += *cp - 'A' + 10;
  1476.         else {
  1477.             (void) fprintf(stderr,
  1478.                 "%s: non-hex address, %s\n", progname, cba);
  1479.             return(NULL);
  1480.         }
  1481.     }
  1482. /*
  1483.  * Read PCB and make sure it is in LISTEN or ESTABLISHED state.
  1484.  */
  1485.     KMPEEK(x, tcpcb);
  1486.     if (tcpcb.t_state < TCPS_LISTEN || tcpcb.t_state > TCPS_ESTABLISHED) {
  1487.         (void) fprintf(stderr,
  1488.             "%s: PCB %x not in LISTEN to ESTABLISHED state\n",
  1489.             progname, x);
  1490.         return(NULL);
  1491.     }
  1492.     if (tcpcb.t_inpcb == (struct inpcb *)0) {
  1493.         (void) fprintf(stderr,
  1494.             "%s: PCB %x has no INPCB\n",
  1495.             progname, x);
  1496.         return(NULL);
  1497.     }
  1498. /*
  1499.  * Read INPCB for PCB and make sure it points back to the PCB.
  1500.  */
  1501.     KMPEEK(tcpcb.t_inpcb, inpcb);
  1502.     if ((caddr_t)x != inpcb.inp_ppcb) {
  1503.         (void) fprintf(stderr,
  1504.             "%s: INPCB for PCB %x not linked to it\n",
  1505.             progname, x);
  1506.         return(NULL);
  1507.     }
  1508. /*
  1509.  * Read the socket and make sure it points back to the INPCB.
  1510.  */
  1511.     KMPEEK(inpcb.inp_socket, sock);
  1512.     if (sock.so_pcb != (caddr_t)tcpcb.t_inpcb) {
  1513.         (void) fprintf(stderr,
  1514.             "%s: socket not linked to INPCB for PCB %x\n",
  1515.             progname, x);
  1516.         return(NULL);
  1517.     }
  1518. /*
  1519.  * Find the file structure that is linked to the socket.
  1520.  */
  1521.     if ((*pfp = socktofile((caddr_t)inpcb.inp_socket)) == NULL) {
  1522.         (void) fprintf(stderr,
  1523.             "%s: no file structure for socket of PCB %x\n",
  1524.             progname, x);
  1525.         return(NULL);
  1526.     }
  1527. /*
  1528.  * Construct a pseudo file name and return it.
  1529.  */
  1530.     (void) sprintf(nmbuf,
  1531.         "file %lx of socket %lx of INPCB %lx of PCB %lx",
  1532.         (long)*pfp, (long)inpcb.inp_socket, (long)tcpcb.t_inpcb, x);
  1533.     return(nmbuf);
  1534. }
  1535.  
  1536. /*
  1537.  * Convert a socket address to a file address.
  1538.  */
  1539. struct file *
  1540. socktofile(s)
  1541.     caddr_t s;
  1542. {
  1543.     register struct file *afile;
  1544.     char *calloc();
  1545.     register struct file *fp;
  1546.     static struct file *ftp;
  1547.     static int nfile = -1;
  1548.     static struct file *xfile = NULL;
  1549. /*
  1550.  * Read the size of file table, allocate space
  1551.  * for it, and read the file table pointer (once).
  1552.  */
  1553.     if (nfile < 0) {
  1554.         KMPEEK(nl[SNFILE].n_value, nfile);
  1555.         xfile = (struct file *) calloc((unsigned)nfile, sizeof (struct file));
  1556.         KMPEEK(nl[SFIL].n_value, ftp);
  1557.     }
  1558. /*
  1559.  * Read the file table and search for an in-use
  1560.  * socket file with a matching data address.
  1561.  */
  1562.     (void)peek(kmem, (ls_t)ftp, (char *)xfile, nfile * sizeof(struct file), "_file",
  1563.             __LINE__, 0);
  1564.     for (fp = xfile, afile = ftp; fp < &xfile[nfile]; fp++, afile++) {
  1565.         if (fp->f_count && fp->f_type == DTYPE_SOCKET
  1566.         &&  s == fp->f_data)
  1567.             return(afile);
  1568.     }
  1569.     return(NULL);
  1570. }
  1571.  
  1572. peek(file, fromwhere, intowhat, size, msg, line, errflg)
  1573. char *intowhat, *msg;
  1574. ls_t fromwhere;
  1575. {
  1576.     extern errno;
  1577.     extern char *sys_errlist[];
  1578.     int n;
  1579.  
  1580. #if defined sun && SunOS >= 4
  1581.     if (file == kmem) {
  1582.         if ((n = kvm_read(kd,
  1583.                  (unsigned long)(fromwhere), 
  1584.                  (char *)(intowhat),
  1585.                   size
  1586.  
  1587.                 )) == -1
  1588.            ) goto bad;
  1589.         return n;
  1590.     }
  1591. #endif
  1592.     if (lseek(file, k_opt?vtophys(fromwhere):fromwhere, 0) == -1) goto bad;
  1593.     if ((n = read(file, intowhat, size)) == -1) goto bad;
  1594.     return n;
  1595. bad:
  1596.     if (errflg > 0) return 0;
  1597.     (void)fprintf (
  1598.         stderr,
  1599.         "%s: peek from 0x%x into 0x%x failed for %s at line %d (%s)\n",
  1600.         progname,
  1601.         fromwhere,
  1602.         intowhat,
  1603.         msg,
  1604.         line,
  1605.         sys_errlist[errno]
  1606.     );
  1607.     if (error == 0) exit(1);
  1608.     return 0;
  1609. }
  1610.  
  1611. #if defined sun && SunOS >= 4 && SunOSrel >= 1
  1612. getuofiles(locu, segu)
  1613. register struct user *locu;
  1614. register struct seguser *segu;
  1615. {
  1616.     nofile = locu->u_lastfile + 1;
  1617.     if (nofile <= 0) return;
  1618.     ofilep = locu->u_ofile;
  1619.     if (ofilep == segu->segu_u.u_ofile_arr)
  1620.         ofilep = locu->u_ofile_arr;
  1621.     else {
  1622.         (void)peek(kmem, (ls_t)(ofilep), (char *)(ofile_arr), 
  1623.              nofile*sizeof (struct file *), "ofile_arr", __LINE__, 0);
  1624.         ofilep = ofile_arr;
  1625.     }
  1626. }
  1627. #endif
  1628.