home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume18 / ofiles < prev    next >
Text File  |  1989-10-15  |  37KB  |  1,534 lines

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