home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / unix / volume18 / ofiles.new < prev    next >
Encoding:
Text File  |  1989-03-25  |  36.0 KB  |  1,540 lines

  1. Path: wugate!wucs1!uunet!bbn.com!rsalz
  2. From: rsalz@uunet.uu.net (Rich Salz)
  3. Newsgroups: comp.sources.unix
  4. Subject: v18i057:  REVISED ofiles, doesn't need Sun source
  5. Message-ID: <1611@fig.bbn.com>
  6. Date: 24 Mar 89 17:43:04 GMT
  7. Lines: 1530
  8. Approved: rsalz@uunet.UU.NET
  9.  
  10. Submitted-by: abe@mace.cc.purdue.edu (Vic Abell)
  11. Posting-number: Volume 18, Issue 57
  12. Archive-name: ofiles.new
  13.  
  14. Here's a new shar of ofiles.  When I saw how little ofiles needed
  15. from /usr/src/sys/specfs/snode.h, I decided to define it in ofiles.c.
  16. This version should now compile for folks who do not have Sun sources.
  17.  
  18. Sorry for the problem.  I'm just about done with fstat, and I have
  19. made sure it doesn't have the same difficulty.
  20.  
  21. Vic Abell
  22.  
  23. #    This is a shell archive.
  24. #    Remove everything above and including the cut line.
  25. #    Then run the rest of the file through sh.
  26. #----cut here-----cut here-----cut here-----cut here----#
  27. #!/bin/sh
  28. # shar:    Shell Archiver
  29. #    Run the following text with /bin/sh to create:
  30. #    README
  31. #    Makefile
  32. #    ofiles.c
  33. #    ofiles.8l
  34. # This archive created: Thu Mar 23 19:42:54 1989
  35. # By:    Vic Abell (Purdue University)
  36. echo shar: extracting README '(1315 characters)'
  37. sed 's/^XX//' << \SHAR_EOF > README
  38. XXOfiles shows the owner of an open file or network connection.
  39. XX
  40. XXC. Spencer is the original author of ofiles.  Michael Ditto, Tom Dunigan,
  41. XXAlexander Dupuy, Gary Nebbett and Richard Tobin made contributions.  Mike
  42. XXSpitzer, Ray Moody and Vik Lall of the Purdue University Computing Center
  43. XX(PUCC) adapted ofiles to a number of different UNIX environments.  I added
  44. XXthe network connection option.
  45. XX
  46. XXOfiles compiles and runs on 4.3BSD, DYNIX 3.0.12 (Balance) and 3.0.14
  47. XX(Symmetry), SunOS 4.0 and ULTRIX 2.2.  It is free of lint on those systems
  48. XXaccording to the lint libraries in use at PUCC.
  49. XX
  50. XXSpecial notes:
  51. XX
  52. XX    1.  A "generic" Makefile is included.  You may have to adjust it
  53. XX        to your local conditions.
  54. XX
  55. XX    2.  SunOS 4.0 loading requires "-lkvm", so modify the Makefile
  56. XX        accordingly when you port ofiles to your Sun system.
  57. XX
  58. XX    3.  Ofiles needs permission to read /dev/drum (swap files), /dev/kmem
  59. XX        and /dev/mem.  PUCC uses a "setgid kmem" approach - i. e.,
  60. XX        /dev/{drum,kmem,mem} are in the kmem group and ofiles has mode
  61. XX        2755, group kmem.  The Makefile install rule implements this
  62. XX        convention.
  63. XX
  64. XXThe ofiles distribution includes:
  65. XX
  66. XX    README        this file
  67. XX    Makefile    a generic Makefile
  68. XX    ofiles.c    source
  69. XX    ofiles.8l    man page
  70. XX
  71. XXVic Abell, abe@mace.cc.purdue.edu
  72. XXPurdue University Computing Center
  73. XXMarch 22, 1989
  74. SHAR_EOF
  75. if test 1315 -ne "`wc -c README`"
  76. then
  77. echo shar: error transmitting README '(should have been 1315 characters)'
  78. fi
  79. echo shar: extracting Makefile '(738 characters)'
  80. sed 's/^XX//' << \SHAR_EOF > Makefile
  81. XX#
  82. XX#    Makefile for ofiles
  83. XX#
  84. XX
  85. XXPROG=    ofiles
  86. XXBIN=    ${DESTDIR}/usr/local/etc
  87. XX
  88. XXI=/usr/include
  89. XXS=/usr/include/sys
  90. XXL=/usr/include/local
  91. XX
  92. XXINCLUDE=
  93. XXDEBUG=    -O
  94. XXCDEFS=  
  95. XXCFLAGS= ${DEBUG} ${CDEFS} ${INCLUDE}
  96. XX
  97. XXHDR=    
  98. XXONEC=    ofiles.c
  99. XXOTHER=    
  100. XXSOURCE=    Makefile ${HDR} ${ONEC} ${OTHER}
  101. XX
  102. XXall: ${PROG}
  103. XX
  104. XX# SunOS 4.0 needs -lkvm in the following rule
  105. XX
  106. XX${PROG}:
  107. XX    ${CC} -o $@ ${CFLAGS} ${ONEC} 
  108. XX
  109. XXclean: FRC
  110. XX    rm -f Makefile.bak ${PROG} *.o a.out core errs tags
  111. XX
  112. XXinstall: all FRC
  113. XX    install -cs -m 2755 -g kmem ${PROG} ${BIN}
  114. XX
  115. XXlint: ${HDR} ${ONEC} FRC
  116. XX    lint ${CDEFS} ${INCLUDE} ${ONEC}
  117. XX
  118. XXprint: source FRC
  119. XX    lpr -J'${PROG} source' ${SOURCE}
  120. XX
  121. XXsource: ${SOURCE}
  122. XX
  123. XXspotless: clean
  124. XX    rcsclean ${SOURCE}
  125. XX
  126. XXtags: ${HDR} ${ONEC}
  127. XX    ctags -t ${HDR} ${ONEC}
  128. XX
  129. XX${SOURCE}:
  130. XX    co -q $@
  131. XX
  132. XXFRC:
  133. XX
  134. SHAR_EOF
  135. if test 738 -ne "`wc -c Makefile`"
  136. then
  137. echo shar: error transmitting Makefile '(should have been 738 characters)'
  138. fi
  139. echo shar: extracting ofiles.c '(24522 characters)'
  140. sed 's/^XX//' << \SHAR_EOF > ofiles.c
  141. XX/*    ofiles.c
  142. XX *
  143. XX *    ofiles [-d ] [-k nlist core] [-n] [-p] args
  144. XX *
  145. XX *    Show owner of open file or network connection.
  146. XX *
  147. XX *    Reports owner, process ID, access type, command and inode number.
  148. XX *
  149. XX *    -d        select verbose debugging output
  150. XX *
  151. XX *    -k nlist core    specifies alternative name list and core files
  152. XX *            (DYNIX only)
  153. XX *
  154. XX *    -n        interpret names as network connection, hexadecimal
  155. XX *            Protocol Control Block (PCB) addresses
  156. XX *
  157. XX *    -p          gives brief (pids only) report
  158. XX *
  159. XX *    names        file names, file system names or network connection
  160. XX *            PCB addresses
  161. XX *
  162. XX *    Stat each file or file system argument and scan the process table,
  163. XX *    looking for a match in the associated user structure's file lists.
  164. XX *
  165. XX *    Follow each PCB arg to the Internet Protocol Control Block (INPCB),
  166. XX *    thence to the socket; then scan the file table to find the file
  167. XX *    structure address associated with the socket; finally, scan the
  168. XX *    process table, looking for a nacth in the associated user structure's
  169. XX *    file lists.
  170. XX *
  171. XX *    Doesn't handlle remote NFS files.
  172. XX */
  173. XX
  174. XX/*
  175. XX *    Authors:
  176. XX *
  177. XX *    The orignal author is:
  178. XX *
  179. XX *        C. Spencer
  180. XX *
  181. XX *    Contributors include:
  182. XX *
  183. XX *        Michael Ditto
  184. XX *        Tom Dunigan
  185. XX *        Alexander Dupuy
  186. XX *        Greg Nebbett
  187. XX *        Richard Tobin
  188. XX *
  189. XX *    From the Purdue University Computing Center:
  190. XX *
  191. XX *        Mike Spitzer         converted to 4.3BSD, DYNIX 3.0.1[24]
  192. XX *        Ray Moody        SunOS 4.0 and ULTRIX 2.2
  193. XX *        Vik Lall
  194. XX *
  195. XX *        Vic Abell        added socket option and removed lint
  196. XX *                
  197. XX */
  198. XX
  199. XX#ifndef lint
  200. XXstatic char rcsid[]="$Header: /usr/src/local/etc/ofiles/RCS/ofiles.c,v 1.8 89/03/21 12:29:30 abe Exp Locker: abe $";
  201. XX#endif /* lint */
  202. XX
  203. XX#include <sys/param.h>
  204. XX#include <sys/dir.h>
  205. XX#include <sys/user.h>
  206. XX
  207. XX#ifdef DYNIX
  208. XX#define KERNEL
  209. XX#include <sys/file.h>
  210. XX#include <sys/vnode.h>
  211. XX#include <sys/inode.h>
  212. XX#undef KERNEL
  213. XX#else
  214. XX#define KERNEL
  215. XX#include <sys/file.h>
  216. XX#ifndef sun
  217. XX#include <sys/inode.h>
  218. XX#endif
  219. XX#undef KERNEL
  220. XX#endif
  221. XX
  222. XX#include <machine/pte.h>
  223. XX#if !defined(ultrix) && !defined(sun)
  224. XX#include <machine/machparam.h>
  225. XX#endif
  226. XX#include <sys/proc.h>
  227. XX#include <nlist.h>
  228. XX#include <sys/stat.h>
  229. XX#include <pwd.h>
  230. XX#include <fstab.h>
  231. XX#include <sys/vmmac.h>
  232. XX#include <stdio.h>
  233. XX
  234. XX#ifdef sun
  235. XX#include <sys/vnode.h>
  236. XX#include <ufs/inode.h>
  237. XX#include <kvm.h>
  238. XXstruct snode {
  239. XX    struct snode *s_next;
  240. XX    struct vnode s_vnode;
  241. XX    struct vnode *s_realvp;
  242. XX    struct vnode *s_bdevvp;
  243. XX    u_short s_flag;
  244. XX    dev_t s_dev;
  245. XX};
  246. XXkvm_t    *kd;
  247. XX#endif
  248. XX
  249. XX#ifdef ultrix
  250. XX#include <sys/gnode.h>
  251. XX#include <sys/gnode_common.h>
  252. XX#include <machine/param.h>
  253. XX#endif
  254. XX
  255. XX#include <sys/socket.h>
  256. XX#include <sys/socketvar.h>
  257. XX#include <net/route.h>
  258. XX#include <netinet/in.h>
  259. XX#include <netinet/in_pcb.h>
  260. XX#include <netinet/tcp.h>
  261. XX#include <netinet/tcp_fsm.h>
  262. XX#include <netinet/tcp_timer.h>
  263. XX#include <netinet/tcp_var.h>
  264. XX
  265. XX#define CDIR    01
  266. XX#define OFILE    02
  267. XX#define RDIR    04
  268. XX#define SHFILE    010
  269. XX#define EXFILE    020
  270. XX#define SOCKET  040
  271. XX
  272. XXchar *namelist;
  273. XXchar *corefile;
  274. XXint k_opt = 0;
  275. XXint n_opt = 0;
  276. XX
  277. XX#ifdef    ultrix
  278. XX#define    ls_t    long
  279. XX#else
  280. XX#define ls_t    off_t
  281. XX#endif
  282. XX
  283. XX#ifdef    sun
  284. XXchar    *sprintf();
  285. XX#endif
  286. XX
  287. XXls_t lseek(), vtophys();
  288. XX
  289. XXvoid eread(), eseek();
  290. XX#ifdef    ultrix
  291. XXvoid exit(), nlist(), perror();
  292. XX#endif
  293. XX
  294. XXint nproc;        /* number of entries in proc table         */
  295. XXint mem;        /* fd for /dev/mem                */
  296. XXint kmem;
  297. XXint swap;        /* fd for /dev/swap                */
  298. XXlong procbase;
  299. XXint ppid = -1;        /* previously display PID */
  300. XX
  301. XXint dirinode;        /* directory (CDIR or RDIR) inode */
  302. XXint opninode;        /* save inode of open file */
  303. XXint pids_only = 0;    /* if non-zero, only output process ids    */
  304. XX
  305. XXchar *progname;
  306. XXstruct nlist nl[] = {
  307. XX#define    X_PROC        0
  308. XX    { "_proc" },
  309. XX#define X_NPROC     1
  310. XX    {"_nproc"},
  311. XX#define X_USRPTMA    2
  312. XX        {"_Usrptmap"},    
  313. XX#define X_USRPT        3
  314. XX    {"_usrpt"},
  315. XX#define X_SYSMAP    4
  316. XX    {"_Sysmap"},
  317. XX#define    SFIL        5
  318. XX    { "_file" },
  319. XX#define    SNFILE        6
  320. XX    { "_nfile" },
  321. XX    { "" },
  322. XX};
  323. XX
  324. XX#ifndef    DYNIX
  325. XXstruct pte *usrpt, *Usrptma;
  326. XX#endif
  327. XX
  328. XXint debug;
  329. XX
  330. XXmain(argc, argv)
  331. XX    int     argc;
  332. XX    char    *argv[];
  333. XX{
  334. XX
  335. XX#ifdef ultrix
  336. XX    struct gnode *i, *getinode();
  337. XX#else
  338. XX    struct inode *i, *getinode();
  339. XX#endif
  340. XX    struct stat s;
  341. XX    struct user *u, *getuser();
  342. XX    struct proc p;
  343. XX    register int filen, flags, procn;
  344. XX    register char *filename, *fsname;
  345. XX    struct fstab *fs, *getfsfile(), *getfsspec();
  346. XX    char *getsockfp(), *rindex();
  347. XX    struct file *fp;
  348. XX    int ax, err, findf, nmct;
  349. XX    char *ap;
  350. XX    int exitval = 0;
  351. XX
  352. XX#ifdef    lint
  353. XX/*
  354. XX * The following code satisfies lint for KERNEL symbols.
  355. XX * This program is lint-free under 4.3BSD, DYNIX 3.0.1[24], SunOS 4.0
  356. XX * and ULTRIX 2.2, using the lint libraries of the systems at the
  357. XX * Purdue University Computing Center.
  358. XX */
  359. XX#if    !defined(ultrix) && !defined(DYNIX) && !defined(sun)
  360. XX    long lintlong;
  361. XX#endif
  362. XX#ifdef    ultrix
  363. XX    struct nch *lintnch;
  364. XX    float lintfloat;
  365. XX#endif
  366. XX#if    !defined(DYNIX)
  367. XX    file = fileNFILE = NULL;
  368. XX    fp = file;
  369. XX    fp = fileNFILE;
  370. XX    nfile = 0;
  371. XX    filen = nfile;
  372. XX#endif
  373. XX#if    !defined(ultrix) && !defined(DYNIX) && !defined(sun)
  374. XX    inode = inodeNINODE = rootdir = NULL;
  375. XX    i = inode;
  376. XX    i = inodeNINODE;
  377. XX    i = rootdir;
  378. XX    ninode = 0;
  379. XX    nextinodeid = 0l;
  380. XX    lintlong = nextinodeid;
  381. XX    nextinodeid = lintlong;
  382. XX    filen = ninode;
  383. XX#endif
  384. XX#ifdef    sun
  385. XX    tcp_ttl = 0;
  386. XX    filen  = tcp_ttl;
  387. XX#endif
  388. XX#ifdef    ultrix
  389. XX    nch = NULL;
  390. XX    lintnch = nch;
  391. XX    nch = lintnch;
  392. XX    nchsize = 0;
  393. XX    filen = nchsize;
  394. XX    tcp_alpha = tcp_beta = 0.0;
  395. XX    lintfloat = tcp_alpha;
  396. XX    lintfloat = tcp_beta;
  397. XX    tcp_alpha = lintfloat;
  398. XX#endif
  399. XX#endif    /* lint */
  400. XX
  401. XX    if ((progname = rindex(argv[0], '/')))
  402. XX        progname++;
  403. XX    else
  404. XX        progname = argv[0];
  405. XX
  406. XX    if (argc == 1) {
  407. XX
  408. XXusage:
  409. XX
  410. XX#ifdef    DYNIX
  411. XX        (void) fprintf(stderr,
  412. XX            "usage: %s [-d ] [-k nlist core] [-n] [-p] names\n",
  413. XX            progname);
  414. XX#else
  415. XX        (void) fprintf(stderr,
  416. XX            "usage: %s [-d ] [-n] [-p] names\n", progname);
  417. XX#endif
  418. XX        (void) fprintf(stderr, "\t-d    = select verbose debugging output\n");
  419. XX#ifdef    DYNIX
  420. XX        (void) fprintf(stderr,
  421. XX            "\t-k    = use specified nlist and core files\n");
  422. XX#endif
  423. XX        (void) fprintf(stderr,
  424. XX            "\t-n    = interpret names as network connection, hexadecimal,\n");
  425. XX        (void) fprintf(stderr,
  426. XX            "\t        Protocol Control Block (PCB) addresses, as supplied\n");
  427. XX        (void) fprintf(stderr,
  428. XX            "\t        by netstat's -A option\n");
  429. XX        (void) fprintf(stderr, "\t-p    = print only process IDs\n");
  430. XX        (void) fprintf(stderr,
  431. XX            "\tnames = file names or PCB addresses\n");
  432. XX        exit(exitval);
  433. XX    }
  434. XX
  435. XX    /* check for switches */
  436. XX    for (err = 0, ax = 1; ax < argc; ax++) {
  437. XX        ap = argv[ax];
  438. XX        if (*ap++ != '-')
  439. XX            break;
  440. XX        while (*ap) {
  441. XX            switch (*ap++) {
  442. XX
  443. XX            case 'd':
  444. XX                debug = 1;
  445. XX                break;
  446. XX#ifdef    DYNIX
  447. XX            case 'k':
  448. XX                if ((ax + 2) >= argc) {
  449. XX                    (void) fprintf(stderr,
  450. XX                        "%s: no nlist/core after -k\n",
  451. XX                        progname);
  452. XX                    err++;
  453. XX                } else {
  454. XX                    namelist = argv[++ax];
  455. XX                    corefile = argv[++ax];
  456. XX                    k_opt = 1;
  457. XX                    continue;
  458. XX                }
  459. XX                break;
  460. XX#endif
  461. XX            case 'n':
  462. XX                n_opt++;
  463. XX                break;
  464. XX
  465. XX            case 'p':
  466. XX                pids_only = 1;
  467. XX                break;
  468. XX
  469. XX            default:
  470. XX                (void) fprintf(stderr,
  471. XX                    "%s: unknown switch - %c\n",
  472. XX                    progname, *(ap - 1));
  473. XX                err++;
  474. XX            }
  475. XX        }
  476. XX    }
  477. XX    if (ax >= argc) {
  478. XX        (void) fprintf(stderr, "%s: no names specified\n", progname);
  479. XX        err++;
  480. XX    }
  481. XX    if (err) {
  482. XX        exitval = 1;
  483. XX        goto usage;
  484. XX    }
  485. XX
  486. XX#ifdef sun
  487. XX        if ((kd = kvm_open (NULL, NULL, NULL, O_RDONLY)) == 0) {
  488. XX        (void) fprintf(stderr, "%s: can't access memory: ",
  489. XX            progname);
  490. XX            perror ("");
  491. XX        exit(1);
  492. XX    }
  493. XX#endif
  494. XX    if ((mem = open("/dev/mem", 0)) < 0) {
  495. XX        (void) fprintf(stderr, "%s: /dev/mem: ", progname);
  496. XX        perror("");
  497. XX        exit(1);
  498. XX    }
  499. XX    if (k_opt) {
  500. XX        if ((kmem = open(corefile, 0)) < 0) {
  501. XX            (void) fprintf(stderr, "%s: %s: ",
  502. XX                progname, corefile);
  503. XX            perror("");
  504. XX            exit(1);
  505. XX        }
  506. XX    } else {
  507. XX        if ((kmem = open("/dev/kmem", 0)) < 0) {
  508. XX            (void) fprintf(stderr, "%s: /dev/kmem: ", progname);
  509. XX            perror("");
  510. XX            exit(1);
  511. XX        }
  512. XX    }
  513. XX    if (!k_opt) 
  514. XX        if ((swap = open("/dev/drum", 0)) < 0) {
  515. XX            (void) fprintf(stderr, "%s: /dev/drum: ", progname);
  516. XX            perror("");
  517. XX            exit(1);
  518. XX        }
  519. XX
  520. XX    getsyms();
  521. XX
  522. XX    for (err = 0, nmct = argc - ax; ax < argc; ax++) {
  523. XX        /* if -n, then arg is a PCB */
  524. XX        if (n_opt) {
  525. XX            if ((filename = getsockfp(argv[ax], &fp)) == NULL) {
  526. XX                err++;
  527. XX                continue;
  528. XX            }
  529. XX            fsname = "";
  530. XX        } else {
  531. XX            /* assume arg is  a filesystem */
  532. XX            if ((fs = getfsfile(argv[ax])) != NULL) {
  533. XX                fsname = argv[ax];
  534. XX                if (strcmp(".", argv[ax]) == 0)
  535. XX                    filename = argv[ax];
  536. XX                else
  537. XX                    filename = fs->fs_spec;
  538. XX            /* maybe it's the device name for a filesystem */
  539. XX            } else if ((fs = getfsspec(argv[ax])) != NULL) {
  540. XX                filename = argv[ax];
  541. XX                fsname = fs->fs_file;
  542. XX            /* probably a regular file */
  543. XX            } else {
  544. XX                filename = argv[ax];
  545. XX                fsname = "";
  546. XX            }
  547. XX            if (stat(filename, &s)) {
  548. XX                (void) fprintf(stderr, "%s: can't stat %s: ",
  549. XX                    progname, filename);
  550. XX                perror("");
  551. XX                err++;
  552. XX                continue;
  553. XX            }
  554. XX            if (debug)
  555. XX                (void) printf(
  556. XX                    "stat dev %x ino %d mode %x rdev %x\n",
  557. XX                    s.st_dev, s.st_ino, s.st_mode,
  558. XX                    s.st_rdev);
  559. XX        }
  560. XX        if (! pids_only) {
  561. XX            (void) printf("%s\t%s", filename, fsname);
  562. XX            if (!n_opt) {
  563. XX                if ((s.st_mode & S_IFMT) == S_IFDIR)
  564. XX                    (void) printf("(directory)");
  565. XX            }
  566. XX            (void) printf("\n%-8.8s  %5s  %-6.6s  FD  %-14.14s",
  567. XX                "USER", "PID", "TYPE", "CMD");
  568. XX            if (!n_opt)
  569. XX                (void) printf("  INODE");
  570. XX            (void) printf("\n");
  571. XX        }
  572. XX        for (findf = procn = 0; procn < nproc; procn++) {
  573. XX            procslot(procn, &p);
  574. XX            flags = 0;
  575. XX            if (p.p_stat == 0 || p.p_stat == SZOMB) 
  576. XX                continue;
  577. XX#ifdef sun
  578. XX                u = kvm_getu(kd, &p);
  579. XX#else
  580. XX            u = getuser(&p);
  581. XX#endif
  582. XX
  583. XX            if ( u == (struct user *)NULL)
  584. XX                continue;
  585. XX            if (debug)
  586. XX                (void) printf("pid %d uid %d cmd %s\n", p.p_pid,
  587. XX                    p.p_uid, u->u_comm);
  588. XX            if (!n_opt) {
  589. XX                i = getinode(u->u_rdir, "rdir");
  590. XX                if (check(&s, i)) {
  591. XX                    dirinode = s.st_ino;
  592. XX                    gotone(u, &p, -1, RDIR);
  593. XX                    findf++;
  594. XX                }
  595. XX                i = getinode(u->u_cdir, "cdir");
  596. XX                if (check(&s, i)) {
  597. XX                    dirinode = s.st_ino;
  598. XX                    gotone(u, &p, -1, CDIR);
  599. XX                    findf++;
  600. XX                }
  601. XX            }
  602. XX#ifdef    DYNIX
  603. XX            for (filen = 0; filen < u->u_nofile; filen++)
  604. XX#else
  605. XX            for (filen = 0; filen < NOFILE; filen++)
  606. XX#endif    
  607. XX            {
  608. XX                struct file f;
  609. XX
  610. XX                flags = 0;
  611. XX                if (n_opt) {
  612. XX#ifdef    DYNIX
  613. XX                    if (u->u_lofile[filen].of_file != fp)
  614. XX#else
  615. XX                    if (u->u_ofile[filen] != fp)
  616. XX#endif
  617. XX                        continue;
  618. XX                } else {
  619. XX#ifdef    DYNIX
  620. XX                    if (u->u_lofile[filen].of_file == NULL)
  621. XX                        continue;
  622. XX#else
  623. XX                    if (u->u_ofile[filen] == NULL)
  624. XX                        continue;
  625. XX#endif
  626. XX                }
  627. XX
  628. XX                if (k_opt)
  629. XX#ifdef    DYNIX
  630. XX                    eseek(kmem, vtophys((ls_t)u->u_lofile[filen].of_file), 0, "file");
  631. XX#else
  632. XX                eseek(kmem, vtophys((ls_t)u->u_ofile[filen]), 0, "file");
  633. XX#endif 
  634. XX                else
  635. XX#ifdef    DYNIX
  636. XX                    eseek(kmem, (ls_t)u->u_lofile[filen].of_file, 0, "file");
  637. XX#else
  638. XX                eseek(kmem, (ls_t)u->u_ofile[filen], 0, "file");
  639. XX#endif
  640. XX                eread(kmem, (char *)&f, sizeof(f), "file");
  641. XX
  642. XX                if (f.f_count > 0) {
  643. XX                    if (n_opt && f.f_type == DTYPE_SOCKET) {
  644. XX                        gotone(u, &p, filen, SOCKET);
  645. XX                        findf++;
  646. XX                        continue;
  647. XX                    }
  648. XX#if    defined(DYNIX) || defined(sun)
  649. XX                    if (f.f_type != DTYPE_VNODE)
  650. XX#else
  651. XX                    if (f.f_type != DTYPE_INODE)
  652. XX#endif
  653. XX                        continue;
  654. XX#if    defined(DYNIX) || defined(sun)
  655. XX                    i = getinode((struct vnode *)f.f_data,
  656. XX                        "ofile");
  657. XX#else
  658. XX#ifdef    ultrix
  659. XX                    i = getinode((struct gnode *)f.f_data,
  660. XX                        "ofile");
  661. XX#else
  662. XX                    i = getinode((struct inode *)f.f_data,
  663. XX                        "ofile");
  664. XX#endif
  665. XX#endif
  666. XX                    if (check(&s, i)) {
  667. XX#if !defined(ultrix)
  668. XX                        opninode = i->i_number;
  669. XX#else
  670. XX                        opninode = (int)i->g_req.gr_number;
  671. XX#endif
  672. XX                        flags |= OFILE;
  673. XX                        if (f.f_flag & FEXLOCK) {
  674. XX                            flags |= EXFILE;
  675. XX                        }
  676. XX                        if (f.f_flag & FSHLOCK) {
  677. XX                            flags |= SHFILE;
  678. XX                        }
  679. XX                        gotone(u, &p, filen, flags);
  680. XX                        findf++;
  681. XX                    }
  682. XX                }
  683. XX            }
  684. XX        }
  685. XX        if (findf)
  686. XX            nmct--;
  687. XX        if (! pids_only) {
  688. XX                (void) printf("\n");
  689. XX            (void) fflush(stdout);
  690. XX        }
  691. XX    }
  692. XX    if (pids_only && ppid != -1) {
  693. XX        (void) printf("\n");
  694. XX        (void) fflush(stdout);
  695. XX    }
  696. XX    exitval = (err || nmct) ? 1 : 0;
  697. XX    exit(exitval);
  698. XX}        
  699. XX
  700. XX/*
  701. XX * print the name of the user owning process "p" and the pid of that process
  702. XX */
  703. XXgotone(u, p, fd, f)
  704. XX    struct user *u;
  705. XX    struct proc *p;
  706. XX    int fd;
  707. XX    int f;
  708. XX{
  709. XX    char *ty, tybuf[8], *strcat(), *strcpy();
  710. XX    struct passwd *getpwuid();
  711. XX    register struct passwd *pw;
  712. XX
  713. XX    /* only print pids and return */
  714. XX    if (pids_only) {
  715. XX        if (ppid != p->p_pid) {
  716. XX            if (ppid != -1)
  717. XX                (void) printf(" ");
  718. XX            (void) printf("%d", p->p_pid);
  719. XX            (void) fflush(stdout);
  720. XX            ppid = p->p_pid;
  721. XX        }
  722. XX        return;
  723. XX    }
  724. XX    pw = getpwuid((int)p->p_uid);
  725. XX    if (pw)
  726. XX        (void) printf("%-8.8s  ", pw->pw_name );
  727. XX    else
  728. XX        (void) printf("%-8d  ", p->p_uid);
  729. XX    (void) printf("%5d  ", p->p_pid);
  730. XX    if (f & OFILE) {
  731. XX        (void) strcpy(tybuf, "file");
  732. XX        ty = tybuf;
  733. XX        if (f & SHFILE)
  734. XX            (void) strcat(ty, "/s");
  735. XX        else if (f & EXFILE)
  736. XX            (void) strcat(ty, "/x");
  737. XX    } else if (f & CDIR)
  738. XX        ty = "cwd";
  739. XX    else if (f & RDIR)
  740. XX        ty = "rdir";
  741. XX    else if (f & SOCKET)
  742. XX        ty = "sock";
  743. XX    else
  744. XX        ty = "";
  745. XX    (void) printf("%-6.6s  ", ty);
  746. XX    if (fd >= 0)
  747. XX        (void) printf("%2d  ", fd);
  748. XX    else
  749. XX        (void) printf("    ");
  750. XX    (void) printf("%-14.14s", u->u_comm);
  751. XX    if (f & OFILE)
  752. XX        (void) printf("  %5d", opninode);
  753. XX    else if (f & (CDIR|RDIR))
  754. XX        (void) printf("  %5d", dirinode);
  755. XX    (void) printf("\n");
  756. XX    return;
  757. XX}
  758. XX
  759. XX/*
  760. XX * is inode "i" on device "s"? returns TRUE or FALSE 
  761. XX */
  762. XXcheck(s, i)
  763. XX    struct stat *s;
  764. XX#ifdef ultrix
  765. XX    struct gnode *i;
  766. XX#else
  767. XX    struct inode *i;
  768. XX#endif
  769. XX{
  770. XX    if (s == (struct stat *)NULL)
  771. XX        return 0;
  772. XX#ifdef ultrix
  773. XX    if (i == (struct gnode *)NULL)
  774. XX        return 0;
  775. XX    if ((s->st_mode & S_IFMT) == S_IFBLK && s->st_rdev == i->g_dev)
  776. XX            return 1;
  777. XX    else if ((s->st_dev == i->g_dev) && (s->st_ino == i->g_req.gr_number))
  778. XX            return 1;
  779. XX#else
  780. XX    if (i == (struct inode *)NULL) return 0;
  781. XX    if ((s->st_mode & S_IFMT) == S_IFBLK && s->st_rdev == i->i_dev)
  782. XX            return 1;
  783. XX    else if ((s->st_dev == i->i_dev) && (s->st_ino == i->i_number))
  784. XX            return 1;
  785. XX#endif
  786. XX#ifdef sun
  787. XX    else if (s->st_rdev == i->i_dev && i->i_number == 0)
  788. XX            return 1;
  789. XX#endif
  790. XX    else return 0;
  791. XX}
  792. XX
  793. XX
  794. XX/* 
  795. XX *    getinode - read an inode from from mem at address "addr"
  796. XX *           return pointer to inode struct. 
  797. XX */
  798. XX#if defined(DYNIX) || defined(sun)
  799. XXstruct inode *
  800. XXgetinode(ip, s)
  801. XX    struct vnode *ip;
  802. XX    char *s;
  803. XX{
  804. XX    static struct inode i;
  805. XX    static struct vnode v;
  806. XX#ifdef    sun
  807. XX    struct snode sn;
  808. XX#endif
  809. XX
  810. XX    if (ip == NULL)
  811. XX        return(NULL);
  812. XX    if (k_opt)
  813. XX        eseek(kmem, vtophys((ls_t)ip), 0, "vnode");
  814. XX    else
  815. XX        eseek(kmem, (ls_t)ip, 0, "vnode");
  816. XX    eread(kmem, (char *)&v, sizeof(v), "vnode");
  817. XX    if (debug)
  818. XX        (void) printf("vnode %s at %x %x dev=%x vtype=%d inode@%x\n",
  819. XX             s, ip, v.v_flag, v.v_rdev, v.v_type, v.v_data);
  820. XX    if (k_opt)
  821. XX        eseek(kmem, vtophys((ls_t)v.v_data), 0, "inode");
  822. XX    else
  823. XX        eseek(kmem, (ls_t)v.v_data, 0, "inode");
  824. XX#ifdef    sun
  825. XX    if (v.v_type == VBLK || v.v_type == VCHR || v.v_type == VFIFO) {
  826. XX        eread(kmem, (char *)&sn, sizeof(sn), "snode");
  827. XX        if (debug)
  828. XX            (void) printf(
  829. XX                "snode %s at %x %x dev=%x realvp=%x bdevvp=%x\n",
  830. XX                s, ip, sn.s_vnode.v_type, sn.s_dev,
  831. XX                sn.s_realvp, sn.s_bdevvp);
  832. XX        if (sn.s_realvp || sn.s_bdevvp) {
  833. XX            eseek(kmem,
  834. XX                (sn.s_realvp) ? (ls_t)sn.s_realvp
  835. XX                          : (ls_t)sn.s_bdevvp,
  836. XX                0, "rvnode");
  837. XX            eread(kmem, (char *)&v, sizeof(v), "rvnode");
  838. XX            eseek(kmem, (ls_t)v.v_data, 0, "rinode");
  839. XX        }
  840. XX    }
  841. XX#endif
  842. XX    eread(kmem, (char *)&i, sizeof(i), "inode");
  843. XX    if (debug)
  844. XX        (void) printf("inode %s at %x %x dev=%x inode=%d vtype=%x\n",
  845. XX            s, v.v_data, i.i_flag, i.i_dev, i.i_number,
  846. XX            i.i_vnode.v_type);
  847. XX    return &i;
  848. XX}
  849. XX
  850. XX#else
  851. XX/* ARGSUSED */
  852. XX
  853. XX#ifdef ultrix
  854. XXstruct gnode *
  855. XXgetinode(ip, s)
  856. XX    struct gnode *ip;
  857. XX#else
  858. XX
  859. XXstruct inode *
  860. XXgetinode(ip, s)
  861. XX    struct inode *ip;
  862. XX#endif
  863. XX
  864. XX    char *s;
  865. XX{
  866. XX#if defined(ultrix) 
  867. XX    static struct gnode i;
  868. XX#else
  869. XX    static struct inode i;
  870. XX#endif
  871. XX
  872. XX    eseek(kmem, (ls_t)ip, 0, "inode");
  873. XX    eread(kmem, (char *)&i, sizeof(i), "inode");
  874. XX    return &i;
  875. XX}
  876. XX#endif
  877. XX
  878. XX#if !defined(sun)
  879. XX/* 
  880. XX * get user page for proc "p" from core or swap
  881. XX * return pointer to user struct
  882. XX */
  883. XX#ifdef    DYNIX
  884. XXstruct user *
  885. XXgetuser(p)
  886. XX    struct proc *p;
  887. XX{
  888. XX    int btr;
  889. XX    ls_t sp;
  890. XX    static struct user *u = NULL;
  891. XX    char *valloc();
  892. XX
  893. XX    if (u == NULL) {
  894. XX        if ((u = (struct user *) valloc(ctob(UPAGES))) == NULL) {
  895. XX            (void) fprintf(stderr,
  896. XX                "%s: can't allocate space for user structure\n",                progname);
  897. XX            exit(1);
  898. XX        }
  899. XX    }
  900. XX    btr = ctob(UPAGES);
  901. XX    if ((p->p_flag & SLOAD) == 0) {
  902. XX        if (k_opt)
  903. XX            return (struct user *)NULL;
  904. XX        sp = (ls_t) dtob(p->p_swaddr);
  905. XX        if (lseek(swap, sp, 0) != sp) {
  906. XX            if (debug) {
  907. XX                (void) fprintf(stderr,
  908. XX                    "%s: error seeking to swap for %d: ",
  909. XX                    progname, p->p_pid);
  910. XX                perror("");
  911. XX            }
  912. XX            return (struct user *)NULL;
  913. XX        }
  914. XX        if (read(swap, (char*)u, btr) != btr) {
  915. XX            if (debug) {
  916. XX                (void) fprintf(stderr,
  917. XX                    "%s: error reading swap for %d: ",
  918. XX                    progname, p->p_pid);
  919. XX                perror("");
  920. XX            }
  921. XX            return (struct user *)NULL;
  922. XX        }
  923. XX        if (debug)
  924. XX            (void) printf("read swap\n");
  925. XX    } else {
  926. XX        if (k_opt)
  927. XX            (void) lseek(kmem, vtophys((ls_t)p->p_uarea), L_SET);
  928. XX        else
  929. XX            (void) lseek(kmem, (ls_t)p->p_uarea, L_SET);
  930. XX        if (read(kmem, (char *)u, btr) != btr)
  931. XX            return (struct user *)NULL;
  932. XX    }
  933. XX    return u;
  934. XX}
  935. XX#else
  936. XXstruct user *
  937. XXgetuser(p)
  938. XX    struct proc *p;
  939. XX{
  940. XX    struct pte *ptep, apte;
  941. XX    struct pte mypgtbl[NBPG/sizeof(struct pte)];
  942. XX    int upage;
  943. XX    char *up;
  944. XX    static struct user user;
  945. XX
  946. XX    /* easy way */
  947. XX    if ((p->p_flag & SLOAD) == 0) {
  948. XX        if (k_opt)
  949. XX            return (struct user *)NULL;
  950. XX        (void) lseek(swap, (ls_t)dtob(p->p_swaddr), 0);
  951. XX        if (read(swap, (char *)&user, sizeof(struct user))==0) {
  952. XX            (void) fprintf(stderr,
  953. XX                "%s: can't get swapped user page\n",
  954. XX                progname);
  955. XX            return (struct user *)NULL;
  956. XX        }
  957. XX        if (debug)
  958. XX            (void) printf("read swap\n");
  959. XX    } else {     /* boo */
  960. XX        ptep = &Usrptma[btokmx(p->p_p0br) + p->p_szpt - 1];
  961. XX
  962. XX        /* get the page table for the user page */
  963. XX        (void) lseek(kmem, (ls_t)ptep, 0);
  964. XX        if (read(kmem, (char *)&apte, sizeof(apte)) == 0) {
  965. XX            (void) fprintf(stderr,
  966. XX                "%s: can't get user page table\n",
  967. XX                progname);
  968. XX            return (struct user *)NULL;
  969. XX        }
  970. XX
  971. XX        /* now get this user's page table */
  972. XX        eseek(mem, (ls_t)ctob(apte.pg_pfnum) ,0, "page tbl");
  973. XX        if (read(mem, (char *)mypgtbl, sizeof(mypgtbl)) == 0) {
  974. XX            (void) fprintf(stderr,
  975. XX                "%s: can't get mypgtbl.\n", progname);
  976. XX            return (struct user *)NULL;
  977. XX        }
  978. XX        /* now collect various pages of u area */
  979. XX        for (upage = 0, up = (char *)&user; upage < sizeof(struct user)/NBPG; upage++) {
  980. XX            eseek(mem, (ls_t)ctob(mypgtbl[NPTEPG-UPAGES+upage].pg_pfnum), 0, "u page");
  981. XX            if (read(mem, up, NBPG) == 0) {
  982. XX                (void) fprintf(stderr,
  983. XX                    "%s: can't get page %d of user area.\n",
  984. XX                    progname, upage);
  985. XX                return(NULL);
  986. XX            }
  987. XX            up += NBPG;
  988. XX        }
  989. XX    }
  990. XX    return &user;
  991. XX}
  992. XX#endif
  993. XX
  994. XX#endif
  995. XX/*
  996. XX * read with error checking
  997. XX */
  998. XXvoid
  999. XXeread(fd, p, size, s)
  1000. XX    int fd;
  1001. XX    char *p;
  1002. XX    int size;
  1003. XX    char *s;
  1004. XX{
  1005. XX    char buf[100];
  1006. XX    if (read(fd, p, size) != size) {
  1007. XX        if (!k_opt) {
  1008. XX            (void) fprintf(stderr, "%s: eread ", progname);
  1009. XX            perror("");
  1010. XX        }
  1011. XX        (void) sprintf(buf, "read error for %s\n", s);
  1012. XX        error(buf);
  1013. XX    }
  1014. XX}
  1015. XX
  1016. XX/*
  1017. XX * seek with error checking
  1018. XX */
  1019. XXvoid
  1020. XXeseek(fd, off, whence, s)
  1021. XX    int fd;
  1022. XX    ls_t off;
  1023. XX    int whence;
  1024. XX    char *s;
  1025. XX{
  1026. XX    ls_t ret;
  1027. XX    char buf[100];
  1028. XX
  1029. XX    if (( ret = lseek(fd, off, whence)) != off) {
  1030. XX        (void) sprintf(buf, "seek for %s failed, wanted %o, got %o.\n",
  1031. XX            s, off, ret);
  1032. XX        error(buf);
  1033. XX    }
  1034. XX}
  1035. XX
  1036. XX/*
  1037. XX * print mesg "s", don't exit if we are processing a core, 
  1038. XX * so that corrupt entries don't prevent further uncorrupted
  1039. XX * entries from showing up.
  1040. XX */
  1041. XXerror(s)
  1042. XX    char *s;
  1043. XX{
  1044. XX    if (s && !k_opt)
  1045. XX        (void) fprintf(stderr, "%s: %s", progname, s);
  1046. XX    if (!k_opt)
  1047. XX        exit(1);
  1048. XX}
  1049. XX
  1050. XX/*
  1051. XX * get some symbols form the kernel
  1052. XX */
  1053. XXgetsyms()
  1054. XX{
  1055. XX    register i;
  1056. XX
  1057. XX    if (k_opt) {
  1058. XX#ifdef    ultrix
  1059. XX        (void) nlist(namelist, nl);
  1060. XX#else    /* not ultrix */
  1061. XX        if (nlist(namelist, nl) == -1) {
  1062. XX            (void) fprintf(stderr,
  1063. XX                "%s: can't get name list from %s\n",
  1064. XX                progname, namelist);
  1065. XX            exit(1);
  1066. XX        }
  1067. XX#endif    /* ultrix */
  1068. XX    } else {
  1069. XX#ifdef    ultrix
  1070. XX        (void) nlist("/vmunix", nl);
  1071. XX#else    /* not ultrix */
  1072. XX#ifdef    DYNIX
  1073. XX        if (nlist("/dynix", nl) == -1)
  1074. XX#else    /* not DYNIX */
  1075. XX        if (nlist("/vmunix", nl) == -1)
  1076. XX#endif    /* DYNIX */
  1077. XX        {
  1078. XX            (void) fprintf(stderr,
  1079. XX                "%s: can't get name list from %s\n",
  1080. XX#ifdef    DYNIX
  1081. XX                progname, "/dynix");
  1082. XX#else    /* not DYNIX */
  1083. XX                progname, "/vmunix");
  1084. XX#endif    /* DYNIX */
  1085. XX            exit(1);
  1086. XX        }
  1087. XX#endif    /* ultrix */
  1088. XX    }
  1089. XX
  1090. XX    for (i = 0; i < (sizeof(nl)/sizeof(nl[0]))-1; i++)
  1091. XX        if (nl[i].n_value == 0) {
  1092. XX            (void) fprintf(stderr, "%s: can't nlist symbol %s\n",
  1093. XX                progname, nl[i].n_name);
  1094. XX            exit(1);
  1095. XX        }
  1096. XX
  1097. XX        eseek(kmem, (ls_t)(nl[X_PROC].n_value), 0, "procbase 1");
  1098. XX        eread(kmem, (char *)&procbase, sizeof(procbase), "procbase 1");
  1099. XX        eseek(kmem, (ls_t)(nl[X_NPROC].n_value), 0, "nproc");
  1100. XX        eread(kmem, (char *)&nproc, sizeof(nproc), "nproc");
  1101. XX
  1102. XX#ifndef    DYNIX
  1103. XX    Usrptma = (struct pte *)nl[X_USRPTMA].n_value;
  1104. XX    usrpt = (struct pte *)nl[X_USRPT].n_value;    /* used by <vmmac.h>*/
  1105. XX#endif
  1106. XX    return;
  1107. XX}
  1108. XX
  1109. XX/*
  1110. XX * read proc table entry "n" into buffer "p"
  1111. XX */
  1112. XXprocslot(n, p)
  1113. XX    int n;
  1114. XX    struct proc *p;
  1115. XX{
  1116. XX    if (k_opt)
  1117. XX        eseek(kmem, vtophys((ls_t)(procbase + (long)(n * sizeof(struct proc)))), 0, "proc");
  1118. XX    else
  1119. XX        eseek(kmem, (ls_t)(procbase + (long)(n * sizeof(struct proc))), 0, "proc");
  1120. XX    eread(kmem, (char *)p, sizeof(struct proc), "proc");
  1121. XX    return;
  1122. XX}
  1123. XX
  1124. XX/*
  1125. XX * When looking at kernel data space through /dev/mem or
  1126. XX * with a core file, do virtual memory mapping.
  1127. XX */
  1128. XXls_t
  1129. XXvtophys(vaddr)
  1130. XX    ls_t vaddr;
  1131. XX{
  1132. XX    u_int paddr;
  1133. XX    
  1134. XX#ifdef    i386
  1135. XX    if (vaddr < 8192)
  1136. XX        return vaddr;
  1137. XX#endif
  1138. XX    paddr = nl[X_SYSMAP].n_value;
  1139. XX    (void) lseek(kmem, (ls_t)paddr, 0);
  1140. XX    (void) read(kmem, (char *)&paddr, sizeof paddr);
  1141. XX    paddr = (int)((int *)paddr + (vaddr / NBPG));
  1142. XX    (void) lseek(kmem, (ls_t)paddr, 0);
  1143. XX    (void) read(kmem, (char *)&paddr, sizeof paddr);
  1144. XX#ifndef    i386
  1145. XX# define    PTBITS    0x1ff    /* 512 byte pages */
  1146. XX#else
  1147. XX# define    PTBITS    0xfff    /* 4096 byte pages */
  1148. XX#endif
  1149. XX
  1150. XX    return ((ls_t)(paddr & ~PTBITS) | (vaddr & PTBITS));
  1151. XX}
  1152. XX
  1153. XX/*
  1154. XX * get file pointer for socket
  1155. XX */
  1156. XXchar *
  1157. XXgetsockfp(cba, pfp)
  1158. XX    char *cba;
  1159. XX    struct file **pfp;
  1160. XX{
  1161. XX    register char *cp;
  1162. XX    struct file *socktofile();
  1163. XX    struct inpcb inpcb;
  1164. XX    static char nmbuf[128];
  1165. XX    struct socket sock;
  1166. XX    struct tcpcb tcpcb;
  1167. XX    long x;
  1168. XX
  1169. XX/*
  1170. XX * Convert PCB address from ASCII to hex.
  1171. XX */
  1172. XX    for (cp = cba, x = 0l; *cp; cp++) {
  1173. XX        x <<= 4;
  1174. XX        if (*cp >= '0' && *cp <= '9')
  1175. XX            x += *cp - '0';
  1176. XX        else if (*cp >= 'a' && *cp <= 'f')
  1177. XX            x += *cp - 'a' + 10;
  1178. XX        else if (*cp >= 'A' && *cp <= 'F')
  1179. XX            x += *cp - 'A' + 10;
  1180. XX        else {
  1181. XX            (void) fprintf(stderr,
  1182. XX                "%s: non-hex address, %s\n", progname, cba);
  1183. XX            return(NULL);
  1184. XX        }
  1185. XX    }
  1186. XX/*
  1187. XX * Read PCB and make sure it is in LISTEN or ESTABLISHED state.
  1188. XX */
  1189. XX    eseek(kmem, (ls_t)x, 0, "tcpcb");
  1190. XX    eread(kmem, (char *)&tcpcb, sizeof(tcpcb), "tcpcb");
  1191. XX    if (tcpcb.t_state < TCPS_LISTEN || tcpcb.t_state > TCPS_ESTABLISHED) {
  1192. XX        (void) fprintf(stderr,
  1193. XX            "%s: PCB %x not in LISTEN to ESTABLISHED state\n",
  1194. XX            progname, x);
  1195. XX        return(NULL);
  1196. XX    }
  1197. XX    if (tcpcb.t_inpcb == (struct inpcb *)0) {
  1198. XX        (void) fprintf(stderr,
  1199. XX            "%s: PCB %x has no INPCB\n",
  1200. XX            progname, x);
  1201. XX        return(NULL);
  1202. XX    }
  1203. XX/*
  1204. XX * Read INPCB for PCB and make sure it points back to the PCB.
  1205. XX */
  1206. XX    eseek(kmem, (ls_t)tcpcb.t_inpcb, 0, "inpcb");
  1207. XX    eread(kmem, (char *)&inpcb, sizeof(inpcb), "inpcb");
  1208. XX    if ((caddr_t)x != inpcb.inp_ppcb) {
  1209. XX        (void) fprintf(stderr,
  1210. XX            "%s: INPCB for PCB %x not linked to it\n",
  1211. XX            progname, x);
  1212. XX        return(NULL);
  1213. XX    }
  1214. XX/*
  1215. XX * Read the socket and make sure it points back to the INPCB.
  1216. XX */
  1217. XX    eseek(kmem, (ls_t)inpcb.inp_socket, 0, "socket");
  1218. XX    eread(kmem, (char *)&sock, sizeof(sock), "socket");
  1219. XX    if (sock.so_pcb != (caddr_t)tcpcb.t_inpcb) {
  1220. XX        (void) fprintf(stderr,
  1221. XX            "%s: socket not linked to INPCB for PCB %x\n",
  1222. XX            progname, x);
  1223. XX        return(NULL);
  1224. XX    }
  1225. XX/*
  1226. XX * Find the file structure that is linked to the socket.
  1227. XX */
  1228. XX    if ((*pfp = socktofile((caddr_t)inpcb.inp_socket)) == NULL) {
  1229. XX        (void) fprintf(stderr,
  1230. XX            "%s: no file structure for socket of PCB %x\n",
  1231. XX            progname, x);
  1232. XX        return(NULL);
  1233. XX    }
  1234. XX/*
  1235. XX * Construct a pseudo file name and return it.
  1236. XX */
  1237. XX    (void) sprintf(nmbuf,
  1238. XX        "file %lx of socket %lx of INPCB %lx of PCB %lx",
  1239. XX        (long)*pfp, (long)inpcb.inp_socket, (long)tcpcb.t_inpcb, x);
  1240. XX    return(nmbuf);
  1241. XX}
  1242. XX
  1243. XX/*
  1244. XX * Convert a socket address to a file address.
  1245. XX */
  1246. XXstruct file *
  1247. XXsocktofile(s)
  1248. XX    caddr_t s;
  1249. XX{
  1250. XX    register struct file *afile;
  1251. XX    char *calloc();
  1252. XX    register struct file *fp;
  1253. XX    static struct file *ftp;
  1254. XX    static int nfile = -1;
  1255. XX    static struct file *xfile = NULL;
  1256. XX
  1257. XX/*
  1258. XX * Read the size of file table, allocate space
  1259. XX * for it, and read the file table pointer (once).
  1260. XX */
  1261. XX    if (nfile < 0) {
  1262. XX        eseek(kmem, (ls_t)(nl[SNFILE].n_value), 0, "_nfile");
  1263. XX        eread(kmem, (char *)&nfile, sizeof(nfile), "_nfile");
  1264. XX        xfile = (struct file *) calloc((unsigned)nfile, sizeof (struct file));
  1265. XX        eseek(kmem, (ls_t)(nl[SFIL].n_value), 0, "_file");
  1266. XX        eread(kmem, (char *)&ftp, sizeof(ftp), "_file");
  1267. XX    }
  1268. XX/*
  1269. XX * Read the file table and search for an in-use
  1270. XX * socket file with a matching data address.
  1271. XX */
  1272. XX    eseek(kmem, (ls_t)ftp, 0, "_file");
  1273. XX    eread(kmem, (char *)xfile, nfile * sizeof(struct file), "_file");
  1274. XX    for (fp = xfile, afile = ftp; fp < &xfile[nfile]; fp++, afile++) {
  1275. XX        if (fp->f_count && fp->f_type == DTYPE_SOCKET
  1276. XX        &&  s == fp->f_data)
  1277. XX            return(afile);
  1278. XX    }
  1279. XX    return(NULL);
  1280. XX}
  1281. SHAR_EOF
  1282. if test 24522 -ne "`wc -c ofiles.c`"
  1283. then
  1284. echo shar: error transmitting ofiles.c '(should have been 24522 characters)'
  1285. fi
  1286. echo shar: extracting ofiles.8l '(5223 characters)'
  1287. sed 's/^XX//' << \SHAR_EOF > ofiles.8l
  1288. XX.TH OFILES 8L LOCAL
  1289. XX.SH NAME
  1290. XXofiles \- show owner of open file or network connection
  1291. XX.SH SYNOPSIS
  1292. XX.B ofiles
  1293. XX[
  1294. XX.B \-d
  1295. XX] [
  1296. XX.B \-k
  1297. XX.I nlist
  1298. XX.I core
  1299. XX] [
  1300. XX.B \-n
  1301. XX] [
  1302. XX.B \-p
  1303. XX]
  1304. XX.I names
  1305. XX.SH DESCRIPTION
  1306. XX.I Ofiles
  1307. XXdisplays the owner, process identification (PID), type, command and
  1308. XXthe number of the inode associated with an open instance of a file
  1309. XXor a network connection.
  1310. XX.PP
  1311. XXAn open file may be a regular file, a file system or a directory;
  1312. XXit is specified by its path name.
  1313. XXWhen the path name refers to a file system,
  1314. XX.I ofiles
  1315. XXwill display the owners of all open instances of files in the system.
  1316. XX.PP
  1317. XXAn open network connection is specified by the kernel address of its
  1318. XXProtocol Control Block (PCB), as displayed by
  1319. XX.IR netstat (8),
  1320. XXwhen its
  1321. XX.B \-A
  1322. XXoption is specified.
  1323. XX.SH OPTIONS
  1324. XX.I Ofiles
  1325. XXdisplays information about its usage if no options are specified.
  1326. XX.TP \w'-kXnlistXcore'u+4
  1327. XX.BI \-d
  1328. XXThis option selects verbose, debugging output.
  1329. XX.TP
  1330. XX.BI \-k \ nlist\ core
  1331. XXThis option may be used only on DYNIX hosts.
  1332. XXIt sets optional name list and core file paths.
  1333. XX.IP
  1334. XX.I Nlist
  1335. XXis the path to the file from which
  1336. XX.I ofiles
  1337. XXshould obtain the addresses of kernel symbols,
  1338. XXinstead of from
  1339. XX.IR /dynix .
  1340. XX.IP
  1341. XX.I Core
  1342. XXis the path to the file from which
  1343. XX.I ofiles
  1344. XXshould obtain the value of kernel symbols,
  1345. XXinstead of from
  1346. XX.IR /dev/mem .
  1347. XX.IP
  1348. XXThis option is useful for debugging system crash dumps.
  1349. XX.TP
  1350. XX.B \-n
  1351. XXThis option specifies that the
  1352. XX.I name
  1353. XXarguments identify network connections by their hexadecimal, Protocol
  1354. XXControl Block (PCB) addresses.
  1355. XXPCB addresses can be obtained via the
  1356. XX.B \-A
  1357. XXoption of
  1358. XX.IR netstat (1).
  1359. XX.IP
  1360. XXThis option makes it possible to determine the local processes that
  1361. XXare using network connections in the LISTEN through ESTABLISHED states.
  1362. XX.TP
  1363. XX.B \-p 
  1364. XXThis option specifies that
  1365. XX.I ofiles
  1366. XXshould print process identifiers only \- e. g., so that the output may
  1367. XXbe piped to
  1368. XX.IR kill (1).
  1369. XX.TP
  1370. XX.I names
  1371. XXThese are path names of files, directories and file systems;
  1372. XXor, if the
  1373. XX.B \-n
  1374. XXoption has been specified, network connections, identified by their
  1375. XXhexadecimal Protocol Control Block (PCB) addresses.
  1376. XX.SH OUTPUT
  1377. XX.I Ofiles
  1378. XXdisplays for each
  1379. XX.IR name :
  1380. XX.TP \w'name/linkages'u+4
  1381. XX.I name/linkages
  1382. XXfor file paths, an interpretation of the type of name \- file, directory
  1383. XXor file system;
  1384. XXfor network connections, the kernel address linkages, starting with the file
  1385. XXstructure and proceeding through the socket structure and the Internet
  1386. XXProtocol Control Block (INPCB) structure to the PCB
  1387. XX.TP
  1388. XX.B USER
  1389. XXthe login name of the user of the process that has
  1390. XX.I name
  1391. XXopen
  1392. XX.TP
  1393. XX.B PID
  1394. XXthe identifier of the process that has
  1395. XX.I name
  1396. XXopen
  1397. XX.TP
  1398. XX.B TYPE
  1399. XXa file type explanation:
  1400. XX.RS
  1401. XX.TP \w'file'u+4
  1402. XX.B cwd 
  1403. XXif
  1404. XX.I name
  1405. XXis the current working directory of the process
  1406. XX.TP
  1407. XX.B file
  1408. XXif
  1409. XX.I name
  1410. XXis being used as a regular file by the process, optionally followed by:
  1411. XX.RS
  1412. XX.TP
  1413. XX.B /s
  1414. XXif the process has a shared lock on the file
  1415. XX.TP
  1416. XX.B /x
  1417. XXif the process has an exclusive lock on the file
  1418. XX.RE
  1419. XX.TP
  1420. XX.B rdir
  1421. XXif 
  1422. XX.I name
  1423. XXis the root directory of the process
  1424. XX.TP
  1425. XX.B sock
  1426. XXif
  1427. XX.I name
  1428. XXis a socket
  1429. XX.RE
  1430. XX.TP
  1431. XX.B FD
  1432. XXthe file descriptor number, local to the process
  1433. XX.TP
  1434. XX.B CMD
  1435. XXthe user command that opened
  1436. XX.I name
  1437. XX.TP
  1438. XX.B INODE
  1439. XXthe inode number of the file
  1440. XX.SH EXAMPLES
  1441. XXThis example shows the use of
  1442. XX.I ofiles
  1443. XXto discover the owner of the open, regular file,
  1444. XX.IR /usr/spool/lpd/lock .
  1445. XX.PP
  1446. XX.RS
  1447. XX.nf
  1448. XX% ofiles /usr/spool/lpd/lock
  1449. XX.br
  1450. XX/usr/spool/lpd/lock    
  1451. XX.br
  1452. XXUSER    PID    TYPE      FD    CMD    INODE
  1453. XX.br
  1454. XXroot    110    file/x     3    lpd    26683
  1455. XX.fi
  1456. XX.RE
  1457. XX.PP
  1458. XXThis example shows the use of
  1459. XX.IR netstat (1),
  1460. XX.IR grep (1)
  1461. XXand
  1462. XX.I ofiles
  1463. XXto identify the local endpoint of the ``smtp'' network connection.
  1464. XXThe first column of output from
  1465. XX.I netstat
  1466. XXis the PCB address; it is used as the
  1467. XX.I name
  1468. XXargument to
  1469. XX.IR ofiles ,
  1470. XXalong with the
  1471. XX.B \-n
  1472. XXoption.
  1473. XX.PP
  1474. XX.RS
  1475. XX.nf
  1476. XX% netstat -aA | grep smtp
  1477. XX.br
  1478. XX80f6770c    tcp    0    0    *.smtp    *.*    LISTEN
  1479. XX.br
  1480. XX% ofiles -n 80f6770c
  1481. XX.br
  1482. XXfile 80102b64 of socket 80f6758c of INPCB 80f6780c of PCB 80f6770c    
  1483. XX.br
  1484. XXUSER    PID    TYPE    FD    CMD
  1485. XX.br
  1486. XXroot    105    sock     5    sendmail 
  1487. XX.fi
  1488. XX.RE
  1489. XX.SH DIAGNOSTICS
  1490. XXErrors are identified with messages on the standard error file.
  1491. XX.PP
  1492. XX.I Ofiles
  1493. XXreturns a one (1) if any error was detected, including the failure to
  1494. XXlocate any
  1495. XX.IR names .
  1496. XXIt returns a zero (0) if no errors were detected and if it was able to
  1497. XXdisplay owner information about all the specified
  1498. XX.IR names .
  1499. XX.SH BUGS
  1500. XX.I Ofiles
  1501. XXcan't identify SunOS 4.0 stream files, so it doesn't follow their file
  1502. XXstructure pointers correctly when reading their inodes.
  1503. XXThat results in the display of erroneous inode numbers for stream files.
  1504. XX.PP
  1505. XXThe
  1506. XX.B \-n
  1507. XXoption limits its search to network connections in the LISTEN through
  1508. XXESTABLISHED states.
  1509. XX.PP
  1510. XXSince
  1511. XX.I ofiles
  1512. XXreads kernel memory in its search for open files and network connections,
  1513. XXrapid changes in kernel memory may produce unsatisfactory results.
  1514. XX.SH AUTHORS
  1515. XXC. Spencer is the original author.
  1516. XXMichael Ditto, Tom Dunigan, Alexander Dupuy, Gary Nebbett and Richard Tobin
  1517. XXcontributed.
  1518. XX.PP
  1519. XXMichael Spitzer, Ray Moody, and Vik Lall of the Purdue University Computing
  1520. XXCenter converted the program to a variety of UNIX environments.
  1521. XX.PP
  1522. XXVic Abell of the Purdue University Computing Center added the
  1523. XX.B \-n
  1524. XXoption.
  1525. XX.SH SEE ALSO
  1526. XXinode(5),
  1527. XXmount(1),
  1528. XXkill(1),
  1529. XXtcp(4).
  1530. SHAR_EOF
  1531. if test 5223 -ne "`wc -c ofiles.8l`"
  1532. then
  1533. echo shar: error transmitting ofiles.8l '(should have been 5223 characters)'
  1534. fi
  1535. #    End of shell archive
  1536. exit 0
  1537.  
  1538. -- 
  1539. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  1540.