home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / unix / volume18 / fstat2 < prev    next >
Encoding:
Internet Message Format  |  1989-04-20  |  33.0 KB

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