home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume18 / fstat2 < prev    next >
Text File  |  1989-04-19  |  34KB  |  1,367 lines

  1. Subject:  v18i107:  Show all open files status
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: abe@mace.cc.purdue.edu (Vic Abell)
  7. Posting-number: Volume 18, Issue 107
  8. Archive-name: fstat2
  9.  
  10. As promised, here is fstat from the 4.3BSD Tahoe release, ported to DYNIX
  11. 3.0.1[24] for Sequent Symmetry and Balance, SunOS 4.0 and ULTRIX 2.2.
  12.  
  13. Fstat is similar to the ofiles program which I recently submitted.  Like
  14. ofiles, fstat identifies open files.  It's orientation differs slightly
  15. from that of ofiles: ofiles starts with a file name and paws through the
  16. proc and user structures to identify the file;  fstat reads all the proc
  17. and user structures, displaying information in all files, optionally
  18. applying a few filters to the output (including a single file name filter.)
  19.  
  20. In combination with netstat -aA and grep, fstat will identify the process
  21. associated with a network connection, just as will ofiles.
  22.  
  23. Vic Abell
  24.  
  25. #    This is a shell archive.
  26. #    Remove everything above and including the cut line.
  27. #    Then run the rest of the file through sh.
  28. #----cut here-----cut here-----cut here-----cut here----#
  29. #!/bin/sh
  30. # shar:    Shell Archiver
  31. #    Run the following text with /bin/sh to create:
  32. #    README
  33. #    Makefile
  34. #    fstat.c
  35. #    fstat.8
  36. # By:    Vic Abell (Purdue University)
  37. echo shar: extracting README '(1773 characters)'
  38. sed 's/^XX//' << \SHAR_EOF > README
  39. XXFstat comes from the 4.3BSD Tahoe distribution.  It may be used to identify
  40. XXopen files.  Coupled with netstat(8) and grep(1), it can be used to discover
  41. XXthe process that has an open socket for a network connection.
  42. XX
  43. XXI have converted fstat to run under 4.3BSD, DYNIX 3.0.1[24], SunOS 4.0 and
  44. XXULTRIX 2.2.  It is free of lint on all those systems, according to the lint
  45. XXlibraries available to me.
  46. XX
  47. XXSpecial notes:
  48. XX
  49. XX    1.  The included Makefile is a generic one, which you may have to
  50. XX        customize to your environment (see notes 3 and 5.)  I have
  51. XX        removed the depend rule, since it relies on a local "maketd"
  52. XX        program.
  53. XX
  54. XX    2.  Fstat needs permission to access /dev/drum, /dev/kmem and
  55. XX        /dev/mem.  The Makefile of this distribution assumes that those
  56. XX        devices belong to the kmem group, and gives the fstat object a
  57. XX        setgid(kmem) mode.
  58. XX
  59. XX    3.  SunOS 4.0 users should make sure that -lkvm appears at the
  60. XX        end of the ${CC} of the fstat rule - e. g., change
  61. XX
  62. XX        fstat: ${OBJ}
  63. XX            ${CC} -o $@ ${CFLAGS} ${OBJ} 
  64. XX        to
  65. XX        fstat: ${OBJ}
  66. XX            ${CC} -o $@ ${CFLAGS} ${OBJ} -lkvm
  67. XX
  68. XX    4.  Some SunOS users may not have the files for making kernels -
  69. XX        specifically, "/usr/share/sys/specfs/snode.h".  If you do
  70. XX        not have this header file, replace its include with the
  71. XX        following structure definition:
  72. XX
  73. XX        struct snode {
  74. XX            struct snode *s_next;
  75. XX            struct vnode s_vnode;
  76. XX            struct vnode *s_realvp;
  77. XX            struct vnode *s_bdevvp;
  78. XX        };
  79. XX
  80. XX    5.  Sequent users should make sure that the DYNIX symbol is defined.
  81. XX        We define it in <sys/param.h>.  It may also be defined in the
  82. XX        Makefile using "-DDYNIX", e. g.,
  83. XX
  84. XX        CDEFS= -DDYNIX
  85. XX
  86. XXI have added to and updated the 4.3BSD Tahoe manual page.
  87. XX
  88. XXVic Abell, abe@mace.cc.purdue.edu
  89. XXPurdue University Computing Center
  90. XXMarch 28, 1989
  91. SHAR_EOF
  92. if test 1773 -ne "`wc -c README`"
  93. then
  94. echo shar: error transmitting README '(should have been 1773 characters)'
  95. fi
  96. echo shar: extracting Makefile '(648 characters)'
  97. sed 's/^XX//' << \SHAR_EOF > Makefile
  98. XX# Makefile for fstat    
  99. XX
  100. XXBIN=    ${DESTDIR}/etc
  101. XX
  102. XXI=/usr/include
  103. XXS=/usr/include/sys
  104. XX
  105. XXINCLUDE=
  106. XXDEBUG=    -O
  107. XXCDEFS= 
  108. XXCFLAGS=    ${DEBUG} ${CDEFS} ${INCLUDE} 
  109. XX
  110. XXSRC=    fstat.c
  111. XXOBJ=    fstat.o
  112. XXSOURCE=    Makefile ${HDR} ${SRC}
  113. XX
  114. XXall: fstat
  115. XX
  116. XX# SunOS 4.0 requires -lkvm
  117. XX
  118. XXfstat: ${OBJ}
  119. XX    ${CC} -o $@ ${CFLAGS} ${OBJ} 
  120. XX
  121. XXclean: FRC
  122. XX    rm -f Makefile.bak fstat *.o a.out core errs tags
  123. XX
  124. XXinstall: all FRC
  125. XX    install -c -s -m 2755 -g kmem fstat ${BIN}
  126. XX
  127. XXlint: ${SRC} ${HDR} FRC
  128. XX    lint ${CDEFS} ${INCLUDE} ${SRC}
  129. XX
  130. XXprint: source FRC
  131. XX    lpr -J'fstat source' ${SOURCE}
  132. XX
  133. XXsource: ${SOURCE}
  134. XX
  135. XXspotless: clean
  136. XX    rcsclean ${SOURCE}
  137. XX
  138. XXtags: ${SRC} ${HDR}
  139. XX    ctags -t ${SRC} ${HDR}
  140. XX
  141. XX${SOURCE}:
  142. XX    co $@
  143. XX
  144. XXFRC:
  145. SHAR_EOF
  146. if test 648 -ne "`wc -c Makefile`"
  147. then
  148. echo shar: error transmitting Makefile '(should have been 648 characters)'
  149. fi
  150. echo shar: extracting fstat.c '(20280 characters)'
  151. sed 's/^XX//' << \SHAR_EOF > fstat.c
  152. XX/*
  153. XX * Copyright (c) 1987 Regents of the University of California.
  154. XX * All rights reserved.
  155. XX *
  156. XX * Redistribution and use in source and binary forms are permitted
  157. XX * provided that the above copyright notice and this paragraph are
  158. XX * duplicated in all such forms and that any documentation,
  159. XX * advertising materials, and other materials related to such
  160. XX * distribution and use acknowledge that the software was developed
  161. XX * by the University of California, Berkeley.  The name of the
  162. XX * University may not be used to endorse or promote products derived
  163. XX * from this software without specific prior written permission.
  164. XX * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  165. XX * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  166. XX * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  167. XX */
  168. XX
  169. XX#ifndef lint
  170. XXchar copyright[] =
  171. XX"@(#) Copyright (c) 1987 Regents of the University of California.\n\
  172. XX All rights reserved.\n";
  173. XX#endif /* not lint */
  174. XX
  175. XX#ifndef lint
  176. XXstatic char sccsid[] = "@(#)fstat.c    5.13 (Berkeley) 6/18/88";
  177. XX#endif /* not lint */
  178. XX
  179. XX/*
  180. XX *  fstat 
  181. XX */
  182. XX#include <machine/pte.h>
  183. XX
  184. XX#include <sys/param.h>
  185. XX#include <sys/dir.h>
  186. XX#include <sys/user.h>
  187. XX#include <sys/proc.h>
  188. XX#ifndef    sun
  189. XX#include <sys/text.h>
  190. XX#endif
  191. XX#include <sys/stat.h>
  192. XX#ifdef    DYNIX
  193. XX#define    KERNEL
  194. XX#include <sys/vnode.h>
  195. XX#endif
  196. XX#ifndef    sun
  197. XX#include <sys/inode.h>
  198. XX#endif
  199. XX#ifdef    DYNIX
  200. XX#undef    KERNEL
  201. XX#endif
  202. XX#include <sys/socket.h>
  203. XX#include <sys/socketvar.h>
  204. XX#include <sys/domain.h>
  205. XX#include <sys/protosw.h>
  206. XX#include <sys/unpcb.h>
  207. XX#include <sys/vmmac.h>
  208. XX#define    KERNEL
  209. XX#include <sys/file.h>
  210. XX#undef    KERNEL
  211. XX#include <net/route.h>
  212. XX#include <netinet/in.h>
  213. XX#include <netinet/in_pcb.h>
  214. XX#include <stdio.h>
  215. XX#include <ctype.h>
  216. XX#include <nlist.h>
  217. XX#include <pwd.h>
  218. XX
  219. XX#ifdef sun
  220. XX#include <sys/vnode.h>
  221. XX#include <ufs/inode.h>
  222. XX#include "/usr/share/sys/specfs/snode.h"
  223. XX#include <kvm.h>
  224. XXkvm_t    *kd;
  225. XXstruct user *kvm_getu();
  226. XX#endif
  227. XX
  228. XX#ifdef    ULTRIX
  229. XX        /* UFS -> GFS */
  230. XX#    define    inode    gnode
  231. XX#    define    x_iptr    x_gptr
  232. XX#    define    i_dev    g_dev
  233. XX#    define    i_number g_number
  234. XX#    define    i_mode    g_mode
  235. XX#    define    i_size    g_size
  236. XXvoid exit(), nlist(), perror();
  237. XX#endif
  238. XX
  239. XX#ifdef    ULTRIX
  240. XX#define    ls_t    long
  241. XX#else
  242. XX#define ls_t    off_t
  243. XX#endif
  244. XX
  245. XX#if    defined(DYNIX) || defined(sun)
  246. XX#define DTYPE_INODE    DTYPE_VNODE
  247. XX#endif
  248. XX
  249. XX#define    N_KMEM    "/dev/kmem"
  250. XX#define    N_MEM    "/dev/mem"
  251. XX#define    N_SWAP    "/dev/drum"
  252. XX#ifdef    DYNIX
  253. XX#define    N_UNIX    "/dynix"
  254. XX#else
  255. XX#define    N_UNIX    "/vmunix"
  256. XX#endif
  257. XX
  258. XX#define    TEXT    -2
  259. XX#define    WD    -1
  260. XX
  261. XXtypedef struct devs {
  262. XX    struct devs *next;
  263. XX    dev_t dev;
  264. XX    int inum;
  265. XX    char *name;
  266. XX} DEVS;
  267. XXDEVS *devs;
  268. XX
  269. XXstatic struct nlist nl[] = {
  270. XX    { "_proc" },
  271. XX#define    X_PROC        0
  272. XX    { "_nproc" },
  273. XX#define    X_NPROC        1
  274. XX    { "_Sysmap"},
  275. XX#define    X_SYSMAP    2
  276. XX#ifdef    sun
  277. XX    { "_inode"},
  278. XX#define X_INODE        3
  279. XX    { "_ninode"},
  280. XX#define X_NINODE    4
  281. XX#else
  282. XX    { "_Usrptmap" },
  283. XX#define    X_USRPTMA    3
  284. XX    { "_usrpt" },
  285. XX#define    X_USRPT        4
  286. XX#endif
  287. XX    { "" },
  288. XX};
  289. XX
  290. XXstruct proc *mproc;
  291. XX#if    !defined(DYNIX) && !defined(sun)
  292. XXstruct pte *Usrptma, *usrpt;
  293. XX#endif
  294. XX
  295. XX#ifdef    sun
  296. XXstruct inode *inodef = NULL;
  297. XXstruct inode *inodel;
  298. XXint ninode = 0;
  299. XX#endif
  300. XX
  301. XX#ifndef    DYNIX
  302. XXunion {
  303. XX    struct user user;
  304. XX    char upages[UPAGES][NBPG];
  305. XX} user;
  306. XX#endif
  307. XXstruct user *u;
  308. XX
  309. XXextern int errno;
  310. XXextern char *sys_errlist[];
  311. XXstatic int fflg, vflg;
  312. XXstatic int kmem, mem, nproc, swap;
  313. XXstatic char *pname, *uname;
  314. XX
  315. XXls_t lseek();
  316. XX#ifdef    DYNIX
  317. XXls_t vtophys();
  318. XX#endif
  319. XX
  320. XXmain(argc, argv)
  321. XX    int argc;
  322. XX    char **argv;
  323. XX{
  324. XX    extern char *optarg;
  325. XX    extern int optind;
  326. XX    register struct passwd *passwd;
  327. XX    register int pflg, pid, uflg, uid;
  328. XX    int ch, size;
  329. XX    struct passwd *getpwnam(), *getpwuid();
  330. XX    long lgetw();
  331. XX    char *malloc(), *rindex(), *valloc();
  332. XX
  333. XX#ifdef    lint
  334. XX/*
  335. XX * The following code satisfies lint for KERNEL symbols.
  336. XX * This program is lint-free under 4.3BSD, DYNIX 3.0.1[24], SunOS 4.0
  337. XX * and ULTRIX 2.2, using the lint libraries of the systems at the
  338. XX * Purdue University Computing Center.
  339. XX */
  340. XX#if    !defined(DYNIX) && !defined(ULTRIX)
  341. XX    struct file *lintfp;
  342. XX
  343. XX    file = fileNFILE = NULL;
  344. XX    lintfp = file;
  345. XX    lintfp = fileNFILE;
  346. XX    file = lintfp;
  347. XX    nfile = 0;
  348. XX    size = nfile;
  349. XX#endif
  350. XX#ifdef    DYNIX
  351. XX    char *optarg = NULL;    /* DYNIX lint misses the extern  */
  352. XX    int optind = 0;        /* DYNIX lint misses the extern  */
  353. XX#endif
  354. XX#ifdef    ULTRIX
  355. XX    struct file *lintfp;
  356. XX    struct nch *lintnch;
  357. XX
  358. XX    file = fileNFILE = NULL;
  359. XX    lintfp = file;
  360. XX    lintfp = fileNFILE;
  361. XX    file = lintfp;
  362. XX    nfile = 0;
  363. XX    size = nfile;
  364. XX    nch = NULL;
  365. XX    lintnch = nch;
  366. XX    nch = lintnch;
  367. XX    nchsize = 0;
  368. XX    size = nchsize;
  369. XX#endif
  370. XX#endif    /* lint */
  371. XX
  372. XX    if ((pname = rindex(argv[0], '/')) != NULL)
  373. XX        pname++;
  374. XX    else
  375. XX        pname = argv[0];
  376. XX    pflg = uflg = 0;
  377. XX    while ((ch = getopt(argc, argv, "p:u:v")) != EOF)
  378. XX        switch((char)ch) {
  379. XX        case 'p':
  380. XX            if (pflg++)
  381. XX                (void) usage();
  382. XX            if (!isdigit(*optarg)) {
  383. XX                (void) fprintf(stderr,
  384. XX                    "%s: -p option requires a process id.\n",
  385. XX                    pname);
  386. XX                (void) usage();
  387. XX            }
  388. XX            pid = atoi(optarg);
  389. XX            break;
  390. XX        case 'u':
  391. XX            if (uflg++)
  392. XX                (void) usage();
  393. XX            if (!(passwd = getpwnam(optarg))) {
  394. XX                (void) fprintf(stderr,
  395. XX                    "%s: %s is unknown uid\n",
  396. XX                    pname, optarg);
  397. XX                exit(1);
  398. XX            }
  399. XX            uid = passwd->pw_uid;
  400. XX            uname = passwd->pw_name;
  401. XX            break;
  402. XX        case 'v':    /* undocumented: print read error messages */
  403. XX            vflg++;
  404. XX            break;
  405. XX        case '?':
  406. XX        default:
  407. XX            (void) usage();
  408. XX        }
  409. XX
  410. XX    if (*(argv += optind)) {
  411. XX        for (; *argv; ++argv) {
  412. XX            if (getfname(*argv))
  413. XX                fflg = 1;
  414. XX        }
  415. XX        if (!fflg)    /* file(s) specified, but none accessible */
  416. XX            exit(1);
  417. XX    }
  418. XX
  419. XX#ifdef    DYNIX
  420. XX    if ((u = (struct user *) valloc(ctob(UPAGES))) == NULL) {
  421. XX        (void) fprintf(stderr,
  422. XX            "%s: can't allocate space for user structure\n",
  423. XX            pname);
  424. XX        exit(1);
  425. XX    }
  426. XX#else
  427. XX    u = &user.user;
  428. XX#endif
  429. XX    openfiles();
  430. XX
  431. XX#ifdef    ULTRIX
  432. XX    (void) nlist(N_UNIX, nl);
  433. XX    if (!nl[0].n_type)
  434. XX#else
  435. XX    if (nlist(N_UNIX, nl) == -1 || !nl[0].n_type)
  436. XX#endif
  437. XX    {
  438. XX        (void) fprintf(stderr, "%s: %s has no namelist\n",
  439. XX            pname, N_UNIX);
  440. XX        exit(1);
  441. XX    }
  442. XX#ifdef    sun
  443. XX    if (nl[X_INODE].n_value == (u_long)0) {
  444. XX        (void) fprintf(stderr, "%s: can't read inode pointer)\n",
  445. XX            pname);
  446. XX        exit(1);
  447. XX    }
  448. XX    inodef = (struct inode *)lgetw((ls_t)nl[X_INODE].n_value);
  449. XX    ninode = (int)lgetw((ls_t)nl[X_NINODE].n_value);
  450. XX    if (!inodef || !ninode) {
  451. XX        (void) fprintf(stderr,
  452. XX            "%s: no inodes (Is this a diskless Sun client?)\n",
  453. XX            pname);
  454. XX        exit(1);
  455. XX    }
  456. XX    inodel = inodef + (ninode - 1);
  457. XX#endif
  458. XX#if    !defined(DYNIX) && !defined(sun)
  459. XX    Usrptma = (struct pte *)nl[X_USRPTMA].n_value;
  460. XX    usrpt = (struct pte *) nl[X_USRPT].n_value;
  461. XX#endif
  462. XX    nproc = (int)lgetw((ls_t)nl[X_NPROC].n_value);
  463. XX
  464. XX    size = nproc * sizeof(struct proc);
  465. XX    if ((mproc = (struct proc *)malloc((u_int)size)) == NULL) {
  466. XX        (void) fprintf(stderr, "%s: out of space\n", pname);
  467. XX        exit(1);
  468. XX    }
  469. XX    if (kread((ls_t)lgetw((ls_t)nl[X_PROC].n_value), (char *)mproc, size)
  470. XX    != size)
  471. XX        rerr1("proc table", N_KMEM);
  472. XX
  473. XX    (void) printf("%-8.8s %-10.10s %5s %4s %-6.6s %6s %7s %-5.5s %s\n",
  474. XX        "USER", "CMD", "PID", "FD", "DEVICE", "INODE", "SIZE", "TYPE",
  475. XX        fflg ? "NAME" : "");
  476. XX    for (; nproc--; ++mproc) {
  477. XX        if (mproc->p_stat == 0)
  478. XX            continue;
  479. XX        if (pflg && mproc->p_pid != pid)
  480. XX            continue;
  481. XX        if (uflg)  {
  482. XX            if (mproc->p_uid != uid)
  483. XX                continue;
  484. XX        }
  485. XX        else
  486. XX            uname = (passwd = getpwuid((int)mproc->p_uid)) ?
  487. XX                passwd->pw_name : "unknown";
  488. XX        if (mproc->p_stat == SZOMB)
  489. XX            continue;
  490. XX#ifdef    sun
  491. XX        if ((u = kvm_getu(kd, mproc)) == NULL)
  492. XX#else
  493. XX        if (getu() == 0)
  494. XX#endif
  495. XX            continue;
  496. XX        dotext();
  497. XX        readf();
  498. XX    }
  499. XX    exit(0);
  500. XX}
  501. XX
  502. XX#ifndef    sun
  503. XX#ifdef    DYNIX
  504. XXgetu()
  505. XX{
  506. XX    int btr;
  507. XX
  508. XX    if ((mproc->p_flag & SLOAD) == 0) {
  509. XX        if (swap < 0)
  510. XX            return(0);
  511. XX        (void) lseek(swap, (ls_t)dtob(mproc->p_swaddr), L_SET);
  512. XX        btr = ctob(UPAGES);
  513. XX        if (read(swap, (char *)u, btr) != btr)
  514. XX            return(0);
  515. XX    } else {
  516. XX        (void) lseek(kmem, (ls_t)mproc->p_uarea, L_SET);
  517. XX        if (read(kmem, (char *)u, sizeof(struct user))
  518. XX        != sizeof(struct user))
  519. XX            return(0);
  520. XX    }
  521. XX    return(1);
  522. XX}
  523. XX#else    /* DYNIX */
  524. XXstatic
  525. XXgetu()
  526. XX{
  527. XX    struct pte *pteaddr, apte;
  528. XX    struct pte arguutl[UPAGES+CLSIZE];
  529. XX    register int i;
  530. XX    int ncl;
  531. XX
  532. XX    if ((mproc->p_flag & SLOAD) == 0) {
  533. XX        if (swap < 0)
  534. XX            return(0);
  535. XX        (void)lseek(swap, (ls_t)dtob(mproc->p_swaddr), L_SET);
  536. XX        if (read(swap, (char *)u, sizeof(struct user))
  537. XX            != sizeof(struct user)) {
  538. XX            (void) fprintf(stderr,
  539. XX                "%s: can't read u for pid %d from %s\n",
  540. XX                pname, mproc->p_pid, N_SWAP);
  541. XX            return(0);
  542. XX        }
  543. XX        return(1);
  544. XX    }
  545. XX    pteaddr = &Usrptma[btokmx(mproc->p_p0br) + mproc->p_szpt - 1];
  546. XX    (void)lseek(kmem, (ls_t)pteaddr, L_SET);
  547. XX    if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
  548. XX        (void) printf(
  549. XX          "%s: can't read indir pte to get u for pid %d from %s\n",
  550. XX          pname, mproc->p_pid, N_SWAP);
  551. XX        return(0);
  552. XX    }
  553. XX    (void)lseek(mem, (ls_t)(ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE)
  554. XX        * sizeof(struct pte)), L_SET);
  555. XX    if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
  556. XX        (void) printf(
  557. XX          "%s: can't read page table for u of pid %d from %s\n",
  558. XX          pname, mproc->p_pid, N_KMEM);
  559. XX        return(0);
  560. XX    }
  561. XX    ncl = (sizeof(struct user) + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
  562. XX    while (--ncl >= 0) {
  563. XX        i = ncl * CLSIZE;
  564. XX        (void)lseek(mem, (ls_t)ctob(arguutl[CLSIZE+i].pg_pfnum), L_SET);
  565. XX        if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
  566. XX            (void) printf(
  567. XX              "%s: can't read page %u of u of pid %d from %s\n",
  568. XX              pname,
  569. XX              arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid, N_MEM);
  570. XX            return(0);
  571. XX        }
  572. XX    }
  573. XX    return(1);
  574. XX}
  575. XX#endif    /* DYNIX */
  576. XX#endif    /* not sun */
  577. XX
  578. XXstatic
  579. XXdotext()
  580. XX{
  581. XX#if    !defined(DYNIX) && !defined(sun)
  582. XX    struct text text;
  583. XX
  584. XX    (void)lseek(kmem, (ls_t)mproc->p_textp, L_SET);
  585. XX    if (read(kmem, (char *) &text, sizeof(text)) != sizeof(text)) {
  586. XX        rerr1("text table", N_KMEM);
  587. XX        return;
  588. XX    }
  589. XX    if (text.x_flag)
  590. XX        itrans(DTYPE_INODE, (char *)text.x_iptr, TEXT);
  591. XX#endif
  592. XX}
  593. XX
  594. XXstatic
  595. XXitrans(ftype, g, fno)
  596. XX    int ftype, fno;
  597. XX    char *g;            /* if ftype is inode/vnode */
  598. XX{
  599. XX    struct inode inode;
  600. XX    dev_t idev;
  601. XX    char *comm, *itype();
  602. XX    char *name = (char *)NULL;    /* set by devmatch() on a match */
  603. XX    int noinode = 0;
  604. XX#if    defined(DYNIX) || defined(sun)
  605. XX    struct vnode v;
  606. XX#ifdef    sun
  607. XX    struct snode s;
  608. XX    char *vntype();
  609. XX#endif
  610. XX#endif
  611. XX
  612. XX    if ((g && (ftype & DTYPE_INODE)) || fflg) {
  613. XX#if    defined(DYNIX) || defined(sun)
  614. XX/*
  615. XX * The file structure points to:
  616. XX *
  617. XX *    DYNIX    vnode, and the vnode points to the inode
  618. XX *    BSD    inode
  619. XX *    SunOS    vnode, and the vode points to an snode if the vnode type
  620. XX *        is VBLK, VCHR or VFIFO; and to an inode otherwise; the
  621. XX *        snode may point to the real vnode or to a stream
  622. XX *        
  623. XX *    ULTRIX    gnode
  624. XX */
  625. XX        if (kread((ls_t)g, (char *)&v, sizeof(v)) != sizeof(v)) {
  626. XX            rerr2(errno, (int)g, "vnode");
  627. XX            return;
  628. XX        }
  629. XX#ifdef    sun
  630. XX        if (v.v_type == VCHR || v.v_type == VBLK || v.v_type == VFIFO) {
  631. XX            if (kread((ls_t)v.v_data, (char *)&s, sizeof(s))
  632. XX            != sizeof(s)) {
  633. XX                rerr2(errno, (int)v.v_data, "snode");
  634. XX                return;
  635. XX            }
  636. XX            if (s.s_realvp || s.s_bdevvp) {
  637. XX                if (kread( s.s_realvp ? (ls_t)s.s_realvp
  638. XX                              : (ls_t)s.s_bdevvp,
  639. XX                     (char *)&v, sizeof(v))
  640. XX                != sizeof(v)) {
  641. XX                    rerr2(errno, (int)s.s_realvp,
  642. XX                        "read vnode");
  643. XX                    return;
  644. XX                }
  645. XX            }
  646. XX        }
  647. XX        /*
  648. XX         * The following test weeds out Sun streams that are
  649. XX         * represented by "clone" snodes whose s_realvp pointer
  650. XX         * has not been properly NULLed in the kernel.
  651. XX         */
  652. XX        if ((struct inode *)v.v_data < inodef
  653. XX        ||  (struct inode *)v.v_data > inodel)
  654. XX            noinode = 1;
  655. XX        else    
  656. XX            if (kread((ls_t)v.v_data, (char *)&inode, sizeof(inode))
  657. XX#else    /* DYNIX && not sun */
  658. XX        if (kread((ls_t)v.v_data, (char *)&inode, sizeof(inode))
  659. XX#endif    /* sun */
  660. XX#else    /* not DYNIX && not sun */
  661. XX        if (kread((ls_t)g, (char *)&inode, sizeof(inode))
  662. XX#endif    /* DYNIX || sun */
  663. XX        != sizeof(inode)) {
  664. XX            rerr2(errno, (int)g, "inode");
  665. XX            return;
  666. XX        }
  667. XX        idev = inode.i_dev;
  668. XX        if (fflg && (noinode || !devmatch(idev, inode.i_number, &name)))
  669. XX            return;
  670. XX    }
  671. XX    if (mproc->p_pid == 0)
  672. XX        comm = "swapper";
  673. XX    else if (mproc->p_pid == 2)
  674. XX        comm = "pagedaemon";
  675. XX    else
  676. XX        comm = u->u_comm;
  677. XX    (void) printf("%-8.8s %-10.10s %5d ", uname, comm, mproc->p_pid);
  678. XX
  679. XX    switch(fno) {
  680. XX    case WD:
  681. XX        (void) printf("  wd");
  682. XX        break;
  683. XX    case TEXT:
  684. XX        (void) printf("text");
  685. XX        break;
  686. XX    default:
  687. XX        (void) printf("%4d", fno);
  688. XX    }
  689. XX
  690. XX    if (g == NULL) {
  691. XX        (void) printf("* (deallocated)\n");
  692. XX        return;
  693. XX    }
  694. XX
  695. XX    switch(ftype) {
  696. XX    case DTYPE_INODE:
  697. XX#ifndef    sun
  698. XX        (void) printf(" %2d, %2d %6lu %7ld %-5.5s %s\n",
  699. XX            major(inode.i_dev), minor(inode.i_dev),
  700. XX            inode.i_number,
  701. XX            inode.i_mode == IFSOCK ? 0 : inode.i_size,
  702. XX            itype(inode.i_mode),
  703. XX            name ? name : "");
  704. XX#else
  705. XX        if (noinode)
  706. XX            (void) printf(" %2d, %2d %6s %7s %-5.5s %s\n",
  707. XX                major(v.v_rdev), minor(v.v_rdev),
  708. XX                "none", "", vntype(v.v_type),
  709. XX                name ? name: "");
  710. XX        else
  711. XX            (void) printf(" %2d, %2d %6lu %7ld %-5.5s %s\n",
  712. XX                major(inode.i_dev), minor(inode.i_dev),
  713. XX                inode.i_number,
  714. XX                    inode.i_mode == IFSOCK ? 0 : inode.i_size,
  715. XX                itype(inode.i_mode), name ? name : "");
  716. XX#endif
  717. XX        break;
  718. XX    case DTYPE_SOCKET:
  719. XX        socktrans((struct socket *)g);
  720. XX        break;
  721. XX#ifdef DTYPE_PORT
  722. XX    case DTYPE_PORT:
  723. XX        (void) printf("* (fifo / named pipe)\n");
  724. XX        break;
  725. XX#endif
  726. XX    default:
  727. XX        (void) printf("* (unknown file type)\n");
  728. XX    }
  729. XX}
  730. XX
  731. XXstatic char *
  732. XXitype(mode)
  733. XX    u_short mode;
  734. XX{
  735. XX    switch(mode & IFMT) {
  736. XX#ifdef    IFIFO
  737. XX    case IFIFO:
  738. XX        return("fifo");
  739. XX#endif
  740. XX    case IFCHR:
  741. XX        return("chr");
  742. XX    case IFDIR:
  743. XX        return("dir");
  744. XX    case IFBLK:
  745. XX        return("blk");
  746. XX    case IFREG:
  747. XX        return("reg");
  748. XX    case IFLNK:
  749. XX        return("link");
  750. XX    case IFSOCK:
  751. XX        return("sock");
  752. XX    default:
  753. XX        return("unk");
  754. XX    }
  755. XX    /*NOTREACHED*/
  756. XX}
  757. XX
  758. XX#ifdef    sun
  759. XXstatic char *
  760. XXvntype(v)
  761. XX    enum vtype v;
  762. XX{
  763. XX    switch (v) {
  764. XX    case VNON:
  765. XX        return("vnon");
  766. XX    case VREG:
  767. XX        return("vreg");
  768. XX    case VDIR:
  769. XX        return("vdir");
  770. XX    case VBLK:
  771. XX        return("vblk");
  772. XX    case VCHR:
  773. XX        return("vchr");
  774. XX    case VLNK:
  775. XX        return("vlnk");
  776. XX    case VSOCK:
  777. XX        return("vsock");
  778. XX    case VBAD:
  779. XX        return("vbad");
  780. XX    case VFIFO:
  781. XX        return("vfifo");
  782. XX    default:
  783. XX        return("vunk");
  784. XX    }
  785. XX    /* NOTREACHED */
  786. XX}
  787. XX#endif
  788. XX
  789. XXstatic
  790. XXsocktrans(sock)
  791. XX    struct socket *sock;
  792. XX{
  793. XX    static char *stypename[] = {
  794. XX        "unused",    /* 0 */
  795. XX        "stream",     /* 1 */
  796. XX        "dgram",    /* 2 */
  797. XX        "raw",        /* 3 */
  798. XX        "rdm",        /* 4 */
  799. XX        "seqpak"    /* 5 */
  800. XX    };
  801. XX#define    STYPEMAX 5
  802. XX    struct socket    so;
  803. XX    struct protosw    proto;
  804. XX    struct domain    dom;
  805. XX    struct inpcb    inpcb;
  806. XX    struct unpcb    unpcb;
  807. XX    int len;
  808. XX    char dname[32], *strcpy();
  809. XX
  810. XX    /* fill in socket */
  811. XX    if (kread((ls_t)sock, (char *)&so, sizeof(so)) != sizeof(so)) {
  812. XX        rerr2(errno, (int)sock, "socket");
  813. XX        return;
  814. XX    }
  815. XX
  816. XX    /* fill in protosw entry */
  817. XX    if (kread((ls_t)so.so_proto, (char *)&proto, sizeof(proto))
  818. XX    != sizeof(proto)) {
  819. XX        rerr2(errno, (int)so.so_proto, "protosw");
  820. XX        return;
  821. XX    }
  822. XX
  823. XX    /* fill in domain */
  824. XX    if (kread((ls_t)proto.pr_domain, (char *)&dom, sizeof(dom))
  825. XX    != sizeof(dom)) {
  826. XX        rerr2(errno, (int)proto.pr_domain, "domain");
  827. XX        return;
  828. XX    }
  829. XX
  830. XX    /*
  831. XX     * grab domain name
  832. XX     * kludge "internet" --> "inet" for brevity
  833. XX     */
  834. XX    if (dom.dom_family == AF_INET)
  835. XX        (void)strcpy(dname, "inet");
  836. XX    else {
  837. XX        if ((len = kread((ls_t)dom.dom_name, dname, sizeof(dname) -1))
  838. XX        < 0) {
  839. XX            rerr2(errno, (int)dom.dom_name, "char");
  840. XX            dname[0] = '\0';
  841. XX        }
  842. XX        else
  843. XX            dname[len] = '\0';
  844. XX    }
  845. XX
  846. XX    if ((u_short)so.so_type > STYPEMAX)
  847. XX        (void) printf("* (%s unk%d %x", dname, so.so_type, so.so_state);
  848. XX    else
  849. XX        (void) printf("* (%s %s %x", dname, stypename[so.so_type],
  850. XX            so.so_state);
  851. XX
  852. XX    /* 
  853. XX     * protocol specific formatting
  854. XX     *
  855. XX     * Try to find interesting things to print.  For tcp, the interesting
  856. XX     * thing is the address of the tcpcb, for udp and others, just the
  857. XX     * inpcb (socket pcb).  For unix domain, its the address of the socket
  858. XX     * pcb and the address of the connected pcb (if connected).  Otherwise
  859. XX     * just print the protocol number and address of the socket itself.
  860. XX     * The idea is not to duplicate netstat, but to make available enough
  861. XX     * information for further analysis.
  862. XX     */
  863. XX    switch(dom.dom_family) {
  864. XX    case AF_INET:
  865. XX        getinetproto(proto.pr_protocol);
  866. XX        if (proto.pr_protocol == IPPROTO_TCP ) {
  867. XX            if (so.so_pcb) {
  868. XX                if (kread((ls_t)so.so_pcb, (char *)&inpcb,
  869. XX                    sizeof(inpcb))
  870. XX                != sizeof(inpcb)) {
  871. XX                    rerr2(errno, (int)so.so_pcb, "inpcb");
  872. XX                    return;
  873. XX                }
  874. XX                (void) printf(" %x", (int)inpcb.inp_ppcb);
  875. XX            }
  876. XX        }
  877. XX        else if (so.so_pcb)
  878. XX            (void) printf(" %x", (int)so.so_pcb);
  879. XX        break;
  880. XX    case AF_UNIX:
  881. XX        /* print address of pcb and connected pcb */
  882. XX        if (so.so_pcb) {
  883. XX            (void) printf(" %x", (int)so.so_pcb);
  884. XX            if (kread((ls_t)so.so_pcb, (char *)&unpcb,
  885. XX                sizeof(unpcb))
  886. XX            != sizeof(struct unpcb)) {
  887. XX                rerr2(errno, (int)so.so_pcb, "unpcb");
  888. XX                return;
  889. XX            }
  890. XX            if (unpcb.unp_conn) {
  891. XX                char shoconn[4], *cp;
  892. XX
  893. XX                cp = shoconn;
  894. XX                if (!(so.so_state & SS_CANTRCVMORE))
  895. XX                    *cp++ = '<';
  896. XX                *cp++ = '-';
  897. XX                if (!(so.so_state & SS_CANTSENDMORE))
  898. XX                    *cp++ = '>';
  899. XX                *cp = '\0';
  900. XX                (void) printf(" %s %x", shoconn,
  901. XX                    (int)unpcb.unp_conn);
  902. XX            }
  903. XX        }
  904. XX        break;
  905. XX    default:
  906. XX        /* print protocol number and socket address */
  907. XX        (void) printf(" %d %x", proto.pr_protocol, (int)sock);
  908. XX    }
  909. XX    (void) printf(")\n");
  910. XX}
  911. XX
  912. XX/*
  913. XX * getinetproto --
  914. XX *    print name of protocol number
  915. XX */
  916. XXstatic
  917. XXgetinetproto(number)
  918. XX    int number;
  919. XX{
  920. XX    char *cp;
  921. XX
  922. XX    switch(number) {
  923. XX    case IPPROTO_IP:
  924. XX        cp = "ip";
  925. XX        break;
  926. XX    case IPPROTO_ICMP:
  927. XX        cp ="icmp";
  928. XX        break;
  929. XX    case IPPROTO_GGP:
  930. XX        cp ="ggp";
  931. XX        break;
  932. XX    case IPPROTO_TCP:
  933. XX        cp ="tcp";
  934. XX        break;
  935. XX    case IPPROTO_EGP:
  936. XX        cp ="egp";
  937. XX        break;
  938. XX    case IPPROTO_PUP:
  939. XX        cp ="pup";
  940. XX        break;
  941. XX    case IPPROTO_UDP:
  942. XX        cp ="udp";
  943. XX        break;
  944. XX#ifdef    IPPROTO_IDP
  945. XX    case IPPROTO_IDP:
  946. XX        cp ="idp";
  947. XX        break;
  948. XX#endif
  949. XX    case IPPROTO_RAW:
  950. XX        cp ="raw";
  951. XX        break;
  952. XX    default:
  953. XX        (void) printf(" %d", number);
  954. XX        return;
  955. XX    }
  956. XX    (void) printf(" %s", cp);
  957. XX}
  958. XX
  959. XXstatic
  960. XXreadf()
  961. XX{
  962. XX    struct file lfile;
  963. XX    int i;
  964. XX
  965. XX    itrans(DTYPE_INODE, (char *)u->u_cdir, WD);
  966. XX    for (i = 0; i < NOFILE; i++) {
  967. XX#ifdef    DYNIX
  968. XX        if (u->u_lofile[i].of_file == NULL)
  969. XX            continue;
  970. XX        if (kread((ls_t)vtophys((ls_t)u->u_lofile[i].of_file),
  971. XX#else
  972. XX        if (u->u_ofile[i] == 0)
  973. XX            continue;
  974. XX        if (kread((ls_t)u->u_ofile[i],
  975. XX#endif
  976. XX            (char *)&lfile, sizeof(lfile)) != sizeof(lfile))
  977. XX        {
  978. XX            rerr1("file", N_KMEM);
  979. XX            continue;
  980. XX        }
  981. XX        itrans(lfile.f_type, (char *)lfile.f_data, i);
  982. XX    }
  983. XX}
  984. XX
  985. XXstatic
  986. XXdevmatch(idev, inum, name)
  987. XX    dev_t idev;
  988. XX    ino_t inum;
  989. XX    char  **name;
  990. XX{
  991. XX    register DEVS *d;
  992. XX
  993. XX    for (d = devs; d; d = d->next)
  994. XX        if (d->dev == idev && (d->inum == 0 || d->inum == inum)) {
  995. XX            *name = d->name;
  996. XX            return(1);
  997. XX        }
  998. XX    return(0);
  999. XX}
  1000. XX
  1001. XXstatic
  1002. XXgetfname(filename)
  1003. XX    char *filename;
  1004. XX{
  1005. XX    struct stat statbuf;
  1006. XX    DEVS *cur;
  1007. XX    char *malloc();
  1008. XX
  1009. XX    if (stat(filename, &statbuf)) {
  1010. XX        perror(filename);
  1011. XX        return(0);
  1012. XX    }
  1013. XX    if ((cur = (DEVS *)malloc(sizeof(DEVS))) == NULL) {
  1014. XX        (void) fprintf(stderr, "%s: out of space\n", pname);
  1015. XX        exit(1);
  1016. XX    }
  1017. XX    cur->next = devs;
  1018. XX    devs = cur;
  1019. XX
  1020. XX    /* if file is block special, look for open files on it */
  1021. XX    if ((statbuf.st_mode & S_IFMT) != S_IFBLK) {
  1022. XX        cur->inum = statbuf.st_ino;
  1023. XX        cur->dev = statbuf.st_dev;
  1024. XX    }
  1025. XX    else {
  1026. XX        cur->inum = 0;
  1027. XX        cur->dev = statbuf.st_rdev;
  1028. XX    }
  1029. XX    cur->name = filename;
  1030. XX    return(1);
  1031. XX}
  1032. XX
  1033. XXstatic
  1034. XXopenfiles()
  1035. XX{
  1036. XX#ifdef sun
  1037. XX        if ((kd = kvm_open (NULL, NULL, NULL, O_RDONLY)) == 0) {
  1038. XX            perror ("kvm");
  1039. XX        exit(1);
  1040. XX    }
  1041. XX#endif
  1042. XX    if ((kmem = open(N_KMEM, O_RDONLY, 0)) < 0) {
  1043. XX        perror(N_KMEM);
  1044. XX        exit(1);
  1045. XX    }
  1046. XX    if ((mem = open(N_MEM, O_RDONLY, 0)) < 0) {
  1047. XX        perror(N_MEM);
  1048. XX        exit(1);
  1049. XX    }
  1050. XX    if ((swap = open(N_SWAP, O_RDONLY, 0)) < 0) {
  1051. XX        perror(N_SWAP);
  1052. XX        exit(1);
  1053. XX    }
  1054. XX}
  1055. XX
  1056. XXstatic
  1057. XXkread(addr, buf, len)
  1058. XX    ls_t addr;
  1059. XX    char *buf;
  1060. XX    int len;
  1061. XX{
  1062. XX#ifdef sun
  1063. XX    return(kvm_read(kd, (u_long)addr, buf, len));
  1064. XX#else
  1065. XX    (void) lseek(kmem, addr, L_SET);
  1066. XX    return(read(kmem, buf, len));
  1067. XX#endif
  1068. XX}
  1069. XX
  1070. XXstatic
  1071. XXrerr1(what, fromwhat)
  1072. XX    char *what, *fromwhat;
  1073. XX{
  1074. XX    if (vflg)
  1075. XX        (void) printf("%s: error reading %s from %s",
  1076. XX            pname, what, fromwhat);
  1077. XX}
  1078. XX
  1079. XXstatic
  1080. XXrerr2(err, address, what)
  1081. XX    int err, address;
  1082. XX    char *what;
  1083. XX{
  1084. XX    if (vflg)
  1085. XX        (void) printf("%s: error reading %s at %x from kmem: %s\n",
  1086. XX            pname, what, address, sys_errlist[err]);
  1087. XX}
  1088. XX
  1089. XXstatic long
  1090. XXlgetw(loc)
  1091. XX    ls_t loc;
  1092. XX{
  1093. XX    long word;
  1094. XX
  1095. XX    if (kread((ls_t)loc, (char *)&word, sizeof(word)) != sizeof(word))
  1096. XX        rerr2(errno, (int)loc, "word");
  1097. XX    return(word);
  1098. XX}
  1099. XX
  1100. XXstatic
  1101. XXusage()
  1102. XX{
  1103. XX    (void) fprintf(stderr,
  1104. XX        "usage: %s [-v] [-u user] [-p pid] [filename ...]\n", pname);
  1105. XX    exit(1);
  1106. XX}
  1107. XX
  1108. XX#ifdef    DYNIX
  1109. XXstatic ls_t
  1110. XXvtophys(vaddr)
  1111. XX    ls_t vaddr;
  1112. XX{
  1113. XX    u_int paddr;
  1114. XX    
  1115. XX#ifdef    i386
  1116. XX    if (vaddr < 8192)
  1117. XX        return vaddr;
  1118. XX#endif
  1119. XX    paddr = nl[X_SYSMAP].n_value;
  1120. XX    (void) lseek(kmem, (ls_t)paddr, 0);
  1121. XX    (void) read(kmem, (char *)&paddr, sizeof paddr);
  1122. XX    paddr = (int)((int *)paddr + (vaddr / NBPG));
  1123. XX    (void) lseek(kmem, (ls_t)paddr, 0);
  1124. XX    (void) read(kmem, (char *)&paddr, sizeof paddr);
  1125. XX#ifndef    i386
  1126. XX# define    PTBITS    0x1ff    /* 512 byte pages */
  1127. XX#else
  1128. XX# define    PTBITS    0xfff    /* 4096 byte pages */
  1129. XX#endif
  1130. XX
  1131. XX    return ((ls_t)(paddr & ~PTBITS) | (vaddr & PTBITS));
  1132. XX}
  1133. XX#endif    /* DYNIX  */
  1134. SHAR_EOF
  1135. if test 20280 -ne "`wc -c fstat.c`"
  1136. then
  1137. echo shar: error transmitting fstat.c '(should have been 20280 characters)'
  1138. fi
  1139. echo shar: extracting fstat.8 '(6096 characters)'
  1140. sed 's/^XX//' << \SHAR_EOF > fstat.8
  1141. XX.\" Copyright (c) 1987 Regents of the University of California.
  1142. XX.\" All rights reserved.
  1143. XX.\"
  1144. XX.\" Redistribution and use in source and binary forms are permitted
  1145. XX.\" provided that the above copyright notice and this paragraph are
  1146. XX.\" duplicated in all such forms and that any documentation,
  1147. XX.\" advertising materials, and other materials related to such
  1148. XX.\" distribution and use acknowledge that the software was developed
  1149. XX.\" by the University of California, Berkeley.  The name of the
  1150. XX.\" University may not be used to endorse or promote products derived
  1151. XX.\" from this software without specific prior written permission.
  1152. XX.\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1153. XX.\" IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1154. XX.\" WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1155. XX.\"
  1156. XX.\"    @(#)fstat.8    5.4 (Berkeley) 7/9/88
  1157. XX.\"
  1158. XX.TH FSTAT 8 "July 9, 1988"
  1159. XX.UC 4
  1160. XX.SH NAME
  1161. XXfstat \- identify open files
  1162. XX.SH SYNOPSIS
  1163. XX.B fstat
  1164. XX[
  1165. XX.B \-u
  1166. XXuser ] [
  1167. XX.B \-p
  1168. XXpid ] [
  1169. XX.B filename... 
  1170. XX]
  1171. XX.SH DESCRIPTION
  1172. XX.I Fstat
  1173. XXidentifies open files.
  1174. XXA file is considered open if a process has it open,
  1175. XXif it is the working directory for a process,
  1176. XXor if it is an active pure text file.
  1177. XXIf no options are specified,
  1178. XX.I fstat
  1179. XXreports on all open files.
  1180. XX.SH OPTIONS
  1181. XX.TP \w`filename...`u+4
  1182. XX.B  \-u
  1183. XXrequests a report of all files open by a specified user.
  1184. XX.TP
  1185. XX.B  \-p
  1186. XXrequests a report of all files open by a specified process id.
  1187. XX.TP
  1188. XX.B filename...
  1189. XXrestricts the reports to the specified files.
  1190. XXIf a file is a block special file,
  1191. XX.I fstat
  1192. XXadditionally reports on any open files on that device,
  1193. XXtreating it as a mounted file system.  
  1194. XX.SH OUTPUT
  1195. XXThe following fields are printed
  1196. XX.TP \w'sockets'u+4
  1197. XX.B  USER
  1198. XXis the user name of the owner of the process.
  1199. XX.TP
  1200. XX.B CMD
  1201. XXis the command name of the process.
  1202. XX.TP
  1203. XX.B PID
  1204. XXis the process id.
  1205. XX.TP
  1206. XX.B FD
  1207. XXis the file descriptor number in the per\-process open file table.
  1208. XXThere are two special file descriptors:
  1209. XX.RS
  1210. XX.TP \w'text'u+4
  1211. XX.B text
  1212. XXmeans that the file is the pure text inode (gnode under ULTRIX)
  1213. XXof the process.
  1214. XXPure text inodes do not exist on DYNIX and Sun hosts.
  1215. XX.TP
  1216. XX.B wd
  1217. XXsignifies the working directory of the process.
  1218. XX.RE
  1219. XX.IP
  1220. XXIf the file number is followed by an asterisk (*), then the file is not an
  1221. XXinode (gnode under ULTRIX), but either a socket, FIFO, or has an error of
  1222. XXsome kind.
  1223. XXThe format of the rest of the entry is variable, doesn't correspond
  1224. XXto the headings, and is enclosed in parenthesis.
  1225. XXThe
  1226. XX.B SOCKET
  1227. XXsection describes the variable format for sockets.
  1228. XX.TP
  1229. XX.B DEVICE
  1230. XXis a display of the major and minor numbers of the device where this
  1231. XXfile's inode (gnode under ULTRIX) resides.
  1232. XX.IP
  1233. XXIf the file lacks an inode \- e. g., a Sun, stream, clone file \- the
  1234. XXdevice information is taken from the vnode, and represents the file's
  1235. XXmajor and minor device numbers.
  1236. XX.TP
  1237. XX.B INODE
  1238. XXis the inode (gnode under ULTRIX) number of the file.
  1239. XXIt will be ``none'' on Sun hosts where the file is a cloned stream.
  1240. XX.TP
  1241. XX.B SIZE
  1242. XXis the size in bytes of the file, where applicable.
  1243. XX.TP
  1244. XX.B TYPE
  1245. XXis the type of the file, as found in
  1246. XX.I /usr/include/sys/file.h
  1247. XX(or
  1248. XX.I /usr/include/sys/vnode.h
  1249. XXon Sun hosts.)
  1250. XX.I 
  1251. XX.TP
  1252. XX.B NAME
  1253. XXare the specified file names, if any.
  1254. XX.TP
  1255. XX.B SOCKET
  1256. XXThe information displayed for an open socket depends on its protocol domain.
  1257. XXThe first three fields are always the same:
  1258. XXfield one is the domain name;
  1259. XXfield two is the socket type (stream, dgram, etc);
  1260. XXand field three is the socket flags field in hex (see
  1261. XX.IR /usr/include/sys/socketvar.h .)
  1262. XX.IP
  1263. XXThe remaining fields are protocol dependent.
  1264. XXThere is a final field for TCP sockets: the address of the TCPCB;
  1265. XXfor UDP, the INPCB (socket PCB).
  1266. XXFor \s-2UNIX\s0 domain sockets, the remaining two fields display the address
  1267. XXof the socket PCB and the address of the connected PCB.
  1268. XXOtherwise, the protocol number and address of the socket itself are printed
  1269. XXas the final field.
  1270. XX.IP
  1271. XXThe intent is to supplement
  1272. XX.IR netstat (8).
  1273. XXFor example, the addresses mentioned above are the addresses that
  1274. XXthe ``netstat -A'' command would print for TCP, UDP, and \s-2UNIX\s0
  1275. XXdomain.
  1276. XX.IP
  1277. XXNote that, since
  1278. XX.IR pipe (2)
  1279. XXis implemented with sockets, a pipe appears as
  1280. XXa connected \s-2UNIX\s0 domain stream socket.
  1281. XXA unidirectional \s-2UNIX\s0
  1282. XXdomain socket indicates the direction of
  1283. XXflow with an arrow (``<-'' or ``->''), and a full duplex socket shows
  1284. XXa double arrow (``<->'').
  1285. XX.SH EXAMPLES
  1286. XXThis example shows the use of
  1287. XX.I fstat
  1288. XXto display information on the file
  1289. XX.IR /usr/spool/lpd/lock .
  1290. XX.PP
  1291. XX.nf
  1292. XX% fstat /usr/spool/lpd/lock
  1293. XX.br
  1294. XXUSER    CMD    PID    FD    DEVICE    INODE    SIZE    TYPE    NAME
  1295. XXroot    lpd    113    3    9,    35    26683    6    reg    /usr/spool/lpd/lock
  1296. XX.fi
  1297. XX.PP
  1298. XXThis example shows the use of
  1299. XX.I fstat
  1300. XXto display all the files of a process that has
  1301. XX.I /usr/spool/lpd/lock
  1302. XXopen.
  1303. XX.PP
  1304. XX.nf
  1305. XX% fstat -p 113
  1306. XXUSER    CMD    PID    FD    DEVICE    INODE    SIZE     TYPE
  1307. XXroot    lpd    113    text    9,    35    18949    74752    reg
  1308. XXroot    lpd    113    wd    9,    35    26624    512      dir
  1309. XXroot    lpd    113    0    9,    0    4103     0        chr
  1310. XXroot    lpd    113    1    9,    0    4103     0        chr
  1311. XXroot    lpd    113    2    9,    35    26634    37        reg
  1312. XXroot    lpd    113    3    9,    35    26683    6         reg 
  1313. XXroot    lpd    113    4*    (inet stream 80 tcp 80f6770c)
  1314. XX.fi
  1315. XX.PP
  1316. XXThis example shows the use of
  1317. XX.IR netstat (8),
  1318. XX.IR grep (1)
  1319. XXand
  1320. XX.I fstat
  1321. XXto locate the process that has a socket open on the ``smtp''
  1322. XXnetwork port.
  1323. XXThe
  1324. XX.B \-aA
  1325. XXarguments direct
  1326. XX.I netstat
  1327. XXto display all protocol control block (PCB) addresses,
  1328. XXand the
  1329. XX.I fstat
  1330. XXcommand displays all files, filtering the output through
  1331. XX.I grep
  1332. XXto locate the specific PCB.
  1333. XX.PP
  1334. XX.nf
  1335. XX% netstat -aA | grep smtp
  1336. XX80f67a8c tcp  0  0  *.smtp  *.*  LISTEN
  1337. XX% fstat | grep 80f67a8c
  1338. XXroot    sendmail    108    5* (inet stream 80 tcp 80f67a8c)
  1339. XX.fi
  1340. XX.SH BUGS
  1341. XXSocket information clutters the output.
  1342. XX.PP
  1343. XXSince \fIfstat\fP takes a snapshot of the system, it is only correct for
  1344. XXa very short period of time.
  1345. XX.PP
  1346. XX.I Fstat
  1347. XXdoes not work on diskless Sun clients, because there are no inodes.
  1348. XX.SH AUTHORS
  1349. XX.I Fstat
  1350. XXcomes from the 4.3BSD Tahoe distribution.
  1351. XX.PP
  1352. XXVic Abell of the Purdue University Computing Center ported it to
  1353. XXDYNIX 3.0.1[24] for the Sequent Balance and Symmetry machines,
  1354. XXSunOS 4.0 and ULTRIX 2.2.
  1355. XX.SH SEE ALSO
  1356. XXps(1),
  1357. XXpstat(8),
  1358. XXofiles(8L).
  1359. SHAR_EOF
  1360. if test 6096 -ne "`wc -c fstat.8`"
  1361. then
  1362. echo shar: error transmitting fstat.8 '(should have been 6096 characters)'
  1363. fi
  1364. #    End of shell archive
  1365. exit 0
  1366.  
  1367.