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
dotext defined in line 294; used 1 times
getfname defined in line 633; used 1 times
getinetproto defined in line 565; used 1 times
getu defined in line 270; used 1 times
itrans defined in line 312; used 3 times
itype defined in line 382; used 2 times
lgetw defined in line 699; used 5 times
main defined in line 122; never used
openfiles defined in line 665; used 1 times
read defined in line 455; used 20 times
readf defined in line 597; used 1 times
rerr1 defined in line 682; used 3 times
rerr2 defined in line 690; used 8 times
socktrans defined in line 405; used 1 times
usage defined in line 715; used 4 times

Defined variables

Usrptma defined in line 99; used 2 times
copyright defined in line 14; never used
devs defined in line 71; used 3 times
dname defined in line 424; used 9 times
dom defined in line 420; used 7 times
fflg defined in line 112; used 5 times
inpcb defined in line 421; used 3 times
kmem defined in line 113; used 26 times
len defined in line 423; used 3 times
mem defined in line 113; used 19 times
mproc defined in line 97; used 26 times
netdata defined in line 116; used 9 times
nl defined in line 84; used 9 times
nproc defined in line 113; used 3 times
proto defined in line 419; used 8 times
sccsid defined in line 18; never used
so defined in line 418; used 23 times
swap defined in line 113; used 7 times
uname defined in line 114; used 3 times
unpcb defined in line 422; used 4 times
usrpt defined in line 99; used 1 times
vflg defined in line 112; used 3 times

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

Defined macros

KERNEL defined in line 36; used 1 times
  • in line 38
N_KMEM defined in line 57; used 6 times
N_MEM defined in line 58; used 4 times
N_SWAP defined in line 59; used 5 times
N_UNIX defined in line 60; used 2 times
STYPEMAX defined in line 417; used 1 times
TEXT defined in line 62; used 1 times
WD defined in line 63; used 1 times
X_NETDATA defined in line 80; used 2 times
X_NPROC defined in line 90; used 1 times
X_PROC defined in line 86; used 2 times
X_USRPT defined in line 92; used 1 times
X_USRPTMA defined in line 88; used 1 times
i_dev defined in line 51; used 3 times
i_mode defined in line 53; used 2 times
i_number defined in line 52; used 2 times
i_size defined in line 54; used 1 times
inode defined in line 49; used 12 times
x_iptr defined in line 50; used 1 times
Last modified: 1994-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5871
Valid CSS Valid XHTML 1.0 Strict