Annotation of researchv8dc/cmd/fstat.c, revision 1.1.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.