Annotation of researchv8dc/cmd/finddev.c, revision 1.1.1.1

1.1       root        1: #include <sys/param.h>
                      2: #include <sys/dir.h>
                      3: #include <sys/file.h>
                      4: #include <sys/user.h>
                      5: #include <sys/inode.h>
                      6: #include <sys/proc.h>
                      7: #include <sys/pte.h>
                      8: #include <sys/text.h>
                      9: #include <sys/vm.h>
                     10: #include <stdio.h>
                     11: #include <ctype.h>
                     12: #include <nlist.h>
                     13: #include <pwd.h>
                     14: #include <sys/stat.h>
                     15: #include <ftw.h>
                     16: 
                     17: struct nlist nl[] = {
                     18:        { "_proc" },
                     19: #define        X_PROC          0
                     20:        { "_Usrptmap" },
                     21: #define        X_USRPTMA       1
                     22:        { "_usrpt" },
                     23: #define        X_USRPT         2
                     24:        { "_nswap" },
                     25: #define        X_NSWAP         3
                     26:        { "_nproc" },
                     27: #define        X_NPROC         4
                     28:        { 0 },
                     29: };
                     30: 
                     31: #define PROCCHUNK 8            /* a few, for fewer syscalls */
                     32: struct proc proc[PROCCHUNK];
                     33: struct proc *mproc;
                     34: 
                     35: 
                     36: int    paduser1;               /* avoid hardware mem clobbering botch */
                     37: union {
                     38:        struct  user user;
                     39:        char    upages[UPAGES][NBPG];
                     40: } user;
                     41: #define u      user.user
                     42: int    paduser2;               /* avoid hardware mem clobbering botch */
                     43: 
                     44: #define clear(x)       ((int)x & 0xfffff)
                     45: 
                     46: int    nswap;
                     47: struct pte *Usrptma, *usrpt;
                     48: int    nproc;
                     49: 
                     50: char   *kmemf, *memf, *swapf, *nlistf;
                     51: int    kmem, mem, swap;
                     52: long   lseek();
                     53: 
                     54: int    pcbpf;
                     55: int    argaddr;
                     56: extern char _sobuf[];
                     57: 
                     58: main(argc, argv)
                     59:        char **argv;
                     60: {
                     61:        register int i, j;
                     62:        off_t procp;
                     63: 
                     64:        initialize (argc, argv);
                     65:        setbuf(stdout, _sobuf);
                     66:        openfiles();
                     67:        getkvars();
                     68:        procp = getw((off_t) nl[X_PROC].n_value);
                     69:        nproc = getw((off_t) nl[X_NPROC].n_value);
                     70:        for (i=0; i<nproc; i += PROCCHUNK) {
                     71:                KMlseek(kmem, (long) (char *)procp, 0);
                     72:                j = nproc - i;
                     73:                if (j > PROCCHUNK)
                     74:                        j = PROCCHUNK;
                     75:                j *= sizeof (struct proc);
                     76:                if (read(kmem, (char *)proc, j) != j)
                     77:                        cantread("proc table", kmemf);
                     78:                procp += j;
                     79:                for (j = j / sizeof (struct proc) - 1; j >= 0; j--) {
                     80:                        mproc = &proc[j];
                     81:                        if (mproc->p_stat == 0)
                     82:                                continue;
                     83:                        if (mproc->p_stat == SZOMB || getu() == 0)
                     84:                                continue;
                     85:                        doproc (mproc, &u);
                     86:                }
                     87:        }
                     88:        return 0;
                     89: }
                     90: 
                     91: getw(loc)
                     92:        off_t loc;
                     93: {
                     94:        long word;
                     95: 
                     96:        KMlseek(kmem, (long) loc, 0);
                     97:        if (read(kmem, (char *) &word, sizeof (word)) != sizeof (word))
                     98:                printf("error reading kmem at %x\n", loc);
                     99:        return (word);
                    100: }
                    101: 
                    102: openfiles()
                    103: {
                    104: 
                    105:        kmemf = "/dev/kmem";
                    106:        kmem = open(kmemf, 0);
                    107:        if (kmem < 0) {
                    108:                perror(kmemf);
                    109:                exit(1);
                    110:        }
                    111:        memf = "/dev/mem";
                    112:        mem = open(memf, 0);
                    113:        if (mem < 0) {
                    114:                perror(memf);
                    115:                exit(1);
                    116:        }
                    117:        swapf = "/dev/drum";
                    118:        swap = open(swapf, 0);
                    119:        if (swap < 0) {
                    120:                perror(swapf);
                    121:                exit(1);
                    122:        }
                    123: }
                    124: 
                    125: getkvars()
                    126: {
                    127:        nlistf = "/unix";
                    128:        nlist(nlistf, nl);
                    129:        if (nl[0].n_type == 0) {
                    130:                fprintf(stderr, "%s: No namelist\n", nlistf);
                    131:                exit(1);
                    132:        }
                    133:        Usrptma = (struct pte *)nl[X_USRPTMA].n_value;
                    134:        usrpt = (struct pte *)nl[X_USRPT].n_value;
                    135:        KMlseek(kmem, (long)nl[X_NSWAP].n_value, 0);
                    136:        if (read(kmem, (char *) &nswap, sizeof (nswap)) != sizeof (nswap)) {
                    137:                cantread("nswap", kmemf);
                    138:                exit(1);
                    139:        }
                    140: }
                    141: 
                    142: cantread(what, fromwhat)
                    143:        char *what, *fromwhat;
                    144: {
                    145:        fprintf(stderr, "ps: error reading %s from %s\n", what, fromwhat);
                    146: }
                    147: 
                    148: 
                    149: 
                    150: getu()
                    151: {
                    152:        struct pte *pteaddr, apte;
                    153:        int pad1;       /* avoid hardware botch */
                    154:        struct pte arguutl[UPAGES+CLSIZE];
                    155:        int pad2;       /* avoid hardware botch */
                    156:        register int i;
                    157:        int ncl, size;
                    158: 
                    159:        size = sizeof (struct user);
                    160:        if ((mproc->p_flag & SLOAD) == 0) {
                    161:                lseek(swap, (long) ctob(mproc->p_swaddr), 0);
                    162:                if (read(swap, (char *)&user.user, size) != size) {
                    163:                        fprintf(stderr, "ps: cant read u for pid %d from %s\n",
                    164:                            mproc->p_pid, swapf);
                    165:                        return (0);
                    166:                }
                    167:                pcbpf = 0;
                    168:                argaddr = 0;
                    169:                return (1);
                    170:        }
                    171:        pteaddr = &Usrptma[btokmx(mproc->p_p0br) + mproc->p_szpt - 1];
                    172:        KMlseek(kmem, (long)pteaddr, 0);
                    173:        if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
                    174:                printf("ps: cant read indir pte to get u for pid %d from %s\n",
                    175:                    mproc->p_pid, swapf);
                    176:                return (0);
                    177:        }
                    178:        lseek(mem,
                    179:            (long) (ctob(apte.pg_pfnum+1) - (UPAGES+CLSIZE) * sizeof (struct pte)),
                    180:            0);
                    181:        if (read(mem, (char *)arguutl, sizeof(arguutl)) != sizeof(arguutl)) {
                    182:                printf("ps: cant read page table for u of pid %d from %s\n",
                    183:                    mproc->p_pid, swapf);
                    184:                return (0);
                    185:        }
                    186:        if (arguutl[0].pg_fod == 0 && arguutl[0].pg_pfnum)
                    187:                argaddr = ctob(arguutl[0].pg_pfnum);
                    188:        else
                    189:                argaddr = 0;
                    190:        pcbpf = arguutl[CLSIZE].pg_pfnum;
                    191:        ncl = (size + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
                    192:        while (--ncl >= 0) {
                    193:                i = ncl * CLSIZE;
                    194:                lseek(mem, (long) ctob(arguutl[CLSIZE+i].pg_pfnum), 0);
                    195:                if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
                    196:                        printf("ps: cant read page %d of u of pid %d from %s\n",
                    197:                            arguutl[CLSIZE+i].pg_pfnum, mproc->p_pid, memf);
                    198:                        return(0);
                    199:                }
                    200:        }
                    201:        return (1);
                    202: }
                    203: 
                    204: KMlseek(f, a, c)
                    205:        long a;
                    206: {
                    207:        lseek(f, a, c);
                    208: }
                    209: 
                    210: #define        NMAX    8
                    211: #define        NUID    2048
                    212: 
                    213: char   names[NUID][NMAX+1];
                    214: 
                    215: /*
                    216:  * Stolen from ls...
                    217:  */
                    218: char *
                    219: getname(uid)
                    220: {
                    221:        register struct passwd *pw;
                    222:        static init;
                    223:        struct passwd *getpwent();
                    224: 
                    225:        if (uid >= 0 && uid < NUID && names[uid][0])
                    226:                return (&names[uid][0]);
                    227:        if (init == 2)
                    228:                return (0);
                    229:        if (init == 0)
                    230:                setpwent(), init = 1;
                    231:        while (pw = getpwent()) {
                    232:                if (pw->pw_uid >= NUID)
                    233:                        continue;
                    234:                if (names[pw->pw_uid][0])
                    235:                        continue;
                    236:                strncpy(names[pw->pw_uid], pw->pw_name, NMAX);
                    237:                if (pw->pw_uid == uid)
                    238:                        return (&names[uid][0]);
                    239:        }
                    240:        init = 2;
                    241:        endpwent();
                    242:        return (0);
                    243: }
                    244: 
                    245: #define new(type) ((type *) alloc (sizeof (type)))
                    246: 
                    247: char   *freebase;
                    248: int    nleft;
                    249: 
                    250: char *
                    251: alloc(size)
                    252:        int size;
                    253: {
                    254:        register char *cp;
                    255:        register int i;
                    256: 
                    257:        if (size > nleft) {
                    258:                freebase = (char *)sbrk(i = size > 2048 ? size : 2048);
                    259:                if (freebase == 0) {
                    260:                        fprintf(stderr, "ps: ran out of memory\n");
                    261:                        exit(1);
                    262:                }
                    263:                nleft = i - size;
                    264:        } else
                    265:                nleft -= size;
                    266:        cp = freebase;
                    267:        for (i = size; --i >= 0; )
                    268:                *cp++ = 0;
                    269:        freebase = cp;
                    270:        return (cp - size);
                    271: }
                    272: 
                    273: char *
                    274: savestr(cp)
                    275:        char *cp;
                    276: {
                    277:        register int len;
                    278:        register char *dp;
                    279: 
                    280:        len = strlen(cp);
                    281:        dp = (char *)alloc(len+1);
                    282:        strcpy(dp, cp);
                    283:        return (dp);
                    284: }
                    285: 
                    286: /*
                    287:  *     read /dev, and record device names, block/character, and
                    288:  *     major/minor devices.
                    289:  */
                    290: 
                    291: #define DEVDIR "/dev"
                    292: 
                    293: struct devdesc {
                    294:        struct devdesc *next;
                    295:        char *name;
                    296:        int mode;
                    297:        dev_t dev;
                    298: } *devhead;
                    299: 
                    300: int
                    301: tryfile (name, p, code)
                    302:        char *name;
                    303:        register struct stat *p;
                    304:        int code;
                    305: {
                    306:        if (code == FTW_F) {
                    307:                register int mode = p->st_mode & S_IFMT;
                    308:                if (mode == S_IFBLK || mode == S_IFCHR) {
                    309:                        register struct devdesc *dp;
                    310:                        dp = new (struct devdesc);
                    311:                        dp->name = savestr (name + sizeof (DEVDIR));
                    312:                        dp->mode = mode;
                    313:                        dp->dev = p->st_rdev;
                    314:                        dp->next = devhead;
                    315:                        devhead = dp;
                    316:                }
                    317:        }
                    318:        return 0;
                    319: }
                    320: 
                    321: struct procdesc {
                    322:        int pid;
                    323:        struct procdesc *next;
                    324: } *prochead;
                    325: 
                    326: struct pdevdesc {
                    327:        dev_t dev;
                    328:        int mode;
                    329:        ino_t ino;
                    330:        struct pdevdesc *next;
                    331: } *pdevhead;
                    332: 
                    333: initialize(c, v)
                    334:        int c;
                    335:        char **v;
                    336: {
                    337:        register int n;
                    338: 
                    339:        for (n = 1; n < c; n++) {
                    340:                if (isnumber (v[n])) {
                    341:                        register struct procdesc *p;
                    342:                        p = new (struct procdesc);
                    343:                        p->pid = atoi (v[n]);
                    344:                        p->next = prochead;
                    345:                        prochead = p;
                    346:                } else {
                    347:                        struct stat sb;
                    348:                        if (stat (v[n], &sb) < 0)
                    349:                                perror (v[n]);
                    350:                        else {
                    351:                                register int mode;
                    352:                                register struct pdevdesc *pd;
                    353:                                pd = new (struct pdevdesc);
                    354:                                mode = sb.st_mode & S_IFMT;
                    355:                                pd->mode = mode;
                    356:                                if (mode == S_IFBLK || mode == S_IFCHR) {
                    357:                                        pd->dev = sb.st_rdev;
                    358:                                        pd->ino = 0;
                    359:                                } else {
                    360:                                        pd->dev = sb.st_dev;
                    361:                                        pd->ino = sb.st_ino;
                    362:                                }
                    363:                                pd->next = pdevhead;
                    364:                                pdevhead = pd;
                    365:                        }
                    366:                }
                    367:        }
                    368: 
                    369:        if (pdevhead == NULL)
                    370:                ftw (DEVDIR, tryfile, 3);
                    371: }
                    372: 
                    373: int
                    374: isnumber (p)
                    375:        register char *p;
                    376: {
                    377:        while (isdigit (*p))
                    378:                p++;
                    379:        return *p == '\0';
                    380: }
                    381: 
                    382: /*
                    383:  *     Here, we handle a process.
                    384:  *
                    385:  *     Everything that has come before is essentially independent
                    386:  *     of what we are doing with the particular process.
                    387:  *
                    388:  *     If pdevhead is set, we are just going to print process numbers.
                    389:  *     The global variable "found" will greatly assist us in this:
                    390:  *     it will be set nonzero as soon as we decide to print this process.
                    391:  */
                    392: 
                    393: int found;
                    394: 
                    395: #undef u
                    396: 
                    397: void
                    398: printdev (str, dev, mode, rmode, ino)
                    399:        char *str;
                    400:        dev_t dev;
                    401:        int mode, rmode;
                    402:        ino_t ino;
                    403: {
                    404:        register struct devdesc *dp;
                    405:        register struct pdevdesc *pd;
                    406: 
                    407:        mode &= IFMT;
                    408:        rmode &= IFMT;
                    409: 
                    410:        if (pdevhead) {
                    411:                if (!found) {
                    412:                        for (pd = pdevhead; pd; pd = pd->next) {
                    413:                                if (dev == pd->dev && (pd->ino ?
                    414:                                    (ino == pd->ino && rmode == pd->mode) :
                    415:                                    (mode == pd->mode))) {
                    416:                                        found = 1;
                    417:                                        return;
                    418:                                }
                    419:                        }
                    420:                }
                    421:                return;
                    422:        }
                    423:                
                    424:        for (dp = devhead; dp; dp = dp->next) {
                    425:                if (mode == dp->mode && dev == dp->dev) {
                    426:                        if (*str)
                    427:                                printf ("%s ", str);
                    428:                        if (ino)
                    429:                                printf ("%d ", ino);
                    430:                        if (*str)
                    431:                                printf ("on ");
                    432:                        printf ("%s", dp->name);
                    433:                        return;
                    434:                }
                    435:        }
                    436: 
                    437:        printf ("(%d/%d)", major (dev), minor (dev));
                    438: }
                    439: 
                    440: struct inode *
                    441: getinode (ip, pid)
                    442:        struct inode *ip;
                    443: {
                    444:        static struct inode ibuf;
                    445:        KMlseek (kmem, (long) ip, 0);
                    446:        if (read (kmem, &ibuf, sizeof (ibuf)) != sizeof (ibuf)) {
                    447:                fprintf (stderr, "proc %d: can't read inode at %lx\n", pid, ip);
                    448:                return NULL;
                    449:        }
                    450:        return &ibuf;
                    451: }
                    452: 
                    453: void
                    454: doinode (str, ip, pid)
                    455:        register char *str;
                    456:        register struct inode *ip;
                    457: {
                    458:        int mode;
                    459: 
                    460:        if (ip && (ip = getinode (ip, pid))) {
                    461: 
                    462:                if (pdevhead) {
                    463:                        if (found)
                    464:                                return;
                    465:                } else
                    466:                        printf ("\t%s: ", str);
                    467: 
                    468:                mode = ip->i_mode & IFMT;
                    469:                switch (mode) {
                    470: 
                    471:                case IFDIR:
                    472:                        printdev ("dir", ip->i_dev, IFBLK, mode, ip->i_number);
                    473:                        break;
                    474:                
                    475:                case IFREG:
                    476:                        printdev ("file", ip->i_dev, IFBLK, mode, ip->i_number);
                    477:                        break;
                    478:                
                    479:                case IFLNK:
                    480:                        printdev ("slink", ip->i_dev, IFBLK, mode, ip->i_number);
                    481:                        break;
                    482:                
                    483:                case IFBLK:
                    484:                case IFCHR:
                    485:                        printdev ("", ip->i_un.i_rdev, ip->i_mode, mode, (ino_t) 0);
                    486:                        break;
                    487:                
                    488:                default:
                    489:                        fprintf (stderr, "??? mode %o", ip->i_mode);
                    490:                        break;
                    491:                }
                    492:                if (pdevhead == NULL)
                    493:                        printf ("\n");
                    494:        }
                    495: 
                    496: }
                    497: 
                    498: void
                    499: dotext (tp, pid)
                    500:        register struct text *tp;
                    501: {
                    502:        if (tp) {
                    503:                struct text t;
                    504:                KMlseek (kmem, (long) tp, 0);
                    505:                if (read (kmem, &t, sizeof (t)) != sizeof (t)) {
                    506:                        fprintf (stderr, "can't read file at %lx\n", tp);
                    507:                        return;
                    508:                }
                    509:                doinode ("prog", t.x_iptr, pid);
                    510:        }
                    511: }
                    512: 
                    513: void
                    514: dofile (n, fp)
                    515:        int n;
                    516:        register struct file *fp;
                    517: {
                    518:        if (fp) {
                    519:                struct file f;
                    520:                char buf[100];
                    521: 
                    522:                KMlseek (kmem, (long) fp, 0);
                    523:                if (read (kmem, &f, sizeof (f)) != sizeof (f)) {
                    524:                        fprintf (stderr, "can't read file at %lx\n", fp);
                    525:                        return;
                    526:                }
                    527:                sprintf (buf, "fd %d at %ld", n, f.f_offset);
                    528:                doinode (buf, f.f_inode);
                    529:        }
                    530: }
                    531: 
                    532: doproc (p, u)
                    533:        register struct proc *p;
                    534:        register struct user *u;
                    535: {
                    536:        struct inode *ip;
                    537:        register int i;
                    538: 
                    539:        found = 0;
                    540: 
                    541:        /* handle only selected processes if asked */
                    542:        if (prochead) {
                    543:                register struct procdesc *pd;
                    544: 
                    545:                pd = prochead;
                    546:                while (pd && pd->pid != p->p_pid)
                    547:                        pd = pd->next;
                    548:                if (pd == NULL)
                    549:                        return;
                    550:        }
                    551: 
                    552:        if (pdevhead == NULL)
                    553:                printf ("process %d, user %s\n", p->p_pid, getname(p->p_uid));
                    554: 
                    555:        dotext (p->p_textp, p->p_pid);
                    556:        doinode ("cdir", u->u_cdir, p->p_pid);
                    557: 
                    558:        if (!found)
                    559:                doinode ("rdir", u->u_rdir, p->p_pid);
                    560: 
                    561:        for (i = 0; i < NOFILE && !found; i++)
                    562:                dofile (i, u->u_ofile[i]);
                    563: 
                    564:        if (pdevhead) {
                    565:                if (found)
                    566:                        printf ("%d\n", p->p_pid);
                    567:        } else {
                    568:                printf ("\n");
                    569:                fflush (stdout);
                    570:        }
                    571: }

unix.superglobalmegacorp.com

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