# 2.11BSD#431 - /usr/src/usr.bin/fstat/fstat.c

##### Functions

    main              X
    read              X

##### Variables

    Usrptma           X
    copyright         X
    devs              X
    dname             X
    dom               X
    inpcb             X
    len               X
    mproc             X
    proto             X
    so                X
    unpcb             X
    usrpt             X

##### Macros

    KERNEL            X
    N_KMEM            X
    N_MEM             X
    N_SWAP            X
    N_UNIX            X
    STYPEMAX          X
    TEXT              X
    WD                X
    X_NETDATA         X
    X_NPROC           X
    X_PROC            X
    X_USRPT           X
    X_USRPTMA         X
    i_dev             X
    i_mode            X
    i_number          X
    i_size            X
    inode             X
    x_iptr            X

##### struct's

    devs              X

##### typedef's

    DEVS              X

       1: /*
       2:  * Copyright (c) 1987 Regents of the University of California.
       3:  * All rights reserved.
       4:  *
       5:  * Redistribution and use in source and binary forms are permitted
       6:  * provided that this notice is preserved and that due credit is given
       7:  * to the University of California at Berkeley. The name of the University
       8:  * may not be used to endorse or promote products derived from this
       9:  * software without specific prior written permission. This software
      10:  * is provided ``as is'' without express or implied warranty.
      11:  */
      12:
      13: #if defined(DOSCCS) && !defined(lint)
      14: char copyright[] =
      15: "@(#) Copyright (c) 1987 Regents of the University of California.\n\
      16:  All rights reserved.\n";
      17:
      18: static char sccsid[] = "@(#)fstat.c	5.11.1 (2.11BSD GTE) 12/31/93";
      19: #endif
      20:
      21: /*
      22:  *  fstat
      23:  */
      24: #include <sys/param.h>
      25: #include <sys/user.h>
      26: #include <sys/proc.h>
      27: #include <sys/text.h>
      28: #include <sys/stat.h>
      29: #include <sys/inode.h>
      30: #include <sys/socket.h>
      31: #include <sys/socketvar.h>
      32: #include <sys/domain.h>
      33: #include <sys/protosw.h>
      34: #include <sys/unpcb.h>
      35: #include <sys/vmmac.h>
      36: #define KERNEL
      37: #include <sys/file.h>
      38: #undef  KERNEL
      39: #include <net/route.h>
      40: #include <netinet/in.h>
      41: #include <netinet/in_pcb.h>
      42: #include <stdio.h>
      43: #include <ctype.h>
      44: #include <nlist.h>
      45: #include <pwd.h>
      46:
      47: #ifdef  ULTRIX
      48:         /* UFS -> GFS */
      49: #    define inode   gnode
      50: #    define x_iptr  x_gptr
      51: #    define i_dev   g_dev
      52: #    define i_number g_number
      53: #    define i_mode  g_mode
      54: #    define i_size  g_size
      55: #endif
      56:
      57: #define N_KMEM  "/dev/kmem"
      58: #define N_MEM   "/dev/mem"
      59: #define N_SWAP  "/dev/drum"
      60: #define N_UNIX  "/vmunix"
      61:
      62: #define TEXT    -2
      63: #define WD  -1
      64:
      65: typedef struct devs {
      66:     struct devs *next;
      67:     dev_t   dev;
      68:     int inum;
      69:     char    *name;
      70: } DEVS;
      71: DEVS    *devs;
      72:
      73: #ifdef pdp11
      74: static struct nlist nl[] = {
      75:     { "_proc" },
      76: #define X_PROC      0
      77:     { "_nproc" },
      78: #define X_NPROC     1
      79:     { "_netdata" },
      80: #define X_NETDATA   2
      81:     { "" },
      82: };
      83: #else
      84: static struct nlist nl[] = {
      85:     { "_proc" },
      86: #define X_PROC      0
      87:     { "_Usrptmap" },
      88: #define X_USRPTMA   1
      89:     { "_nproc" },
      90: #define X_NPROC     2
      91:     { "_usrpt" },
      92: #define X_USRPT     3
      93:     { "" },
      94: };
      95: #endif
      96:
      97: struct proc *mproc;
      98: #ifndef pdp11
      99: struct pte  *Usrptma, *usrpt;
     100: #endif
     101:
     102: union {
     103:     struct  user user;
     104: #ifdef pdp11
     105:     char    upages[ctob(USIZE)];
     106: #else
     107:     char    upages[UPAGES][NBPG];
     108: #endif
     109: } user;
     110:
     111: extern int  errno;
     112: static int  fflg, vflg;
     113: static int  kmem, mem, nproc, swap;
     114: static char *uname;
     115: #ifdef pdp11
     116: static off_t    netdata;
     117: long    lgetw();
     118: #endif
     119:
     120: off_t   lseek();
     121:
     122: main(argc, argv)
     123:     int argc;
     124:     char    **argv;
     125: {
     126:     extern char *optarg;
     127:     extern int optind;
     128:     register struct passwd *passwd;
     129:     register int pflg, pid, uflg, uid;
     130:     int ch, size;
     131:     struct passwd *getpwnam(), *getpwuid();
     132:     long lgetw();
     133:     char *malloc();
     134:
     135:     pflg = uflg = 0;
     136:     while ((ch = getopt(argc, argv, "p:u:v")) != EOF)
     137:         switch((char)ch) {
     138:         case 'p':
     139:             if (pflg++)
     140:                 usage();
     141:             if (!isdigit(*optarg)) {
     142:                 fputs("fstat: -p option requires a process id.\n", stderr);
     143:                 usage();
     144:             }
     145:             pid = atoi(optarg);
     146:             break;
     147:         case 'u':
     148:             if (uflg++)
     149:                 usage();
     150:             if (!(passwd = getpwnam(optarg))) {
     151:                 fprintf(stderr, "%s: unknown uid\n", optarg);
     152:                 exit(1);
     153:             }
     154:             uid = passwd->pw_uid;
     155:             uname = passwd->pw_name;
     156:             break;
     157:         case 'v':   /* undocumented: print read error messages */
     158:             vflg++;
     159:             break;
     160:         case '?':
     161:         default:
     162:             usage();
     163:         }
     164:
     165:     if (*(argv += optind)) {
     166:         for (; *argv; ++argv) {
     167:             if (getfname(*argv))
     168:                 fflg = 1;
     169:         }
     170:         if (!fflg)  /* file(s) specified, but none accessable */
     171:             exit(1);
     172:     }
     173:
     174:     openfiles();
     175:
     176:     if (nlist(N_UNIX, nl) == -1 || !nl[0].n_type) {
     177:         fprintf(stderr, "%s: No namelist\n", N_UNIX);
     178:         exit(1);
     179:     }
     180: #ifdef pdp11
     181:     if (nl[X_NETDATA].n_type) {
     182:         netdata = lgetw((off_t)nl[X_NETDATA].n_value);
     183:         netdata = ctob(netdata);
     184:     }
     185: #else
     186:     Usrptma = (struct pte *)nl[X_USRPTMA].n_value;
     187:     usrpt = (struct pte *) nl[X_USRPT].n_value;
     188: #endif
     189:     nproc = (int)lgetw((off_t)nl[X_NPROC].n_value);
     190:
     191: #ifdef pdp11
     192:     (void)lseek(kmem, (off_t)nl[X_PROC].n_value, L_SET);
     193: #else
     194:     (void)lseek(kmem, lgetw((off_t)nl[X_PROC].n_value), L_SET);
     195: #endif
     196:     size = nproc * sizeof(struct proc);
     197:     if ((mproc = (struct proc *)malloc((u_int)size)) == NULL) {
     198:         fprintf(stderr, "fstat: out of space.\n");
     199:         exit(1);
     200:     }
     201:     if (read(kmem, (char *)mproc, size) != size)
     202:         rerr1("proc table", N_KMEM);
     203:
     204:     printf("USER\t CMD\t      PID    FD\tDEVICE\tINODE\t  SIZE TYPE%s\n",
     205:         fflg ? " NAME" : "");
     206:     for (; nproc--; ++mproc) {
     207:         if (mproc->p_stat == 0)
     208:             continue;
     209:         if (pflg && mproc->p_pid != pid)
     210:             continue;
     211:         if (uflg)  {
     212:             if (mproc->p_uid != uid)
     213:                 continue;
     214:         }
     215:         else
     216:             uname = (passwd = getpwuid(mproc->p_uid)) ?
     217:                 passwd->pw_name : "unknown";
     218:         if (mproc->p_stat != SZOMB && getu() == 0)
     219:             continue;
     220:         dotext();
     221:         readf();
     222:     }
     223:     exit(0);
     224: }
     225:
     226: #ifndef pdp11
     227: static
     228: getu()
     229: {
     230:     struct pte *pteaddr, apte;
     231:     struct pte arguutl[UPAGES+CLSIZE];
     232:     register int i;
     233:     int ncl;
     234:
     235:     if ((mproc->p_flag & SLOAD) == 0) {
     236:         if (swap < 0)
     237:             return(0);
     238:         (void)lseek(swap, (off_t)dtob(mproc->p_swaddr), L_SET);
     239:         if (read(swap, (char *)&user.user, sizeof(struct user))
     240:             != sizeof(struct user)) {
     241:             fprintf(stderr, "fstat: can't read u for pid %d from %s\n", mproc->p_pid, N_SWAP);
     242:             return(0);
     243:         }
     244:         return(1);
     245:     }
     246:     pteaddr = &Usrptma[btokmx(mproc->p_p0br) + mproc->p_szpt - 1];
     247:     (void)lseek(kmem, (off_t)pteaddr, L_SET);
     248:     if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
     249:         printf("fstat: can't read indir pte to get u for pid %d from %s\n", mproc->p_pid, N_SWAP);
     250:         return(0);
     251:     }
     252:     (void)lseek(mem, (off_t)ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE)
     253:         * sizeof(struct pte), L_SET);
     254:     if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
     255:         printf("fstat: can't read page table for u of pid %d from %s\n", mproc->p_pid, N_KMEM);
     256:         return(0);
     257:     }
     258:     ncl = (sizeof(struct user) + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
     259:     while (--ncl >= 0) {
     260:         i = ncl * CLSIZE;
     261:         (void)lseek(mem, (off_t)ctob(arguutl[CLSIZE+i].pg_pfnum), L_SET);
     262:         if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
     263:             printf("fstat: can't read page %u of u of pid %d from %s\n", arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid, N_MEM);
     264:             return(0);
     265:         }
     266:     }
     267:     return(1);
     268: }
     269: #else
     270: static
     271: getu()
     272: {
     273:
     274:     if ((mproc->p_flag & SLOAD) == 0) {
     275:         if (swap < 0)
     276:             return(0);
     277:         (void)lseek(swap, (off_t)(mproc->p_addr)<<9, L_SET);
     278:         if (read(swap, (char *)&user.user, sizeof(struct user))
     279:             != sizeof(struct user)) {
     280:             fprintf(stderr, "fstat: can't read u for pid %d from %s\n", mproc->p_pid, N_SWAP);
     281:             return(0);
     282:         }
     283:         return(1);
     284:     }
     285:     (void)lseek(mem, (off_t)ctob((off_t)mproc->p_addr), L_SET);
     286:     if (read(mem, &user.user, sizeof(user.user))!=sizeof(user.user)) {
     287:         printf("fstat: can't read page table for u of pid %d from %s\n", mproc->p_pid, N_MEM);
     288:         return(0);
     289:     }
     290:     return(1);
     291: }
     292: #endif
     293:
     294: static
     295: dotext()
     296: {
     297:     struct text text;
     298:
     299: #ifdef pdp11
     300:     if (!mproc->p_textp)
     301:         return;
     302: #endif
     303:     (void)lseek(kmem, (off_t)mproc->p_textp, L_SET);
     304:     if (read(kmem, (char *) &text, sizeof(text)) != sizeof(text)) {
     305:         rerr1("text table", N_KMEM);
     306:         return;
     307:     }
     308:     if (text.x_flag)
     309:         itrans(DTYPE_INODE, text.x_iptr, TEXT);
     310: }
     311:
     312: static
     313: itrans(ftype, g, fno)
     314:     int ftype, fno;
     315:     struct inode    *g;     /* if ftype is inode */
     316: {
     317:     struct inode inode;
     318:     dev_t idev;
     319:     char *comm, *itype();
     320:     char *name = (char *)NULL;  /* set by devmatch() on a match */
     321:
     322:     if (g || fflg) {
     323:         (void)lseek(kmem, (off_t)g, L_SET);
     324:         if (read(kmem, (char *)&inode, sizeof(inode)) != sizeof(inode)) {
     325:             rerr2(errno, (int)g, "inode");
     326:             return;
     327:         }
     328:         idev = inode.i_dev;
     329:         if (fflg && !devmatch(idev, inode.i_number, &name))
     330:             return;
     331:     }
     332:     if (mproc->p_pid == 0)
     333:         comm = "swapper";
     334: #ifndef pdp11
     335:     else if (mproc->p_pid == 2)
     336:         comm = "pagedaemon";
     337: #endif
     338:     else
     339:         comm = user.user.u_comm;
     340:     printf("%-8.8s %-10.10s %5d  ", uname, comm, mproc->p_pid);
     341:
     342:     switch(fno) {
     343:     case WD:
     344:         printf("  wd"); break;
     345:     case TEXT:
     346:         printf("text"); break;
     347:     default:
     348:         printf("%4d", fno);
     349:     }
     350:
     351:     if (g == 0) {
     352:         printf("* (deallocated)\n");
     353:         return;
     354:     }
     355:
     356:     switch(ftype) {
     357:     case DTYPE_INODE:
     358: #ifdef pdp11
     359:     case DTYPE_PIPE:
     360: #endif
     361:         printf("\t%2d, %2d\t%5lu\t%6ld\t%3s %s\n", major(inode.i_dev),
     362:             minor(inode.i_dev), (long)inode.i_number,
     363:             inode.i_mode == IFSOCK ? 0L : inode.i_size,
     364: #ifdef pdp11
     365:             ftype == DTYPE_PIPE ? "pip" :
     366: #endif
     367:             itype(inode.i_mode), name ? name : "");
     368:         break;
     369:     case DTYPE_SOCKET:
     370:         socktrans((struct socket *)g);
     371:         break;
     372: #ifdef DTYPE_PORT
     373:     case DTYPE_PORT:
     374:         printf("* (fifo / named pipe)\n");
     375:         break;
     376: #endif
     377:     default:
     378:         printf("* (unknown file type)\n");
     379:     }
     380: }
     381:
     382: static char *
     383: itype(mode)
     384:     u_short mode;
     385: {
     386:     switch(mode & IFMT) {
     387:     case IFCHR:
     388:         return("chr");
     389:     case IFDIR:
     390:         return("dir");
     391:     case IFBLK:
     392:         return("blk");
     393:     case IFREG:
     394:         return("reg");
     395:     case IFLNK:
     396:         return("lnk");
     397:     case IFSOCK:
     398:         return("soc");
     399:     default:
     400:         return("unk");
     401:     }
     402:     /*NOTREACHED*/
     403: }
     404:
     405: static
     406: socktrans(sock)
     407:     struct socket *sock;
     408: {
     409:     static char *stypename[] = {
     410:         "unused",   /* 0 */
     411:         "stream",   /* 1 */
     412:         "dgram",    /* 2 */
     413:         "raw",      /* 3 */
     414:         "rdm",      /* 4 */
     415:         "seqpak"    /* 5 */
     416:     };
     417: #define STYPEMAX 5
     418:     struct socket   so;
     419:     struct protosw  proto;
     420:     struct domain   dom;
     421:     struct inpcb    inpcb;
     422:     struct unpcb    unpcb;
     423:     int len;
     424:     char dname[32], *strcpy();
     425:
     426:     /* fill in socket */
     427: #ifdef pdp11
     428:     (void)lseek(mem, (off_t)sock + netdata, L_SET);
     429:     if (read(mem, (char *)&so, sizeof(struct socket))
     430: #else
     431:     (void)lseek(kmem, (off_t)sock, L_SET);
     432:     if (read(kmem, (char *)&so, sizeof(struct socket))
     433: #endif
     434:         != sizeof(struct socket)) {
     435:         rerr2(errno, (int)sock, "socket");
     436:         return;
     437:     }
     438:
     439:     /* fill in protosw entry */
     440: #ifdef pdp11
     441:     (void)lseek(mem, (off_t)so.so_proto + netdata, L_SET);
     442:     if (read(mem, (char *)&proto, sizeof(struct protosw))
     443: #else
     444:     (void)lseek(kmem, (off_t)so.so_proto, L_SET);
     445:     if (read(kmem, (char *)&proto, sizeof(struct protosw))
     446: #endif
     447:         != sizeof(struct protosw)) {
     448:         rerr2(errno, (int)so.so_proto, "protosw");
     449:         return;
     450:     }
     451:
     452:     /* fill in domain */
     453: #ifdef pdp11
     454:     (void)lseek(mem, (off_t)proto.pr_domain + netdata, L_SET);
     455:     if (read(mem, (char *)&dom, sizeof(struct domain))
     456: #else
     457:     (void)lseek(kmem, (off_t)proto.pr_domain, L_SET);
     458:     if (read(kmem, (char *)&dom, sizeof(struct domain))
     459: #endif
     460:         != sizeof(struct domain)) {
     461:         rerr2(errno, (int)proto.pr_domain, "domain");
     462:         return;
     463:     }
     464:
     465:     /*
     466: 	 * grab domain name
     467: 	 * kludge "internet" --> "inet" for brevity
     468: 	 */
     469:     if (dom.dom_family == AF_INET)
     470:         (void)strcpy(dname, "inet");
     471:     else {
     472: #ifdef pdp11
     473:         (void)lseek(mem, (off_t)dom.dom_name + netdata, L_SET);
     474:         if ((len = read(mem, dname, sizeof(dname) - 1)) < 0) {
     475: #else
     476:         (void)lseek(kmem, (off_t)dom.dom_name, L_SET);
     477:         if ((len = read(kmem, dname, sizeof(dname) - 1)) < 0) {
     478: #endif
     479:             rerr2(errno, (int)dom.dom_name, "char");
     480:             dname[0] = '\0';
     481:         }
     482:         else
     483:             dname[len] = '\0';
     484:     }
     485:
     486:     if ((u_short)so.so_type > STYPEMAX)
     487:         printf("* (%s unk%d %x", dname, so.so_type, so.so_state);
     488:     else
     489:         printf("* (%s %s %x", dname, stypename[so.so_type],
     490:             so.so_state);
     491:
     492:     /*
     493: 	 * protocol specific formatting
     494: 	 *
     495: 	 * Try to find interesting things to print.  For tcp, the interesting
     496: 	 * thing is the address of the tcpcb, for udp and others, just the
     497: 	 * inpcb (socket pcb).  For unix domain, its the address of the socket
     498: 	 * pcb and the address of the connected pcb (if connected).  Otherwise
     499: 	 * just print the protocol number and address of the socket itself.
     500: 	 * The idea is not to duplicate netstat, but to make available enough
     501: 	 * information for further analysis.
     502: 	 */
     503:     switch(dom.dom_family) {
     504:     case AF_INET:
     505:         getinetproto(proto.pr_protocol);
     506:         if (proto.pr_protocol == IPPROTO_TCP ) {
     507:             if (so.so_pcb) {
     508: #ifdef pdp11
     509:                 (void)lseek(mem,(off_t)so.so_pcb+netdata,L_SET);
     510:                 if (read(mem, &inpcb, sizeof(struct inpcb))
     511: #else
     512:                 (void)lseek(kmem, (off_t)so.so_pcb, L_SET);
     513:                 if (read(kmem, (char *)&inpcb, sizeof(struct inpcb))
     514: #endif
     515:                     != sizeof(struct inpcb)){
     516:                     rerr2(errno, (int)so.so_pcb, "inpcb");
     517:                     return;
     518:                 }
     519:                 printf(" %x", (int)inpcb.inp_ppcb);
     520:             }
     521:         }
     522:         else if (so.so_pcb)
     523:             printf(" %x", (int)so.so_pcb);
     524:         break;
     525:     case AF_UNIX:
     526:         /* print address of pcb and connected pcb */
     527:         if (so.so_pcb) {
     528:             printf(" %x", (int)so.so_pcb);
     529: #ifdef pdp11
     530:             (void)lseek(mem, (off_t)so.so_pcb + netdata, L_SET);
     531:             if (read(mem, (char *)&unpcb, sizeof(struct unpcb))
     532: #else
     533:             (void)lseek(kmem, (off_t)so.so_pcb, L_SET);
     534:             if (read(kmem, (char *)&unpcb, sizeof(struct unpcb))
     535: #endif
     536:                 != sizeof(struct unpcb)){
     537:                 rerr2(errno, (int)so.so_pcb, "unpcb");
     538:                 return;
     539:             }
     540:             if (unpcb.unp_conn) {
     541:                 char shoconn[4], *cp;
     542:
     543:                 cp = shoconn;
     544:                 if (!(so.so_state & SS_CANTRCVMORE))
     545:                     *cp++ = '<';
     546:                 *cp++ = '-';
     547:                 if (!(so.so_state & SS_CANTSENDMORE))
     548:                     *cp++ = '>';
     549:                 *cp = '\0';
     550:                 printf(" %s %x", shoconn, (int)unpcb.unp_conn);
     551:             }
     552:         }
     553:         break;
     554:     default:
     555:         /* print protocol number and socket address */
     556:         printf(" %d %x", proto.pr_protocol, (int)sock);
     557:     }
     558:     printf(")\n");
     559: }
     560:
     561: /*
     562:  * getinetproto --
     563:  *	print name of protocol number
     564:  */
     565: static
     566: getinetproto(number)
     567:     int number;
     568: {
     569:     char *cp;
     570:
     571:     switch(number) {
     572:     case IPPROTO_IP:
     573:         cp = "ip"; break;
     574:     case IPPROTO_ICMP:
     575:         cp ="icmp"; break;
     576:     case IPPROTO_GGP:
     577:         cp ="ggp"; break;
     578:     case IPPROTO_TCP:
     579:         cp ="tcp"; break;
     580:     case IPPROTO_EGP:
     581:         cp ="egp"; break;
     582:     case IPPROTO_PUP:
     583:         cp ="pup"; break;
     584:     case IPPROTO_UDP:
     585:         cp ="udp"; break;
     586:     case IPPROTO_IDP:
     587:         cp ="idp"; break;
     588:     case IPPROTO_RAW:
     589:         cp ="raw"; break;
     590:     default:
     591:         printf(" %d", number);
     592:         return;
     593:     }
     594:     printf(" %s", cp);
     595: }
     596:
     597: static
     598: readf()
     599: {
     600:     struct file lfile;
     601:     int i;
     602:
     603:     itrans(DTYPE_INODE, user.user.u_cdir, WD);
     604:     for (i = 0; i < NOFILE; i++) {
     605:         if (user.user.u_ofile[i] == 0)
     606:             continue;
     607:         (void)lseek(kmem, (off_t)user.user.u_ofile[i], L_SET);
     608:         if (read(kmem, (char *)&lfile, sizeof(lfile))
     609:             != sizeof(lfile)) {
     610:             rerr1("file", N_KMEM);
     611:             continue;
     612:         }
     613:         itrans(lfile.f_type, (struct inode *)lfile.f_data, i);
     614:     }
     615: }
     616:
     617: static
     618: devmatch(idev, inum, name)
     619:     dev_t idev;
     620:     ino_t inum;
     621:     char  **name;
     622: {
     623:     register DEVS *d;
     624:
     625:     for (d = devs; d; d = d->next)
     626:         if (d->dev == idev && (d->inum == 0 || d->inum == inum)) {
     627:             *name = d->name;
     628:             return(1);
     629:         }
     630:     return(0);
     631: }
     632:
     633: static
     634: getfname(filename)
     635:     char *filename;
     636: {
     637:     struct stat statbuf;
     638:     DEVS *cur;
     639:     char *malloc();
     640:
     641:     if (stat(filename, &statbuf)) {
     642:         perror(filename);
     643:         return(0);
     644:     }
     645:     if ((cur = (DEVS *)malloc(sizeof(DEVS))) == NULL) {
     646:         fprintf(stderr, "fstat: out of space.\n");
     647:         exit(1);
     648:     }
     649:     cur->next = devs;
     650:     devs = cur;
     651:
     652:     /* if file is block special, look for open files on it */
     653:     if ((statbuf.st_mode & S_IFMT) != S_IFBLK) {
     654:         cur->inum = statbuf.st_ino;
     655:         cur->dev = statbuf.st_dev;
     656:     }
     657:     else {
     658:         cur->inum = 0;
     659:         cur->dev = statbuf.st_rdev;
     660:     }
     661:     cur->name = filename;
     662:     return(1);
     663: }
     664:
     665: static
     666: openfiles()
     667: {
     668:     if ((kmem = open(N_KMEM, O_RDONLY, 0)) < 0) {
     669:         perror(N_KMEM);
     670:         exit(1);
     671:     }
     672:     if ((mem = open(N_MEM, O_RDONLY, 0)) < 0) {
     673:         perror(N_MEM);
     674:         exit(1);
     675:     }
     676:     if ((swap = open(N_SWAP, O_RDONLY, 0)) < 0) {
     677:         perror(N_SWAP);
     678:         exit(1);
     679:     }
     680: }
     681:
     682: static
     683: rerr1(what, fromwhat)
     684:     char *what, *fromwhat;
     685: {
     686:     if (vflg)
     687:         printf("fstat: error reading %s from %s", what, fromwhat);
     688: }
     689:
     690: static
     691: rerr2(err, address, what)
     692:     int err, address;
     693:     char *what;
     694: {
     695:     if (vflg)
     696:         printf("error %d reading %s at %x from kmem\n", errno, what, address);
     697: }
     698:
     699: static long
     700: lgetw(loc)
     701:     off_t loc;
     702: {
     703: #ifdef pdp11
     704:     u_short word;
     705: #else
     706:     long word;
     707: #endif
     708:
     709:     (void)lseek(kmem, (off_t)loc, L_SET);
     710:     if (read(kmem, (char *)&word, sizeof(word)) != sizeof(word))
     711:         rerr2(errno, (int)loc, "word");
     712:     return((long)word);
     713: }
     714:
     715: static
     716: usage()
     717: {
     718:     fputs("usage: fstat [-v] [-u user] [-p pid] [filename ...]\n", stderr);
     719:     exit(1);
     720: }

#### Defined functions

devmatch defined in line 617; used 1 times

- in line 329

dotext defined in line 294; used 1 times

- in line 220

getfname defined in line 633; used 1 times

- in line 167

getinetproto defined in line 565; used 1 times

- in line 505

getu defined in line 270; used 1 times

- in line 218

itrans defined in line 312; used 3 times

- in line 309, 603, 613

itype defined in line 382; used 2 times

- in line 319, 367

lgetw defined in line 699; used 5 times

- in line 117, 132, 182, 189-194(2)

main defined in line 122; never used
openfiles defined in line 665; used 1 times

- in line 174

read defined in line 455; used 20 times

- in line 201, 239, 248, 254, 262, 278, 286, 304, 324, 432, 445, 458, 474-477(2), 510-513(2), 531-534(2), 608, 710

readf defined in line 597; used 1 times

- in line 221

rerr1 defined in line 682; used 3 times

- in line 202, 305, 610

rerr2 defined in line 690; used 8 times

- in line 325, 435, 448, 461, 479, 516, 537, 711

socktrans defined in line 405; used 1 times

- in line 370

usage defined in line 715; used 4 times

- in line 140-143(2), 149, 162

#### Defined variables

Usrptma defined in line 99; used 2 times

- in line 186, 246

copyright defined in line 14; never used
devs defined in line 71; used 3 times

- in line 625, 649-650(2)

dname defined in line 424; used 9 times

- in line 470-489(9)

dom defined in line 420; used 7 times

- in line 455-458(2), 469-479(4), 503

fflg defined in line 112; used 5 times

- in line 168-170(2), 205, 322, 329

inpcb defined in line 421; used 3 times

- in line 510-513(2), 519

kmem defined in line 113; used 26 times

- in line 192-194(2), 201, 247-248(2), 303-304(2), 323-324(2), 431-432(2), 444-445(2), 457-458(2), 476-477(2), 512-513(2), 533-534(2), 607-608(2), 668, 709-710(2)

len defined in line 423; used 3 times

- in line 474-477(2), 483

mem defined in line 113; used 19 times

- in line 252-254(2), 261-262(2), 285-286(2), 428-429(2), 441-442(2), 454-455(2), 473-474(2), 509-510(2), 530-531(2), 672

mproc defined in line 97; used 26 times

- in line 197-218(8), 235-249(6), 255, 263, 274-287(5), 300-303(2), 332-340(3)

netdata defined in line 116; used 9 times

- in line 182-183(3), 428, 441, 454, 473, 509, 530

nl defined in line 84; used 9 times

- in line 176-194(9)

nproc defined in line 113; used 3 times

- in line 189, 196, 206

proto defined in line 419; used 8 times

- in line 442-445(2), 454-461(3), 505-506(2), 556

sccsid defined in line 18; never used
so defined in line 418; used 23 times

- in line 429-432(2), 441-448(3), 486-490(5), 507-516(4), 522-537(7), 544-547(2)

swap defined in line 113; used 7 times

- in line 236-239(3), 275-278(3), 676

uname defined in line 114; used 3 times

- in line 155, 216, 340

unpcb defined in line 422; used 4 times

- in line 531-534(2), 540, 550

usrpt defined in line 99; used 1 times

- in line 187

vflg defined in line 112; used 3 times

- in line 158, 686, 695

#### Defined struct's

devs defined in line 65; used 2 times

- in line 66(2)

#### Defined typedef's

DEVS defined in line 70; used 5 times

- in line 71, 623, 638, 645(2)

#### Defined macros

KERNEL defined in line 36; used 1 times

- in line 38

N_KMEM defined in line 57; used 6 times

- in line 202, 255, 305, 610, 668-669(2)

N_MEM defined in line 58; used 4 times

- in line 263, 287, 672-673(2)

N_SWAP defined in line 59; used 5 times

- in line 241, 249, 280, 676-677(2)

N_UNIX defined in line 60; used 2 times

- in line 176-177(2)

STYPEMAX defined in line 417; used 1 times

- in line 486

TEXT defined in line 62; used 1 times

- in line 309

WD defined in line 63; used 1 times

- in line 603

X_NETDATA defined in line 80; used 2 times

- in line 181-182(2)

X_NPROC defined in line 90; used 1 times

- in line 189

X_PROC defined in line 86; used 2 times

- in line 192-194(2)

X_USRPT defined in line 92; used 1 times

- in line 187

X_USRPTMA defined in line 88; used 1 times

- in line 186

i_dev defined in line 51; used 3 times

- in line 328, 361-362(2)

i_mode defined in line 53; used 2 times

- in line 363-367(2)

i_number defined in line 52; used 2 times

- in line 329, 362

i_size defined in line 54; used 1 times

- in line 363

inode defined in line 49; used 12 times

- in line 317, 324-329(5), 361-367(6)

x_iptr defined in line 50; used 1 times

- in line 309

Last modified: 1994-01-11 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2867 |