Annotation of 43BSDReno/usr.bin/fstat/fstat.c, revision 1.1

1.1     ! root        1: /*-
        !             2:  * Copyright (c) 1988 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted provided
        !             6:  * that: (1) source distributions retain this entire copyright notice and
        !             7:  * comment, and (2) distributions including binaries display the following
        !             8:  * acknowledgement:  ``This product includes software developed by the
        !             9:  * University of California, Berkeley and its contributors'' in the
        !            10:  * documentation or other materials provided with the distribution and in
        !            11:  * all advertising materials mentioning features or use of this software.
        !            12:  * Neither the name of the University nor the names of its contributors may
        !            13:  * be used to endorse or promote products derived from this software without
        !            14:  * specific prior written permission.
        !            15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            18:  */
        !            19: 
        !            20: #ifndef lint
        !            21: char copyright[] =
        !            22: "@(#) Copyright (c) 1988 The Regents of the University of California.\n\
        !            23:  All rights reserved.\n";
        !            24: #endif /* not lint */
        !            25: 
        !            26: #ifndef lint
        !            27: static char sccsid[] = "@(#)fstat.c    5.25 (Berkeley) 6/29/90";
        !            28: #endif /* not lint */
        !            29: 
        !            30: /*
        !            31:  *  fstat 
        !            32:  */
        !            33: #include <machine/pte.h>
        !            34: 
        !            35: #include <sys/param.h>
        !            36: #include <sys/user.h>
        !            37: #include <sys/proc.h>
        !            38: #include <sys/text.h>
        !            39: #include <sys/stat.h>
        !            40: #include <sys/time.h>
        !            41: #include <sys/vnode.h>
        !            42: #include <sys/socket.h>
        !            43: #include <sys/socketvar.h>
        !            44: #include <sys/domain.h>
        !            45: #include <sys/protosw.h>
        !            46: #include <sys/unpcb.h>
        !            47: #include <sys/vmmac.h>
        !            48: #define        KERNEL
        !            49: #define NFS
        !            50: #include <sys/file.h>
        !            51: #include <sys/mount.h>
        !            52: #include <ufs/quota.h>
        !            53: #include <ufs/inode.h>
        !            54: #include <nfs/nfsv2.h>
        !            55: #include <nfs/nfs.h>
        !            56: #include <nfs/nfsnode.h>
        !            57: #undef KERNEL
        !            58: 
        !            59: #include <net/route.h>
        !            60: #include <netinet/in.h>
        !            61: #include <netinet/in_systm.h>
        !            62: #include <netinet/ip.h>
        !            63: #include <netinet/in_pcb.h>
        !            64: 
        !            65: #include <kvm.h>
        !            66: #include <paths.h>
        !            67: #include <ctype.h>
        !            68: #include <nlist.h>
        !            69: #include <pwd.h>
        !            70: #include <string.h>
        !            71: #include <stdio.h>
        !            72: 
        !            73: #define        TEXT    -1
        !            74: #define        CDIR    -2
        !            75: #define        RDIR    -3
        !            76: #define        TRACE   -4
        !            77: 
        !            78: typedef struct devs {
        !            79:        struct  devs *next;
        !            80:        long    fsid;
        !            81:        ino_t   ino;
        !            82:        char    *name;
        !            83: } DEVS;
        !            84: DEVS *devs;
        !            85: 
        !            86: struct  filestat {
        !            87:        long    fsid;
        !            88:        long    fileid;
        !            89:        mode_t  mode;
        !            90:        u_long  size;
        !            91:        dev_t   rdev;
        !            92: };
        !            93: 
        !            94: #ifdef notdef
        !            95: struct nlist nl[] = {
        !            96:        { "" },
        !            97: };
        !            98: #endif
        !            99: 
        !           100: int    fsflg,  /* show files on same filesystem as file(s) argument */
        !           101:        pflg,   /* show files open by a particular pid */
        !           102:        uflg;   /* show files open by a particular (effective) user */
        !           103: int    checkfile; /* true if restricting to particular files or filesystems */
        !           104: int    nflg;   /* (numerical) display f.s. and rdev as dev_t */
        !           105: int    vflg;   /* display errors in locating kernel data objects etc... */
        !           106: 
        !           107: #define dprintf        if (vflg) fprintf
        !           108: 
        !           109: extern int errno;
        !           110: off_t lseek();
        !           111: 
        !           112: main(argc, argv)
        !           113:        int argc;
        !           114:        char **argv;
        !           115: {
        !           116:        register struct passwd *passwd;
        !           117:        int what = KINFO_PROC_ALL, arg = 0;
        !           118:        struct passwd *getpwnam(), *getpwuid();
        !           119:        struct proc *p;
        !           120:        extern char *optarg;
        !           121:        extern int optind;
        !           122:        int ch;
        !           123:        char *malloc();
        !           124: 
        !           125: 
        !           126:        while ((ch = getopt(argc, argv, "p:u:fnv")) != EOF)
        !           127:                switch((char)ch) {
        !           128:                case 'p':
        !           129:                        if (pflg++)
        !           130:                                usage();
        !           131:                        if (!isdigit(*optarg)) {
        !           132:                                fputs("fstat: -p option requires a process id.\n", stderr);
        !           133:                                usage();
        !           134:                        }
        !           135:                        what = KINFO_PROC_PID;
        !           136:                        arg = atoi(optarg);
        !           137:                        break;
        !           138:                case 'u':
        !           139:                        if (uflg++)
        !           140:                                usage();
        !           141:                        if (!(passwd = getpwnam(optarg))) {
        !           142:                                fprintf(stderr, "%s: unknown uid\n",
        !           143:                                    optarg);
        !           144:                                exit(1);
        !           145:                        }
        !           146:                        what = KINFO_PROC_UID;
        !           147:                        arg = passwd->pw_uid;
        !           148:                        break;
        !           149:                case 'f':
        !           150:                        fsflg++;
        !           151:                        break;
        !           152:                case 'n':
        !           153:                        nflg++;
        !           154:                        break;
        !           155:                case 'v':
        !           156:                        vflg++;
        !           157:                        break;
        !           158:                case '?':
        !           159:                default:
        !           160:                        usage();
        !           161:                }
        !           162: 
        !           163:        if (*(argv += optind)) {
        !           164:                for (; *argv; ++argv) {
        !           165:                        if (getfname(*argv))
        !           166:                                checkfile = 1;
        !           167:                }
        !           168:                if (!checkfile) /* file(s) specified, but none accessable */
        !           169:                        exit(1);
        !           170:        }
        !           171:        if (fsflg && !checkfile) {      
        !           172:                /* -f with no files means use wd */
        !           173:                if (getfname(".") == 0)
        !           174:                        exit(1);
        !           175:                checkfile = 1;
        !           176:        }
        !           177: 
        !           178:        /* modify the following to make work on dead kernels */
        !           179:        if (kvm_openfiles(NULL, NULL, NULL) == -1) {
        !           180:                fprintf(stderr, "fstat: %s\n", kvm_geterr());
        !           181:                exit(1);
        !           182:        }
        !           183: #ifdef notdef
        !           184:        if (kvm_nlist(nl) != 0) {
        !           185:                fprintf(stderr, "fstat: no namelist: %s\n", kvm_geterr());
        !           186:                exit(1);
        !           187:        }
        !           188: #endif
        !           189:        if (kvm_getprocs(what, arg) == -1) {
        !           190:                fprintf(stderr, "fstat: %s\n", kvm_geterr());
        !           191:                exit(1);
        !           192:        }
        !           193:        if (nflg)
        !           194: fputs("USER     CMD        PID   FD  DEV    INUM       MODE SZ|DV", stdout);
        !           195:        else
        !           196: fputs("USER     CMD        PID   FD MOUNT      INUM MODE         SZ|DV", stdout);
        !           197:        if (checkfile && fsflg == 0)
        !           198:                fputs(" NAME\n", stdout);       
        !           199:        else
        !           200:                putchar('\n');
        !           201: 
        !           202:        while ((p = kvm_nextproc()) != NULL) {
        !           203:                if (p->p_stat == SZOMB)
        !           204:                        continue;
        !           205:                dofiles(p);
        !           206:        }
        !           207:        exit(0);
        !           208: }
        !           209: 
        !           210: char   *Uname, *Comm;
        !           211: int    Pid;
        !           212: 
        !           213: #define PREFIX(i) printf("%-8.8s %-8.8s %5d", Uname, Comm, Pid); \
        !           214:        switch(i) { \
        !           215:        case TEXT: \
        !           216:                fputs(" text", stdout); \
        !           217:                break; \
        !           218:        case CDIR: \
        !           219:                fputs("   wd", stdout); \
        !           220:                break; \
        !           221:        case RDIR: \
        !           222:                fputs(" root", stdout); \
        !           223:                break; \
        !           224:        case TRACE: \
        !           225:                fputs("   tr", stdout); \
        !           226:                break; \
        !           227:        default: \
        !           228:                printf(" %4d", i); \
        !           229:                break; \
        !           230:        }
        !           231: 
        !           232: /*
        !           233:  * print open files attributed to this process
        !           234:  */
        !           235: dofiles(p)
        !           236:        struct proc *p;
        !           237: {
        !           238:        int i;
        !           239:        struct file file;
        !           240:        struct user *up = kvm_getu(p);
        !           241:        struct vnode *xvptr;
        !           242:        extern char *user_from_uid();
        !           243: 
        !           244:        Uname = user_from_uid(p->p_uid, 0);
        !           245:        Pid = p->p_pid;
        !           246:        Comm = p->p_comm;
        !           247: 
        !           248:        if (up == NULL) {
        !           249:                dprintf(stderr, "can't read u for pid %d\n", Pid);
        !           250:                return;
        !           251:        }
        !           252:        /*
        !           253:         * root directory vnode, if one
        !           254:         */
        !           255:        if (up->u_rdir)
        !           256:                vtrans(up->u_rdir, RDIR);
        !           257:        /*
        !           258:         * text vnode
        !           259:         */
        !           260:        if (p->p_textp && 
        !           261:            kvm_read(&(p->p_textp->x_vptr), &xvptr,
        !           262:            sizeof (struct vnode *)) == sizeof (struct vnode *) &&
        !           263:            xvptr != NULL)
        !           264:                vtrans(xvptr, TEXT);
        !           265:        /*
        !           266:         * current working directory vnode
        !           267:         */
        !           268:        vtrans(up->u_cdir, CDIR);
        !           269:        /*
        !           270:         * ktrace vnode, if one
        !           271:         */
        !           272:        if (p->p_tracep)
        !           273:                vtrans(p->p_tracep, TRACE);
        !           274:        /*
        !           275:         * open files
        !           276:         */
        !           277:        for (i = 0; i <= up->u_lastfile; i++) {
        !           278:                if (up->u_ofile[i] == 0)
        !           279:                        continue;
        !           280:                if (kvm_read(up->u_ofile[i], &file, sizeof (struct file)) !=
        !           281:                    sizeof (struct file)) {
        !           282:                        dprintf(stderr, "can't read file %d for pid %d\n",
        !           283:                                i, Pid);
        !           284:                        continue;
        !           285:                }
        !           286:                if (file.f_type == DTYPE_VNODE)
        !           287:                        vtrans((struct vnode *)file.f_data, i);
        !           288:                else if (file.f_type == DTYPE_SOCKET && checkfile == 0)
        !           289:                        socktrans((struct socket *)file.f_data, i);
        !           290:                else {
        !           291:                        dprintf(stderr, 
        !           292:                                "unknown file type %d for file %d of pid %d\n",
        !           293:                                file.f_type, i, Pid);
        !           294:                }
        !           295:        }
        !           296: }
        !           297: 
        !           298: vtrans(vp, i)
        !           299:        struct vnode *vp;
        !           300: {
        !           301:        struct vnode vn;
        !           302:        struct filestat fst;
        !           303:        char *filename = NULL;
        !           304:        char *badtype = NULL;
        !           305:        char *getmnton();
        !           306:        extern char *devname();
        !           307:        char mode[15];
        !           308: 
        !           309:        if (kvm_read((off_t)vp, &vn, sizeof (struct vnode)) != 
        !           310:            sizeof (struct vnode)) {
        !           311:                dprintf(stderr, "can't read vnode at %x for pid %d\n",
        !           312:                        vp, Pid);
        !           313:                return;
        !           314:        }
        !           315:        if (vn.v_type == VNON || vn.v_tag == VT_NON)
        !           316:                badtype = "none";
        !           317:        else if (vn.v_type == VBAD)
        !           318:                badtype = "bad";
        !           319:        else
        !           320:                switch (vn.v_tag) {
        !           321:                case VT_UFS:
        !           322:                        ufs_filestat(&vn, &fst);
        !           323:                        break;
        !           324:                case VT_MFS:
        !           325:                        ufs_filestat(&vn, &fst);
        !           326:                        break;
        !           327:                case VT_NFS:
        !           328:                        nfs_filestat(&vn, &fst);
        !           329:                        break;
        !           330:                default: {
        !           331:                        static char unknown[10];
        !           332:                        sprintf(badtype = unknown, "?(%x)", vn.v_tag);
        !           333:                        break;;
        !           334:                }
        !           335:        }
        !           336:        if (checkfile) {
        !           337:                int fsmatch = 0;
        !           338:                register DEVS *d;
        !           339: 
        !           340:                if (badtype)
        !           341:                        return;
        !           342:                for (d = devs; d != NULL; d = d->next)
        !           343:                        if (d->fsid == fst.fsid) {
        !           344:                                fsmatch = 1;
        !           345:                                if (d->ino == fst.fileid) {
        !           346:                                        filename = d->name;
        !           347:                                        break;
        !           348:                                }
        !           349:                        }
        !           350:                if (fsmatch == 0 || (filename == NULL && fsflg == 0))
        !           351:                        return;
        !           352:        }
        !           353:        PREFIX(i);
        !           354:        if (badtype) {
        !           355:                (void)printf(" -         -  %10s    -\n", badtype);
        !           356:                return;
        !           357:        }
        !           358:        if (nflg)
        !           359:                (void)printf(" %2d,%-2d", major(fst.fsid), minor(fst.fsid));
        !           360:        else
        !           361:                (void)printf(" %-8s", getmnton(vn.v_mount));
        !           362:        if (nflg)
        !           363:                (void)sprintf(mode, "%o", fst.mode);
        !           364:        else
        !           365:                strmode(fst.mode, mode);
        !           366:        (void)printf(" %6d %10s", fst.fileid, mode);
        !           367:        switch (vn.v_type) {
        !           368:        case VBLK:
        !           369:        case VCHR: {
        !           370:                char *name;
        !           371: 
        !           372:                if (nflg || ((name = devname(fst.rdev, vn.v_type == VCHR ? 
        !           373:                    S_IFCHR : S_IFBLK)) == NULL))
        !           374:                        printf("  %2d,%-2d", major(fst.rdev), minor(fst.rdev));
        !           375:                else
        !           376:                        printf(" %6s", name);
        !           377:                break;
        !           378:        }
        !           379:        default:
        !           380:                printf(" %6d", fst.size);
        !           381:        }
        !           382:        if (filename && !fsflg)
        !           383:                printf(" %s", filename);
        !           384:                
        !           385:        putchar('\n');
        !           386: }
        !           387: 
        !           388: ufs_filestat(vp, fsp)
        !           389:        struct vnode *vp;
        !           390:        struct filestat *fsp;
        !           391: {
        !           392:        struct inode *ip = VTOI(vp);
        !           393: 
        !           394:        fsp->fsid = ip->i_dev & 0xffff;
        !           395:        fsp->fileid = (long)ip->i_number;
        !           396:        fsp->mode = (mode_t)ip->i_mode;
        !           397:        fsp->size = (u_long)ip->i_size;
        !           398:        fsp->rdev = ip->i_rdev;
        !           399: }
        !           400: 
        !           401: nfs_filestat(vp, fsp)
        !           402:        struct vnode *vp;
        !           403:        struct filestat *fsp;
        !           404: {
        !           405:        register struct nfsnode *np = VTONFS(vp);
        !           406:        register mode_t mode;
        !           407: 
        !           408:        fsp->fsid = np->n_vattr.va_fsid;
        !           409:        fsp->fileid = np->n_vattr.va_fileid;
        !           410:        fsp->size = np->n_size;
        !           411:        fsp->rdev = np->n_vattr.va_rdev;
        !           412:        mode = (mode_t)np->n_vattr.va_mode;
        !           413:        switch (vp->v_type) {
        !           414:        case VREG:
        !           415:                mode |= S_IFREG;
        !           416:                break;
        !           417:        case VDIR:
        !           418:                mode |= S_IFDIR;
        !           419:                break;
        !           420:        case VBLK:
        !           421:                mode |= S_IFBLK;
        !           422:                break;
        !           423:        case VCHR:
        !           424:                mode |= S_IFCHR;
        !           425:                break;
        !           426:        case VLNK:
        !           427:                mode |= S_IFLNK;
        !           428:                break;
        !           429:        case VSOCK:
        !           430:                mode |= S_IFSOCK;
        !           431:                break;
        !           432:        case VFIFO:
        !           433:                mode |= S_IFIFO;
        !           434:                break;
        !           435:        };
        !           436:        fsp->mode = mode;
        !           437: }
        !           438: 
        !           439: 
        !           440: char *
        !           441: getmnton(m)
        !           442:        struct mount *m;
        !           443: {
        !           444:        static struct mount mount;
        !           445:        static struct mtab {
        !           446:                struct mtab *next;
        !           447:                struct mount *m;
        !           448:                char mntonname[MNAMELEN];
        !           449:        } *mhead = NULL;
        !           450:        register struct mtab *mt;
        !           451: 
        !           452:        for (mt = mhead; mt != NULL; mt = mt->next)
        !           453:                if (m == mt->m)
        !           454:                        return (mt->mntonname);
        !           455:        if (kvm_read((off_t)m, &mount, sizeof(struct mount)) != 
        !           456:            sizeof(struct mount)) {
        !           457:                fprintf(stderr, "can't read mount table at %x\n", m);
        !           458:                return (NULL);
        !           459:        }
        !           460:        if ((mt = (struct mtab *)malloc(sizeof (struct mtab))) == NULL) {
        !           461:                fprintf(stderr, "out of memory\n");
        !           462:                exit(1);
        !           463:        }
        !           464:        mt->m = m;
        !           465:        bcopy(&mount.mnt_stat.f_mntonname[0], &mt->mntonname[0], MNAMELEN);
        !           466:        mt->next = mhead;
        !           467:        mhead = mt;
        !           468:        return (mt->mntonname);
        !           469: }
        !           470: 
        !           471: socktrans(sock, i)
        !           472:        struct socket *sock;
        !           473: {
        !           474:        static char *stypename[] = {
        !           475:                "unused",       /* 0 */
        !           476:                "stream",       /* 1 */
        !           477:                "dgram",        /* 2 */
        !           478:                "raw",          /* 3 */
        !           479:                "rdm",          /* 4 */
        !           480:                "seqpak"        /* 5 */
        !           481:        };
        !           482: #define        STYPEMAX 5
        !           483:        struct socket   so;
        !           484:        struct protosw  proto;
        !           485:        struct domain   dom;
        !           486:        struct inpcb    inpcb;
        !           487:        struct unpcb    unpcb;
        !           488:        int len;
        !           489:        char dname[32], *strcpy();
        !           490: 
        !           491:        PREFIX(i);
        !           492: 
        !           493:        /* fill in socket */
        !           494:        if (kvm_read((off_t)sock, (char *)&so, sizeof(struct socket))
        !           495:            != sizeof(struct socket)) {
        !           496:                dprintf(stderr, "can't read sock at %x\n", sock);
        !           497:                goto bad;
        !           498:        }
        !           499: 
        !           500:        /* fill in protosw entry */
        !           501:        if (kvm_read((off_t)so.so_proto, (char *)&proto, sizeof(struct protosw))
        !           502:            != sizeof(struct protosw)) {
        !           503:                dprintf(stderr, "can't read protosw at %x", so.so_proto);
        !           504:                goto bad;
        !           505:        }
        !           506: 
        !           507:        /* fill in domain */
        !           508:        if (kvm_read((off_t)proto.pr_domain, (char *)&dom, sizeof(struct domain))
        !           509:            != sizeof(struct domain)) {
        !           510:                dprintf(stderr, "can't read domain at %x\n", proto.pr_domain);
        !           511:                goto bad;
        !           512:        }
        !           513: 
        !           514:        /*
        !           515:         * grab domain name
        !           516:         * kludge "internet" --> "inet" for brevity
        !           517:         */
        !           518:        if (dom.dom_family == AF_INET)
        !           519:                strcpy(dname, "inet");
        !           520:        else {
        !           521:                if ((len = kvm_read((off_t)dom.dom_name, dname, sizeof(dname) - 1)) < 0) {
        !           522:                        dprintf(stderr, "can't read domain name at %x\n",
        !           523:                                dom.dom_name);
        !           524:                        dname[0] = '\0';
        !           525:                }
        !           526:                else
        !           527:                        dname[len] = '\0';
        !           528:        }
        !           529: 
        !           530:        if ((u_short)so.so_type > STYPEMAX)
        !           531:                printf("* %s ?%d", dname, so.so_type);
        !           532:        else
        !           533:                printf("* %s %s", dname, stypename[so.so_type]);
        !           534: 
        !           535:        /* 
        !           536:         * protocol specific formatting
        !           537:         *
        !           538:         * Try to find interesting things to print.  For tcp, the interesting
        !           539:         * thing is the address of the tcpcb, for udp and others, just the
        !           540:         * inpcb (socket pcb).  For unix domain, its the address of the socket
        !           541:         * pcb and the address of the connected pcb (if connected).  Otherwise
        !           542:         * just print the protocol number and address of the socket itself.
        !           543:         * The idea is not to duplicate netstat, but to make available enough
        !           544:         * information for further analysis.
        !           545:         */
        !           546:        switch(dom.dom_family) {
        !           547:        case AF_INET:
        !           548:                getinetproto(proto.pr_protocol);
        !           549:                if (proto.pr_protocol == IPPROTO_TCP ) {
        !           550:                        if (so.so_pcb) {
        !           551:                                if (kvm_read((off_t)so.so_pcb, (char *)&inpcb, sizeof(struct inpcb))
        !           552:                                    != sizeof(struct inpcb)){
        !           553:                                        dprintf(stderr, 
        !           554:                                             "can't read inpcb at %x\n", so.so_pcb);
        !           555:                                        goto bad;
        !           556:                                }
        !           557:                                printf(" %x", (int)inpcb.inp_ppcb);
        !           558:                        }
        !           559:                }
        !           560:                else if (so.so_pcb)
        !           561:                        printf(" %x", (int)so.so_pcb);
        !           562:                break;
        !           563:        case AF_UNIX:
        !           564:                /* print address of pcb and connected pcb */
        !           565:                if (so.so_pcb) {
        !           566:                        printf(" %x", (int)so.so_pcb);
        !           567:                        if (kvm_read((off_t)so.so_pcb, (char *)&unpcb, sizeof(struct unpcb))
        !           568:                            != sizeof(struct unpcb)){
        !           569:                                dprintf(stderr, "can't read unpcb at %x\n",
        !           570:                                        so.so_pcb);
        !           571:                                goto bad;
        !           572:                        }
        !           573:                        if (unpcb.unp_conn) {
        !           574:                                char shoconn[4], *cp;
        !           575: 
        !           576:                                cp = shoconn;
        !           577:                                if (!(so.so_state & SS_CANTRCVMORE))
        !           578:                                        *cp++ = '<';
        !           579:                                *cp++ = '-';
        !           580:                                if (!(so.so_state & SS_CANTSENDMORE))
        !           581:                                        *cp++ = '>';
        !           582:                                *cp = '\0';
        !           583:                                printf(" %s %x", shoconn,
        !           584:                                    (int)unpcb.unp_conn);
        !           585:                        }
        !           586:                }
        !           587:                break;
        !           588:        default:
        !           589:                /* print protocol number and socket address */
        !           590:                printf(" %d %x", proto.pr_protocol, (int)sock);
        !           591:        }
        !           592:        printf("\n");
        !           593:        return;
        !           594: bad:
        !           595:        printf("* error\n");
        !           596: }
        !           597: 
        !           598: /*
        !           599:  * getinetproto --
        !           600:  *     print name of protocol number
        !           601:  */
        !           602: getinetproto(number)
        !           603:        int number;
        !           604: {
        !           605:        char *cp;
        !           606: 
        !           607:        switch(number) {
        !           608:        case IPPROTO_IP:
        !           609:                cp = "ip"; break;
        !           610:        case IPPROTO_ICMP:
        !           611:                cp ="icmp"; break;
        !           612:        case IPPROTO_GGP:
        !           613:                cp ="ggp"; break;
        !           614:        case IPPROTO_TCP:
        !           615:                cp ="tcp"; break;
        !           616:        case IPPROTO_EGP:
        !           617:                cp ="egp"; break;
        !           618:        case IPPROTO_PUP:
        !           619:                cp ="pup"; break;
        !           620:        case IPPROTO_UDP:
        !           621:                cp ="udp"; break;
        !           622:        case IPPROTO_IDP:
        !           623:                cp ="idp"; break;
        !           624:        case IPPROTO_RAW:
        !           625:                cp ="raw"; break;
        !           626:        default:
        !           627:                printf(" %d", number);
        !           628:                return;
        !           629:        }
        !           630:        printf(" %s", cp);
        !           631: }
        !           632: 
        !           633: getfname(filename)
        !           634:        char *filename;
        !           635: {
        !           636:        struct stat statbuf;
        !           637:        DEVS *cur;
        !           638:        char *malloc();
        !           639: 
        !           640:        if (stat(filename, &statbuf)) {
        !           641:                fprintf(stderr, "fstat: %s: %s\n", strerror(errno),
        !           642:                    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:        cur->ino = statbuf.st_ino;
        !           653:        cur->fsid = statbuf.st_dev & 0xffff;
        !           654:        cur->name = filename;
        !           655:        return(1);
        !           656: }
        !           657: 
        !           658: usage()
        !           659: {
        !           660:        (void)fprintf(stderr,
        !           661:            "usage: fstat [-u user] [-p pid] [filename ...]\n");
        !           662:        exit(1);
        !           663: }

unix.superglobalmegacorp.com

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