Annotation of researchv8dc/cmd/fstat.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * ps; VAX 4BSD version
        !             3:  */
        !             4: 
        !             5: #include <stdio.h>
        !             6: #include <ctype.h>
        !             7: #include <nlist.h>
        !             8: #include <pwd.h>
        !             9: #include <sys/param.h>
        !            10: #include <sys/tty.h>
        !            11: #include <sys/dir.h>
        !            12: #include <sys/user.h>
        !            13: #include <sys/proc.h>
        !            14: #include <sys/pte.h>
        !            15: #include <sys/vm.h>
        !            16: #include <sys/text.h>
        !            17: #include <sys/stat.h>
        !            18: #include <math.h>
        !            19: #include <sys/vlimit.h>
        !            20: #include <sys/inode.h>
        !            21: #include <sys/file.h>
        !            22: 
        !            23: #define vprintf        if (vflg) printf
        !            24: #define WD     -1
        !            25: #define TEXT   -2
        !            26: 
        !            27: int    pcbpf, nswap, kmem, mem, swap, uid, pid;
        !            28: int    uflg, fflg, inum, Mdev, mdev, special, vflg, nproc, pflg;
        !            29: char   *uname;
        !            30: 
        !            31: struct nlist nl[] = {
        !            32:        { "_proc" },
        !            33: #define        X_PROC          0
        !            34:        { "_Usrptmap" },
        !            35: #define        X_USRPTMA       1
        !            36:        { "_usrpt" },
        !            37: #define        X_USRPT         2
        !            38:        { "_nswap" },
        !            39: #define        X_NSWAP         3
        !            40:        { "_nproc" },
        !            41: #define        X_NPROC         4
        !            42:        { 0 },
        !            43: };
        !            44: 
        !            45: struct proc proc[8], *mproc;           /* 8 = a few, for less syscalls */
        !            46: struct pte *Usrptma, *usrpt;
        !            47: 
        !            48: int    paduser1;               /* avoid hardware mem clobbering botch */
        !            49: union {
        !            50:        struct  user user;
        !            51:        char    upages[UPAGES][NBPG];
        !            52: } user;
        !            53: int    paduser2;               /* avoid hardware mem clobbering botch */
        !            54: #define u      user.user
        !            55: 
        !            56: char   *kmemf, *memf, *swapf, *nlistf;
        !            57: 
        !            58: extern int     errno;
        !            59: 
        !            60: main(argc, argv)
        !            61: char **argv;
        !            62: {
        !            63:        register int i, j;
        !            64:        off_t procp;
        !            65:        dev_t   dev;
        !            66: 
        !            67:        argv++;
        !            68:        while (--argc > 0) {
        !            69:                if (strcmp(*argv, "-v") == 0) {
        !            70:                        vflg++;
        !            71:                        argv++;
        !            72:                        continue;
        !            73:                } 
        !            74:                if (strcmp(*argv, "-u") == 0) {
        !            75:                        if (uflg++)
        !            76:                                usage();
        !            77:                        if ((uid = getuname(*(++argv))) < 0) {
        !            78:                                fprintf(stderr, "%s: unknown user\n", *argv);
        !            79:                                exit(1);
        !            80:                        }
        !            81:                        --argc;
        !            82:                        argv++;
        !            83:                        continue;
        !            84:                } 
        !            85:                if (strcmp(*argv, "-f") == 0) {
        !            86:                        if (fflg++)
        !            87:                                usage();
        !            88:                        if ((dev = getfname(*(++argv))) < 0) {
        !            89:                                perror(*argv);
        !            90:                                exit(1);
        !            91:                        }
        !            92:                        --argc;
        !            93:                        argv++;
        !            94:                        continue;
        !            95:                }
        !            96: 
        !            97:                if (strcmp(*argv, "-p") == 0) {
        !            98:                        if (pflg++ || ((pid = Atoi(*(++argv))) <= 0)) {
        !            99:                                usage();
        !           100:                                perror(*argv);
        !           101:                                exit(1);
        !           102:                        }
        !           103:                        --argc;
        !           104:                        argv++;
        !           105:                        continue;
        !           106:                }
        !           107: 
        !           108:                /* admit missing -u, -f, -p */
        !           109:                /* it's an expert system! */
        !           110:                if ((pid = Atoi(*argv)) > 0) {
        !           111:                        if (pflg++)
        !           112:                                usage();
        !           113:                        continue;
        !           114:                }
        !           115:                if (fflg && uflg)
        !           116:                        usage();
        !           117:                if (uflg) {
        !           118:                        /* it must be a file */
        !           119:                        fflg++;
        !           120:                        if ((dev = getfname(*argv)) < 0) {
        !           121:                                perror(*argv);
        !           122:                                exit(1);
        !           123:                        }
        !           124:                        argv++;
        !           125:                        continue;
        !           126:                }
        !           127:                if (fflg) {
        !           128:                        /* it must be a user */
        !           129:                        uflg++;
        !           130:                        if ((uid = getuname(*argv)) < 0) {
        !           131:                                fprintf(stderr,
        !           132:                                        "%s: unknown user\n", *argv);
        !           133:                                exit(1);
        !           134:                        }
        !           135:                        argv++;
        !           136:                        continue;
        !           137:                }
        !           138:                /* !uflg && !fflg -- which is it? */
        !           139:                if ((dev = getfname(*argv)) >= 0)
        !           140:                        fflg++;         /* could be a file */
        !           141:                if ((uid = getuname(*argv)) >= 0)
        !           142:                        uflg++;         /* could be a user */
        !           143:                if ((!uflg ^ !fflg) == 0)
        !           144:                        usage();        /* could be either/neither */
        !           145:                argv++;
        !           146:                continue;
        !           147:        }
        !           148: 
        !           149:        if (fflg) {
        !           150:                Mdev = major(dev);
        !           151:                mdev = minor(dev);
        !           152:        }
        !           153: 
        !           154:        if (chdir("/dev") < 0) {
        !           155:                perror("/dev");
        !           156:                exit(1);
        !           157:        }
        !           158: 
        !           159:        printf("user\t\t  pid\t  fd   major   minor\tinode\n");
        !           160:        openfiles();
        !           161:        getkvars();
        !           162:        procp = getw((off_t) nl[X_PROC].n_value);
        !           163:        nproc = getw((off_t) nl[X_NPROC].n_value);
        !           164:        for (i=0; i<nproc; i += 8) {
        !           165:                lseek(kmem, (long) procp, 0);
        !           166:                j = nproc - i;
        !           167:                if (j > 8)
        !           168:                        j = 8;
        !           169:                j *= sizeof (struct proc);
        !           170:                if (read(kmem, (char *) proc, j) != j)
        !           171:                        cantread("proc table", kmemf);
        !           172:                procp += j;
        !           173:                for (j = j / sizeof (struct proc) - 1; j >= 0; j--) {
        !           174:                        mproc = &proc[j];
        !           175:                        if (mproc->p_stat == 0)
        !           176:                                continue;
        !           177:                        doproc();
        !           178:                }
        !           179:        }
        !           180:        exit(0);
        !           181: }
        !           182: 
        !           183: long
        !           184: getw(loc)
        !           185:        off_t loc;
        !           186: {
        !           187:        long word;
        !           188: 
        !           189:        lseek(kmem, (long) loc, 0);
        !           190:        if (read(kmem, (char *) &word, sizeof (word)) != sizeof (word))
        !           191:                vprintf("error reading kmem at %x\n", loc);
        !           192:        return (word);
        !           193: }
        !           194: 
        !           195: openfiles()
        !           196: {
        !           197: 
        !           198:        kmemf = "kmem";
        !           199:        kmem = open(kmemf, 0);
        !           200:        if (kmem < 0) {
        !           201:                perror(kmemf);
        !           202:                exit(1);
        !           203:        }
        !           204:        memf = "mem";
        !           205:        mem = open(memf, 0);
        !           206:        if (mem < 0) {
        !           207:                perror(memf);
        !           208:                exit(1);
        !           209:        }
        !           210:        swapf = "drum";
        !           211:        swap = open(swapf, 0);
        !           212:        if (swap < 0) {
        !           213:                perror(swapf);
        !           214:                exit(1);
        !           215:        }
        !           216: }
        !           217: 
        !           218: getkvars()
        !           219: {
        !           220:        nlistf = "/unix";
        !           221:        nlist(nlistf, nl);
        !           222:        if (nl[0].n_type == 0) {
        !           223:                fprintf(stderr, "%s: No namelist\n", nlistf);
        !           224:                exit(1);
        !           225:        }
        !           226:        Usrptma = (struct pte *) nl[X_USRPTMA].n_value;
        !           227:        usrpt = (struct pte *) nl[X_USRPT].n_value;
        !           228:        lseek(kmem, (long) nl[X_NSWAP].n_value, 0);
        !           229:        if (read(kmem, (char *) &nswap, sizeof (nswap)) != sizeof (nswap)) {
        !           230:                cantread("nswap", kmemf);
        !           231:                exit(1);
        !           232:        }
        !           233: }
        !           234: 
        !           235: cantread(what, fromwhat)
        !           236:        char *what, *fromwhat;
        !           237: {
        !           238: 
        !           239:        vprintf("fstat: error reading %s from %s", what, fromwhat);
        !           240: }
        !           241: 
        !           242: doproc()
        !           243: {
        !           244:        struct passwd   *getpwuid();
        !           245: 
        !           246:        if (uflg && mproc->p_uid != uid)
        !           247:                return;
        !           248:        if (pflg && mproc->p_pid != pid)
        !           249:                return;
        !           250:        if (mproc->p_stat != SZOMB && getu() == 0)
        !           251:                return;
        !           252:        uname = getpwuid(u.u_uid)->pw_name;
        !           253:        dotext();
        !           254:        getf();
        !           255: }
        !           256: 
        !           257: getu()
        !           258: {
        !           259:        struct pte *pteaddr, apte;
        !           260:        int pad1;       /* avoid hardware botch */
        !           261:        struct pte arguutl[UPAGES+CLSIZE];
        !           262:        int pad2;       /* avoid hardware botch */
        !           263:        register int i;
        !           264:        int ncl, size, argaddr;
        !           265: 
        !           266:        size = sizeof (struct user);
        !           267:        if ((mproc->p_flag & SLOAD) == 0) {
        !           268:                lseek(swap, (long) ctob(mproc->p_swaddr), 0);
        !           269:                if (read(swap, (char *) &user.user, size) != size) {
        !           270:                        vprintf("fstat: cant read u for pid %d from %s\n",
        !           271:                            mproc->p_pid, swapf);
        !           272:                        return (0);
        !           273:                }
        !           274:                pcbpf = 0;
        !           275:                argaddr = 0;
        !           276:                return (1);
        !           277:        }
        !           278:        pteaddr = &Usrptma[btokmx(mproc->p_p0br) + mproc->p_szpt - 1];
        !           279:        lseek(kmem, (long) pteaddr, 0);
        !           280:        if (read(kmem, (char *) &apte, sizeof(apte)) != sizeof(apte)) {
        !           281:                vprintf("fstat: can't read indir pte to get u for pid %d from %s\n",
        !           282:                    mproc->p_pid, swapf);
        !           283:                return (0);
        !           284:        }
        !           285:        lseek(mem,
        !           286:            (long) ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE) * sizeof (struct pte), 0);
        !           287:        if (read(mem, (char *) arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
        !           288:                vprintf("fstat: can't read page table for u of pid %d from %s\n",
        !           289:                    mproc->p_pid, swapf);
        !           290:                return (0);
        !           291:        }
        !           292:        if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum)
        !           293:                argaddr = ctob(arguutl[0].pg_pfnum);
        !           294:        else
        !           295:                argaddr = 0;
        !           296:        pcbpf = arguutl[CLSIZE].pg_pfnum;
        !           297:        ncl = (size + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
        !           298:        while (--ncl >= 0) {
        !           299:                i = ncl * CLSIZE;
        !           300:                lseek(mem, (long) ctob(arguutl[CLSIZE+i].pg_pfnum), 0);
        !           301:                if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
        !           302:                        vprintf("fstat: can't read page %d of u of pid %d from %s\n",
        !           303:                            arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid, memf);
        !           304:                        return(0);
        !           305:                }
        !           306:        }
        !           307:        return (1);
        !           308: }
        !           309: 
        !           310: #define        NMAX    8
        !           311: #define        NUID    2048
        !           312: 
        !           313: dotext()
        !           314: {
        !           315:        struct text     text;
        !           316: 
        !           317:        lseek(kmem, (long) mproc->p_textp, 0);
        !           318:        if (read(kmem, (char *) &text, sizeof(text)) != sizeof(text)) {
        !           319:                cantread("text table", kmemf);
        !           320:                return;
        !           321:        }
        !           322:        if (text.x_flag == 0)
        !           323:                return;
        !           324:        itrans(text.x_iptr, TEXT);
        !           325: }
        !           326: 
        !           327: itrans(i, fno)
        !           328: struct inode   *i;
        !           329: {
        !           330:        struct inode    inode;
        !           331:        dev_t   idev;
        !           332: 
        !           333:        lseek(kmem, (long) i, 0);
        !           334:        if (read(kmem, (char *) &inode, sizeof(inode))
        !           335:                                        != sizeof(inode)) {
        !           336:                vprintf("error %d reading inode at %x from kmem\n", errno, i);
        !           337:                return;
        !           338:        }
        !           339:        if (special)
        !           340:                idev = inode.i_dev;
        !           341:        else
        !           342:                idev = inode.i_dev;
        !           343:        if (fflg && major(idev) != Mdev)
        !           344:                return; 
        !           345:        if (fflg && minor(idev) != mdev)
        !           346:                return; 
        !           347:        if (inum && inode.i_number != inum)
        !           348:                return;
        !           349:        printf("%-16s%5d\t", uname, mproc->p_pid);
        !           350:        if (fno == WD)
        !           351:                printf("  wd");
        !           352:        else if (fno == TEXT)
        !           353:                printf("text");
        !           354:        else
        !           355:                printf("%4d", fno);
        !           356:        printf("\t%2d\t%2d\t%5d\n", major(inode.i_dev), minor(inode.i_dev),
        !           357:                inode.i_number);
        !           358: }
        !           359: 
        !           360: getf()
        !           361: {
        !           362:        int     i;
        !           363:        struct file     file;
        !           364: 
        !           365:        itrans(u.u_cdir, WD);
        !           366:        for (i = 0; i < NOFILE; i++) {
        !           367:                if (u.u_ofile[i] == 0)
        !           368:                        continue;
        !           369:                lseek(kmem, (long) u.u_ofile[i], 0);
        !           370:                if (read(kmem, (char *) &file, sizeof(file)) != sizeof(file)) {
        !           371:                        cantread("file", kmemf);
        !           372:                        continue;
        !           373:                }
        !           374:                itrans(file.f_inode, i);
        !           375:        }
        !           376: }
        !           377: 
        !           378: usage()
        !           379: {
        !           380:        fputs("usage: fstat [-u user] [-f filename] [-p pid]\n", stderr);
        !           381:        exit(1);
        !           382: }
        !           383: 
        !           384: getuname(uname)
        !           385: char   *uname;
        !           386: {
        !           387:        struct passwd   *passwd, *getpwnam();
        !           388:        
        !           389:        if ((passwd = getpwnam(uname)) == NULL)
        !           390:                return(-1);
        !           391:        return(passwd->pw_uid);
        !           392: }
        !           393: 
        !           394: getfname(filename)
        !           395: char   *filename;
        !           396: {
        !           397:        struct  stat statbuf;
        !           398: 
        !           399:        if (stat(filename, &statbuf) != 0)
        !           400:                return(-1);
        !           401: 
        !           402:        /*
        !           403:         *      if file is block special, look for open files on it
        !           404:         */
        !           405:        if ((statbuf.st_mode & S_IFMT) != S_IFBLK) {
        !           406:                inum = statbuf.st_ino;
        !           407:                return(statbuf.st_dev);
        !           408:        } else {
        !           409:                special++;
        !           410:                inum = 0;
        !           411:                return(statbuf.st_rdev);
        !           412:        }
        !           413: }
        !           414: 
        !           415: Atoi(p)
        !           416: register char *p;
        !           417: {
        !           418:        register int n = 0;
        !           419: 
        !           420:        while(*p >= '0' && *p <= '9')
        !           421:                n = n*10 + *p++ - '0';
        !           422:        return(*p ? -n : n);
        !           423: }
        !           424: /* @(#)getpwent.c      4.1 (Berkeley) 12/21/80 */
        !           425: 
        !           426: static char PASSWD[]   = "/etc/passwd";
        !           427: static char EMPTY[] = "";
        !           428: static FILE *pwf = NULL;
        !           429: static char line[BUFSIZ+1];
        !           430: static struct passwd passwd;
        !           431: 
        !           432: setpwent()
        !           433: {
        !           434:        if( pwf == NULL )
        !           435:                pwf = fopen( PASSWD, "r" );
        !           436:        else
        !           437:                rewind( pwf );
        !           438: }
        !           439: 
        !           440: endpwent()
        !           441: {
        !           442:        if( pwf != NULL ){
        !           443:                fclose( pwf );
        !           444:                pwf = NULL;
        !           445:        }
        !           446: }
        !           447: 
        !           448: static char *
        !           449: pwskip(p)
        !           450: register char *p;
        !           451: {
        !           452:        while( *p && *p != ':' )
        !           453:                ++p;
        !           454:        if( *p ) *p++ = 0;
        !           455:        return(p);
        !           456: }
        !           457: 
        !           458: struct passwd *
        !           459: getpwent()
        !           460: {
        !           461:        register char *p;
        !           462: 
        !           463:        if (pwf == NULL) {
        !           464:                if( (pwf = fopen( PASSWD, "r" )) == NULL )
        !           465:                        return(0);
        !           466:        }
        !           467:        p = fgets(line, BUFSIZ, pwf);
        !           468:        if (p==NULL)
        !           469:                return(0);
        !           470:        passwd.pw_name = p;
        !           471:        p = pwskip(p);
        !           472:        passwd.pw_passwd = p;
        !           473:        p = pwskip(p);
        !           474:        passwd.pw_uid = atoi(p);
        !           475:        p = pwskip(p);
        !           476:        passwd.pw_gid = atoi(p);
        !           477:        passwd.pw_quota = 0;
        !           478:        passwd.pw_comment = EMPTY;
        !           479:        p = pwskip(p);
        !           480:        passwd.pw_gecos = p;
        !           481:        p = pwskip(p);
        !           482:        passwd.pw_dir = p;
        !           483:        p = pwskip(p);
        !           484:        passwd.pw_shell = p;
        !           485:        while(*p && *p != '\n') p++;
        !           486:        *p = '\0';
        !           487:        return(&passwd);
        !           488: }
        !           489: /* @(#)getpwuid.c      4.1 (Berkeley) 12/21/80 */
        !           490: 
        !           491: struct passwd *
        !           492: getpwuid(uid)
        !           493: register uid;
        !           494: {
        !           495:        register struct passwd *p;
        !           496:        struct passwd *getpwent();
        !           497: 
        !           498:        setpwent();
        !           499:        while( (p = getpwent()) && p->pw_uid != uid );
        !           500:        endpwent();
        !           501:        return(p);
        !           502: }

unix.superglobalmegacorp.com

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