Annotation of 43BSDTahoe/etc/fstat.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.