Annotation of 42BSD/undoc/sps/sps.c, revision 1.1.1.1

1.1       root        1: #
                      2: /*
                      3:  ps - show process status - iiasa version (jek)
                      4:        originally from harvard and/or CULC
                      5: 
                      6:        flags are single letters
                      7:        multiple flags can occur in one argument
                      8:        dashes are optional but are needed to delimit lists of things
                      9:                multiple lists are present(???)
                     10:        flags that imply other arguments read the following arguments
                     11:                until the end of the list or until an argument starts with dash
                     12:        certain flags read exactly one argument
                     13:        initialization (i flag) should be done for:
                     14:                new users,
                     15:                new kernel
                     16:        parameters here must change to indicate:
                     17:                new tty devices, max tty lines, tty letter changes
                     18:                max users
                     19:                new things to wait for
                     20:        this program should be changed if:
                     21:                proc structure makes this obsolete
                     22:                etc
                     23:        recompilation should occur if:
                     24:                kernel structures and or paramters (nproc etc.) change
                     25:                any above changes of course
                     26: 
                     27:        flags are:
                     28:                a - show all processes that have pgrps except shells
                     29:                b - show background (not detached)
                     30:                c - show child times instead of process times
                     31:                d - show detached processes inherited by init
                     32:                e - show the environment with the args
                     33:                f - show foreground jobs, connected to tty
                     34:                g - show processes in given pgrps
                     35:                h - unused
                     36:                i - perform initialization (implies 'n')
                     37:                j,k - unused
                     38:                l - print long format. includes most good stuff
                     39:                m - specify different memory file (file is next arg)
                     40:                n - show no processes
                     41:                o - unused
                     42:                p - show only processes whose id's are in list (following args)
                     43:                q - unused
                     44:                r - repeat indefinitely (number of r's = seconds or r#)
                     45:                s - show stopped processes
                     46:                t - show only processes associated with ttys in list (following)
                     47:                u - show only processes (or ancestors of) for users in list
                     48:                v - be verbose - show the most information
                     49:                w - wide format, show entire argument list (up to 512 chars)
                     50:                x - show unattached processes - no pgrp. a+x gives shells also
                     51:                y - unused
                     52:                z - show zombies
                     53:                A - show ALL information possible
                     54:                B - show busy processes
                     55:                F - go fast, avoid swap space.
                     56:                G - print pgrp
                     57:                U - use different UNIX file (next arg)
                     58:                S - show size
                     59:                T - show tty information
                     60:                W - print wait channels in hex
                     61: */
                     62: 
                     63: #include       <signal.h>
                     64: #include       <h/param.h>
                     65: #include       <h/dir.h>
                     66: #include       <h/user.h>
                     67: #include       <h/proc.h>
                     68: #include       <h/pte.h>
                     69: #include       <h/vm.h>
                     70: #include       <h/inode.h>
                     71: #include       <h/file.h>
                     72: #include       <h/buf.h>
                     73: #include       <h/text.h>
                     74: #include       <h/tty.h>
                     75: #include       <h/conf.h>
                     76: #include       <nlist.h>
                     77: #include       <sys/stat.h>
                     78: #include       <stdio.h>
                     79: #include       <pwd.h>
                     80: 
                     81: 
                     82: #define        TRUE    1
                     83: #define FALSE  0
                     84: #define        INTPPG  (NBPG/sizeof(int))
                     85: #define MAXARGPG       5
                     86: 
                     87: #define Usrptmap               ((struct pte *)info.kaddr[ausrptmap])
                     88: #define usrpt          ((struct pte *)info.kaddr[ausrpt])
                     89: #define cswitch                ((struct cdevsw *)info.kaddr[acdevsw])
                     90: struct proc *proc, *kproc;
                     91: struct text *text, *ktext;
                     92: struct buf *buf, *swbuf;
                     93: struct inode *inode;
                     94: int nproc, ntext, hz, nbuf, ninode, nfile, nswbuf;
                     95: union {
                     96:        struct user user;
                     97:        char    upages[UPAGES][NBPG];
                     98: } user;
                     99: int pad1;      /* supposedly to aviod hardware problem reading /dev/mem */
                    100: struct pte pagetable[UPAGES + MAXARGPG];       /* for users page table */
                    101: int pad2;      /* supposedly to aviod hardware problem reading /dev/mem */
                    102: 
                    103: #define u      user.user
                    104: #define MSPID  2               /* max system pid, not to considered BUSY */
                    105: 
                    106: #define        MAXUSERS        256     /* total different users */
                    107: #define        UNAMELENGTH     8       /* length of a user name */
                    108: #define        NSPEC           15      /* number of specified things (proc, user, tty */
                    109: #define MAXTTYS                100
                    110: 
                    111: /* definitions to reuse uninteresting proc table entries for linked lists */
                    112: 
                    113: struct procinfo        {               /* structure to use for */
                    114:        char    *pi_cmd;                /* attaching a time */
                    115:        struct ttyline  *pi_tty;
                    116:        long    pi_time;                /* and an arg string to a proc */
                    117: };
                    118: 
                    119: #define p_next         p_link          /* pointer to next proc in global list */
                    120: #define        p_bro           p_rlink         /* next process with same parent */
                    121: #define        p_son           p_xlink         /* first child of this process */
                    122: #define pinfo(p)       (*((struct procinfo **)&p->p_sig))
                    123: #define procsize(p)    ((p)->p_tsize + (p)->p_dsize + (p)->p_ssize)
                    124:                                        /* size of process */
                    125: #define ABS(x) ((int)(x) & ~0x80000000)        /* clear top bit - type int */
                    126: #define K 1024
                    127: #define KSHIFT 10
                    128: 
                    129: #define msize(x)       (x >> (KSHIFT-PGSHIFT))
                    130: 
                    131: #define        USERPAGE        0               /* flag for pread - read user page */
                    132: #define        TOPMEM          1               /* flag for pread - read top of mem */
                    133: 
                    134: struct proc    *plist;
                    135: int            mypid;                  /* pid of this process */
                    136: 
                    137: char   Aflag, aflag, Bflag, bflag, cflag, dflag, eflag, fflag, Fflag;
                    138: char   Gflag, iflag, lflag, mflag, nflag, rflag, Sflag, sflag, Tflag;
                    139: char   Uflag, uflag, vflag, wflag, xflag, nxflag, Wflag, zflag;
                    140: int select;            /* flag indicating process selection */
                    141: 
                    142: int    ntotal, nbusy, nloaded, nswapped;
                    143: int    ktotal, kbusy, kloaded, kswapped;
                    144: 
                    145: /* specified users, ttys, pids, pgrps */
                    146: union numptr {
                    147:        int nm_int;
                    148:        char *nm_ptr;
                    149: };
                    150: 
                    151: union ttyptr {
                    152:        struct ttyline *ty_line;
                    153:        char *ty_ptr;
                    154: };
                    155: 
                    156: union numptr   pids[NSPEC], *ppids = pids;     /* specified process ids */
                    157: union numptr   grps[NSPEC], *pgrps = grps;     /* specified groups */
                    158: union numptr   uids[NSPEC], *puids = uids;     /* specified user ids */
                    159: union ttyptr   ttys[NSPEC], *pttys = ttys;     /* specified ttys */
                    160: 
                    161: /* files needed by ps */
                    162: 
                    163: char   *memf = "/dev/mem";             /* default memory file */
                    164: int    mem;                            /* memory file descriptor */
                    165: char   *kmemf = "/dev/kmem";           /* virtual memory file */
                    166: int    kmem;                           /* virtual memory file descriptor */
                    167: char   *symf = "/vmunix";              /* default symbol file */
                    168: char   *swapf = "/dev/swap";           /* default swap file */
                    169: int    swap;                           /* swap area file descriptor */
                    170: char   *infof = "/etc/spsinfo";        /* default info save file */
                    171: int    infofd;                         /* info file descriptor */
                    172: 
                    173: /* variables read from the kernel */
                    174: 
                    175: struct nlist   namelist[] = {
                    176: #define aproc          0
                    177:        {"_proc"},
                    178: #define        aswapdev        1
                    179:        {"_swapdev"},
                    180: #define        aswplo          2
                    181:        {"_swplo"},
                    182: #define        answbuf         3
                    183:        {"_nswbuf"},
                    184: #define        atext           4
                    185:        {"_text"},
                    186: #define        abuf            5
                    187:        {"_buf"},
                    188: #define        abfreeli        6
                    189:        {"_bfreelist"},
                    190: #define        akl11           7
                    191:        {"_kl11"},
                    192: #define        adh11           8
                    193:        {"_dh11"},
                    194: #define        alpdt           9
                    195:        {"_lp_softc"},
                    196: #define        albolt          10
                    197:        {"_lbolt"},
                    198: #define        atout           11
                    199:        {"_tout"},
                    200: #define        arunin          12
                    201:        {"_runin"},
                    202: #define        arunout         13
                    203:        {"_runout"},
                    204: #define        aipc            14
                    205:        {"_ipc"},
                    206: #define        afile           15
                    207:        {"_file"},
                    208: #define        ainode          16
                    209:        {"_inode"},
                    210: #define        amaplock        17
                    211:        {"_maplock"},
                    212: #define        acoremap        18
                    213:        {"_coremap"},
                    214: #define        aswapmap        19
                    215:        {"_swapmap"},
                    216: #define        au              20
                    217:        {"_u"},
                    218: #define adz11          21
                    219:        {"_dz_tty"},
                    220: #define aetext         22
                    221:        {"_etext"},
                    222: #define ausrptmap      23
                    223:        {"_Usrptmap"},
                    224: #define        ausrpt          24
                    225:        {"_usrpt"},
                    226: #define        achtbuf         25
                    227:        {"_chtbuf"},
                    228: #define        arhtbuf         26
                    229:        {"_rhtbuf"},
                    230: #define        ahpbuf          27
                    231:        {"_hpbuf"},
                    232: #define aswbuf         28
                    233:        {"_swbuf"},
                    234: #define arswbuf                29
                    235:        {"_rswbuf"},
                    236: #define acons          30
                    237:        {"_cons"},
                    238: #define ark7           31
                    239:        {"_rrk7buf"},
                    240: #define achrfclist     32
                    241:        {"_Chrfclist"},
                    242: #define anproc         33
                    243:        {"_nproc"},
                    244: #define antext         34
                    245:        {"_ntext"},
                    246: #define anbuf          35
                    247:        {"_nbuf"},
                    248: #define ahz            36
                    249:        {"_hz"},
                    250: #define aninode                37
                    251:        {"_ninode"},
                    252: #define anfile         38
                    253:        {"_nfile"},
                    254: #define answap         39
                    255:        {"_nswap"},
                    256: #define        acdevsw         40
                    257:        {"_cdevsw"},
                    258: #define        aChconntab      41
                    259:        {"_Chconntab"},
                    260: #define        MAXSYMBOLS      42
                    261:        {"", 0, 0},
                    262: };
                    263: 
                    264: /* this structure is read from info file or initialized (iflag) */
                    265: 
                    266: struct {
                    267:        caddr_t kaddr[MAXSYMBOLS];              /* useful kernel addresses */
                    268:        char    unames[MAXUSERS][UNAMELENGTH];  /* user names */
                    269:        struct  ttyline {
                    270:                struct tty      *l_addr;                /* address of ttystruct */
                    271:                unsigned        l_pgrp;         /* process group */
                    272:                char            l_name[2];      /* name */
                    273:                dev_t           l_dev;          /* device number */
                    274:        } ttyline[MAXTTYS];     
                    275:        
                    276: } info;
                    277: int    swapdev;                        /* major, minor of swap device */
                    278: int    swplo;                          /* unix swap disk offset */
                    279: int    nswap;                          /* unix swap space size */
                    280: 
                    281: struct ttyline notty = {0, 0, {"- "}};
                    282: 
                    283: /* flags for once only activities (once per repeat) */
                    284: 
                    285: int heading;
                    286: int coreinit, core;
                    287: char *topmem;
                    288: int arglength;
                    289: char *getcore(), *store(), *waitingfor(), *getcmd(), *strcat(), *brk();
                    290: 
                    291: main(argc,argv)
                    292: char *argv[];
                    293: {
                    294:        register char *cp, **ap;
                    295:        register int i;
                    296:        int myuid;
                    297:        extern char _sobuf[];
                    298: 
                    299:        if ((myuid = getuid()) == 0)
                    300:                nice(-100);
                    301: 
                    302:        setbuf(stdout, _sobuf);
                    303:        select = 0;
                    304:        for (ap = &argv[1]; --argc; ap++) {
                    305:                for (cp = *ap; *cp;) {
                    306:                        switch (*cp++) {
                    307:                        case '-':
                    308:                                continue;
                    309:                        case 'A':       /* EVERYTHING */
                    310:                                Aflag++;
                    311:                                continue;
                    312:                        case 'a':       /* all procs attached to ttys */
                    313:                                bflag++;        /* include background */
                    314:                                fflag++;        /* include foreground */
                    315:                                dflag++;        /* include detached */
                    316:                                aflag++;        /* include shells */
                    317:                                select++;
                    318:                                continue;
                    319:                        case 'b':       /* all background processes */
                    320:                                bflag++;
                    321:                                select++;
                    322:                                continue;
                    323:                        case 'B':       /* all busy processes */
                    324:                                Bflag++;
                    325:                                select++;
                    326:                                lflag++;
                    327:                                continue;
                    328:                        case 'c':
                    329:                                cflag++;
                    330:                                lflag++;
                    331:                                continue;
                    332:                        case 'd':       /* detached processes */
                    333:                                dflag++;
                    334:                                select++;
                    335:                                continue;
                    336:                        case 'e':
                    337:                                eflag++;
                    338:                                continue;
                    339:                        case 'f':       /* foreground only */
                    340:                                fflag++;
                    341:                                select++;
                    342:                                continue;
                    343:                        case 'F':       /* go fast, don't touch swap */
                    344:                                Fflag++;
                    345:                                continue;
                    346:                        case 'G':       /* print pgrp */
                    347:                                Gflag++;
                    348:                                continue;
                    349:                        case 'g':       /* specify process gourp */
                    350:                                select++;
                    351:                                while (argc > 1) {
                    352:                                        if (**++ap == '-') {
                    353:                                                ap--;
                    354:                                                break;
                    355:                                        }
                    356:                                        --argc;
                    357:                                        if (pgrps >= &grps[NSPEC])
                    358:                                                prexit("%a: too many groups\n");
                    359:                                        (pgrps++)->nm_int = atoi(*ap);
                    360:                                }
                    361:                                if (pgrps == grps)
                    362:                                        (pgrps++)->nm_int = getpgrp();
                    363:                                continue;
                    364:                        case 'i':       /* initialize info file */
                    365:                                if (myuid != 0) /* must be super user */
                    366:                                        goto def;
                    367:                                iflag++;
                    368:                                nflag++;
                    369:                                Uflag++;
                    370:                                continue;
                    371:                        case 'l':       /* long output */
                    372:                                lflag++;
                    373:                                continue;
                    374:                        case 'm':       /* use designated memory file */
                    375:                                if (myuid != 0) /* must be super user */
                    376:                                        goto def;
                    377:                                if (argc-- < 2 || **++ap == '-')
                    378:                                        prexit("%a: missing memory file\n");
                    379:                                memf = *ap;
                    380:                                mflag++;
                    381:                                continue;
                    382:                        case 'n':
                    383:                                select++;
                    384:                                nflag++;
                    385:                                continue;
                    386:                        case 'p':       /* only designated processes */
                    387:                                select++;
                    388:                                while (argc > 1) {
                    389:                                        if (**++ap == '-') {
                    390:                                                ap--;
                    391:                                                break;
                    392:                                        }
                    393:                                        --argc;
                    394:                                        if (ppids >= &pids[NSPEC])
                    395:                                                prexit("%a: too many pids\n");
                    396:                                        (ppids++)->nm_int = atoi(*ap);
                    397:                                }
                    398:                                continue;
                    399:                        case 'r':       /* repeat every <number> seconds */
                    400:                                if (myuid != 0)
                    401:                                        goto def;
                    402:                                rflag++;
                    403:                                for (i = 0; *cp >= '0' && *cp <= '9'; cp++)
                    404:                                        i = i * 10 + *cp - '0';
                    405:                                if (i)
                    406:                                        rflag = i;
                    407:                                continue;
                    408:                        case 'U':       /* use designated symbol file */
                    409:                                if (myuid != 0)
                    410:                                        goto def;
                    411:                                if (argc-- < 2 || **++ap == '-')
                    412:                                        prexit("%a: missing symbol file\n");
                    413:                                symf = *ap;
                    414:                                Uflag++;
                    415:                                continue;
                    416:                        case 's':
                    417:                                sflag++;
                    418:                                select++;
                    419:                                continue;
                    420:                        case 'S':
                    421:                                Sflag++;
                    422:                                continue;
                    423:                        case 'T':
                    424:                                Tflag++;
                    425:                                continue;
                    426:                        case 't':       /* on designated tty(s) */
                    427:                                select++;
                    428:                                while (argc > 1) {
                    429:                                        if (**++ap == '-') {
                    430:                                                ap--;
                    431:                                                break;
                    432:                                        }
                    433:                                        --argc;
                    434:                                        if (pttys >= &ttys[NSPEC])
                    435:                                                prexit("%a: too many ttys\n");
                    436:                                        (pttys++)->ty_ptr = *ap;
                    437:                                }
                    438:                                if (pttys == ttys) {
                    439:                                        char *ttyname();
                    440: 
                    441:                                        if ( (pttys->ty_ptr = ttyname(2)) == 0)
                    442:                                                prexit("%a: unknown tty\n");
                    443:                                        else if (strcmp("/dev/console", pttys->ty_ptr) == 0)
                    444:                                                (pttys++)->ty_ptr = "co";
                    445:                                        else
                    446:                                                (pttys++)->ty_ptr +=
                    447:                                                        sizeof("/dev/tty") - 1;
                    448:                                }
                    449:                                continue;
                    450:                        case 'u':               /* specific user name */
                    451:                                aflag++;
                    452:                                select++;
                    453:                                puids = &uids[0];
                    454:                                while (argc > 1) {
                    455:                                        if (**++ap == '-') {
                    456:                                                ap--;
                    457:                                                break;
                    458:                                        }
                    459:                                        --argc;
                    460:                                        if (puids >= &uids[NSPEC])
                    461:                                                prexit("%a: too many users\n");
                    462:                                        (puids++)->nm_ptr = *ap;
                    463:                                }
                    464:                                if (puids == &uids[0])
                    465:                                        (puids++)->nm_int = myuid;
                    466:                                continue;
                    467:                        case 'v':       /* most verbose output */
                    468:                                vflag++;
                    469:                                lflag++;
                    470:                                continue;
                    471:                        case 'W':
                    472:                                Wflag++;
                    473:                                continue;
                    474:                        case 'w':       /* wide form (all arguments) */
                    475:                                wflag++;
                    476:                                continue;
                    477:                        case 'x':       /* include un-owned procs */
                    478:                                xflag++;
                    479:                                select++;
                    480:                                continue;
                    481:                        case 'z':       /* include only zombies */
                    482:                                zflag++;
                    483:                                select++;
                    484:                                continue;
                    485:                        def:
                    486:                        default:
                    487:                                prexit("%a: unknown switch: %c\n", *--cp);
                    488:                        }
                    489:                        break;
                    490:                }
                    491:        }
                    492: 
                    493: /* these lengths are kludgely tuned to make things not exceed 79 columns */
                    494:        arglength = 60;
                    495:        if (lflag)
                    496:                arglength -= 28;
                    497:        if (vflag)
                    498:                arglength -= 14;
                    499:        if ((mem = open(memf, 0)) < 0)
                    500:                prexit("%a: cannot read system memory: %s\n", memf);
                    501:        if ((kmem = open(kmemf, 0)) < 0)
                    502:                prexit("%a: cannot read system virtural memory: %s\n", kmemf);
                    503:        if (!Fflag && (swap = open(swapf, 0)) <0)
                    504:                prexit("%a: cannot read swap device: %s\n", swapf);
                    505: 
                    506:        if (!iflag)
                    507:                if ((i = open(infof, 0)) < 0)
                    508:                        prexit("%a: cannot open info file\n");
                    509:                else if (read(i, &info, sizeof info) != sizeof info)
                    510:                        prexit("%a: cannot read info file\n");
                    511:                else
                    512:                        close(i);
                    513:        if (Uflag) {
                    514:                struct nlist *np;
                    515:                if ((i = open(symf, 0)) < 0)
                    516:                        prexit("%a: can't read symbol file\n");
                    517:                close(i);
                    518:                nlist(symf, namelist);
                    519:                for (np = namelist; np < &namelist[MAXSYMBOLS]; np++)
                    520:                        if (np->n_value == 0)
                    521:                                fprintf(stderr, "%a: can't find symbol: %s\n",
                    522:                                        np->n_name);
                    523:                if (namelist[0].n_value == -1)
                    524:                        prexit("%a: cannot read symbol file: %s\n", symf);
                    525:                for (i = 0; i < MAXSYMBOLS; i++)
                    526:                        info.kaddr[i] = (caddr_t)namelist[i].n_value;
                    527:                info.kaddr[aetext] = (caddr_t)( ((unsigned)info.kaddr[aetext] + 63) & ~63);
                    528:        }
                    529:        if (iflag) {
                    530:                readusers();
                    531:                ttyinit();
                    532:                if ((infofd = creat(infof, 0600)) < 0)
                    533:                        prexit("%a: cannot create info file\n");
                    534:                if ((i = write(infofd, &info, sizeof info)) != sizeof info) {
                    535:                        if (i == -1)
                    536:                                perror(0);
                    537:                        prexit("%a: cannot write info file: %d\n", i);
                    538:                }
                    539:                close(infofd);
                    540:        }
                    541:        lseek(kmem, (long)info.kaddr[aswapdev], 0);
                    542:        read(kmem, &swapdev, sizeof(swapdev) );
                    543:        lseek(kmem, (long)info.kaddr[aswplo], 0);
                    544:        read(kmem, &swplo, sizeof(swplo) );
                    545:        lseek(kmem, (long)info.kaddr[answap], 0);
                    546:        read(kmem, &nswap, sizeof(nswap) );
                    547:        lseek(kmem, (long)info.kaddr[anproc], 0);
                    548:        read(kmem, &nproc, sizeof(nproc) );
                    549:        lseek(kmem, (long)info.kaddr[antext], 0);
                    550:        read(kmem, &ntext, sizeof(ntext) );
                    551:        lseek(kmem, (long)info.kaddr[anbuf], 0);
                    552:        read(kmem, &nbuf, sizeof(nbuf) );
                    553:        lseek(kmem, (long)info.kaddr[abuf], 0);
                    554:        read(kmem, &buf, sizeof(buf) );
                    555:        lseek(kmem, (long)info.kaddr[answbuf], 0);
                    556:        read(kmem, &nswbuf, sizeof(nswbuf) );
                    557:        lseek(kmem, (long)info.kaddr[aswbuf], 0);
                    558:        read(kmem, &swbuf, sizeof(swbuf) );
                    559:        lseek(kmem, (long)info.kaddr[aninode], 0);
                    560:        read(kmem, &ninode, sizeof(ninode) );
                    561:        lseek(kmem, (long)info.kaddr[ainode], 0);
                    562:        read(kmem, &inode, sizeof(inode) );
                    563:        lseek(kmem, (long)info.kaddr[ahz], 0);
                    564:        read(kmem, &hz, sizeof(hz) );
                    565:        lseek(kmem, (long)info.kaddr[aproc], 0);
                    566:        read(kmem, &kproc, sizeof(kproc));
                    567:        lseek(kmem, (long)info.kaddr[atext], 0);
                    568:        read(kmem, &ktext, sizeof(ktext));
                    569:        proc = (struct proc *)getcore(nproc * sizeof(struct proc));
                    570:        text = (struct text *)getcore(ntext * sizeof(struct text));
                    571:        if (puids != &uids[0] && uids[0].nm_int != myuid)
                    572:                usersetup();
                    573:        if (!select) {
                    574:                mypid = getpid();
                    575:                (puids++)->nm_int = myuid;
                    576:                nxflag++;
                    577:                select++;
                    578:        }
                    579:        ttysetup();
                    580:        topmem = 0;
                    581:        do {
                    582:                heading = 0;                    /* reset heading flag (for repeat) */
                    583:                core = coreinit = 0;            /* reset core flag (for repeat) */
                    584:                lseek(kmem, (long)kproc, 0);
                    585:                read(kmem, proc, nproc * sizeof(struct proc));
                    586:                lseek(kmem, (long)ktext, 0);
                    587:                read(kmem, text, ntext * sizeof(struct text));
                    588:                needed();
                    589:                mktree();
                    590:                action (plist, 0);
                    591:                printf("%d processes (%dkb), %d busy (%dkb), %d loaded (%dkb)\n",
                    592:                        ntotal, (ctob(ktotal) + 1023) / 1024,
                    593:                        nbusy, (ctob(kbusy) + 1023) / 1024,
                    594:                        nloaded, (ctob(kloaded) + 1023) / 1024);
                    595:                fflush(stdout);
                    596:        } while (rflag && sleep(rflag) == 0);
                    597:        exit(0);
                    598: }
                    599: 
                    600: /* read the passwd file and fill in the user name arrays */
                    601: readusers()
                    602: {
                    603:        register struct passwd *pw;
                    604:        struct passwd *getpwent();
                    605: 
                    606:        while((pw = getpwent()) != 0) {
                    607:                if(info.unames[pw->pw_uid][0] == '\0')
                    608:                        strcpyn(info.unames[pw->pw_uid], pw->pw_name, UNAMELENGTH);
                    609:        }
                    610:        endpwent();
                    611: }
                    612: 
                    613: /* check for specified user names */
                    614: 
                    615: usersetup()
                    616: {
                    617:        register int i;
                    618:        register union numptr *ip;
                    619: 
                    620:        for (ip = uids; ip < puids; ip++) {
                    621:                for (i = 0; i < MAXUSERS; i++)
                    622:                        if (equalu(ip->nm_ptr, info.unames[i]))
                    623:                                goto cont2;
                    624:                prexit("%a: unknown user: %s\n", ip->nm_ptr);
                    625:        cont2:
                    626:                ip->nm_int = i;
                    627:        }
                    628: }
                    629: 
                    630: /* compare a fixed length user name */
                    631: 
                    632: equalu(u1, u2)
                    633: register char *u1, *u2;
                    634: {
                    635:        register int i = 0;
                    636: 
                    637:        while (*u1++ == *u2)
                    638:                if (!*u2++ || ++i == UNAMELENGTH)
                    639:                        return 1;
                    640:        return 0;
                    641: }
                    642: 
                    643: /*
                    644:  * Initialize the tty part of the info structure
                    645:  */
                    646: ttyinit()
                    647: {
                    648:        struct direct dir;
                    649:        struct stat sbuf;
                    650:        int fd;
                    651:        register struct ttyline *lp = info.ttyline;
                    652: 
                    653:        if ((fd = open("/dev", 0)) < 0)
                    654:                prexit("%a: can't open /dev\n");
                    655:        chdir("/dev");
                    656:        while (read(fd, (char *)&dir, sizeof(dir)) == sizeof(dir)) {
                    657:                if (dir.d_ino == 0 ||
                    658:                    strncmp("tty", dir.d_name, 3) != 0 &&
                    659:                    strcmp("console", dir.d_name) != 0)
                    660:                        continue;
                    661:                if (dir.d_name[sizeof("tty") - 1] == 'C')
                    662:                        continue;
                    663:                if (lp >= &info.ttyline[MAXTTYS])
                    664:                        prexit("%a: too many ttys in /dev\n");
                    665:                if (dir.d_name[0] == 'c') {
                    666:                        lp->l_name[0] = 'c';
                    667:                        lp->l_name[1] = 'o';
                    668:                } else {
                    669:                        lp->l_name[0] = dir.d_name[3];
                    670:                        lp->l_name[1] = dir.d_name[4];
                    671:                }
                    672:                stat(dir.d_name, &sbuf);
                    673:                lp->l_dev = sbuf.st_rdev;
                    674:                lseek(kmem, (long)&cswitch[major(sbuf.st_rdev)].d_ttys, 0);
                    675:                read(kmem, (char *)&lp->l_addr, sizeof(lp->l_addr));
                    676:                lp->l_addr += minor(sbuf.st_rdev);
                    677:                lp++;
                    678:        }
                    679:        close(fd);
                    680: }
                    681: ttysetup()
                    682: {
                    683:        register struct ttyline *lp;
                    684:        register char *cp;
                    685:        union ttyptr *tp;
                    686:        struct tty tty;
                    687: 
                    688:        for (lp = info.ttyline; lp->l_name[0]; lp++) {
                    689:                lseek(kmem, (long)lp->l_addr, 0);
                    690:                if (read(kmem, &tty, sizeof tty) != sizeof tty)
                    691:                        prexit("%a: read error in kmem\n");
                    692:                lp->l_pgrp = tty.t_pgrp;
                    693:                if (Tflag)
                    694:                        printf("tty%-.2s: dev:%2d,%2d addr:%6x, rawq:%4d, canq:%d, outq:%4d, pgrp:%5d\n",
                    695:                                lp->l_name, major(lp->l_dev), minor(lp->l_dev),
                    696:                                ABS(lp->l_addr), tty.t_rawq.c_cc,
                    697:                                tty.t_canq.c_cc, tty.t_outq.c_cc,
                    698:                                tty.t_pgrp);
                    699:        }
                    700: #ifdef CHAOS
                    701:        mkchttys(lp);
                    702: #endif
                    703:        /* now fix up specified ttys */
                    704: 
                    705:        for (tp = &ttys[0]; tp < pttys; tp++) {
                    706:                for (lp = info.ttyline; lp->l_name[0]; lp++)
                    707:                        if (strcmpn(tp->ty_ptr, lp->l_name, 2) == 0) {
                    708:                                tp->ty_line = lp;
                    709:                                goto cont2;
                    710:                        }
                    711:                prexit("%a: unknown tty name: %c\n", tp->ty_ptr);
                    712:        cont2:;
                    713:        }
                    714: }
                    715: 
                    716: /*
                    717:  * Determine which procs are needed for the printout
                    718:  * and add these to a list of needed processes (plist)
                    719:  */
                    720: needed()
                    721: {
                    722:        register struct proc *p, *pp;
                    723:        register struct text *tp;
                    724:        struct ttyline *lp;
                    725:        int ok;
                    726: 
                    727:        plist = 0;
                    728:        nswapped = ntotal = nbusy = nloaded = 0;
                    729:        kswapped = ktotal = kbusy = kloaded = 0;
                    730: 
                    731:        for (tp = text; tp < text + ntext; tp++)
                    732:                if (tp->x_count) {
                    733:                        ktotal += tp->x_size;
                    734:                        if (!(tp->x_ccount))
                    735:                                kswapped += tp->x_size;
                    736:                }
                    737: 
                    738:        for (p = proc; p < proc + nproc; p++) {
                    739:                if (!p->p_stat)
                    740:                        continue;
                    741:                if (p->p_textp)
                    742:                        p->p_textp = &text[p->p_textp - ktext];
                    743:                if (p->p_pptr) {
                    744:                        p->p_pptr = &proc[p->p_pptr - kproc];
                    745:                        if (p->p_pptr < proc || p->p_pptr >= &proc[nproc]) {
                    746:                                fprintf(stderr, "proc %d bad pptr\n", p->p_pid);
                    747:                                p->p_pptr = proc;
                    748:                        }
                    749:                } else
                    750:                        p->p_pptr = proc;
                    751:        }
                    752:        for (p = &proc[0]; p < &proc[nproc]; p++) {
                    753:                if (!p->p_stat)
                    754:                        continue;
                    755:                ntotal++;
                    756:                ktotal += procsize(p);
                    757:                if (p->p_flag != SZOMB)
                    758:                        if (p->p_flag & SLOAD) {
                    759:                                nloaded++;
                    760:                                kloaded += procsize(p);
                    761:                                if ((tp = p->p_textp) && tp->x_count) {
                    762:                                        tp->x_count = 0;
                    763:                                        kloaded += tp->x_size;
                    764:                                }
                    765:                        } else {
                    766:                                nswapped++;
                    767:                                kswapped += procsize(p);
                    768:                        }
                    769:                ok = FALSE;
                    770:                if (p->p_stat == SRUN ||
                    771:                    p->p_stat == SSLEEP && (p->p_pri < PZERO && p->p_pid > MSPID)) {
                    772:                        nbusy++;
                    773:                        kbusy += procsize(p);
                    774:                        if ((tp = p->p_textp) && tp->x_ccount) {
                    775:                                tp->x_ccount = 0;
                    776:                                kbusy += tp->x_size;
                    777:                        }
                    778:                        if (Bflag)
                    779:                                ok = TRUE;
                    780:                }
                    781:                if (nflag)
                    782:                        continue;
                    783:                if (zflag && p->p_stat == SZOMB)
                    784:                        ok = TRUE;
                    785:                if (sflag && p->p_stat == SSTOP)
                    786:                        ok = TRUE;
                    787:                if (select == 0 && mypid && p->p_pid == mypid)
                    788:                        continue;
                    789:                if (p->p_pgrp == 0)
                    790:                        if (xflag)
                    791:                                ok = TRUE;
                    792:                        else if (nxflag)
                    793:                                continue;
                    794:                if (dflag && p->p_pgrp != 0 && (p->p_flag & SDETACH) != 0)
                    795:                        ok = TRUE;
                    796:                if (aflag && xflag && p->p_pgrp != 0 && (p->p_flag & SDETACH) == 0 &&
                    797:                    p->p_pptr == &proc[1])
                    798:                        ok = TRUE;
                    799:                if (puids != uids) {
                    800:                        register union numptr *ip;
                    801: 
                    802:                        for (pp = p; pp > &proc[1]; pp = pp->p_pptr)
                    803:                                for (ip = uids; ip < puids; ip++)
                    804:                                        if ((pp->p_uid & 0377) == ip->nm_int){
                    805:                                                ok = TRUE;
                    806:                                                goto uidok;
                    807:                                        }
                    808:                }
                    809:        uidok:
                    810:                if (pgrps != grps) {
                    811:                        register union numptr *ip;
                    812: 
                    813:                        for (pp = p; pp > &proc[1]; pp = pp->p_pptr)
                    814:                                for (ip = grps; ip < pgrps; ip++)
                    815:                                        if (pp->p_pgrp == ip->nm_int) {
                    816:                                                ok = TRUE;
                    817:                                                goto pgrpok;
                    818:                                        }
                    819:                }
                    820:        pgrpok:
                    821:                if (ppids != pids) {
                    822:                        register union numptr *ip;
                    823: 
                    824:                        for (ip = pids; ip < ppids; ip++)
                    825:                                if (ip->nm_int == p->p_pid) {
                    826:                                        ok = TRUE;
                    827:                                        goto procok;
                    828:                                }
                    829:                }
                    830:        procok:
                    831:                if (select && pttys == ttys && !fflag && !bflag && !ok)
                    832:                        continue;
                    833:                if (getu(p) == 0) {
                    834:                        static struct procinfo  fakep = {"--no upage--", &notty, 0};
                    835: 
                    836:                        if (select && !ok)
                    837:                                continue;
                    838:                        pinfo(p) = &fakep;
                    839:                        goto putonlist;
                    840:                }
                    841:                if (pttys != ttys && p->p_pgrp != 0) {
                    842:                        union ttyptr *ip;
                    843: 
                    844:                        for (ip = ttys; ip < pttys; ip++)
                    845:                                if (p->p_pgrp && p->p_pgrp == ip->ty_line->l_pgrp ||
                    846:                                    p->p_stat == SSLEEP &&
                    847:                                    p->p_wchan >= (char *)ip->ty_line->l_addr &&
                    848:                                    p->p_wchan < (char *)ip->ty_line->l_addr +
                    849:                                                 sizeof (struct tty) ||
                    850:                                    u.u_ttyd == ip->ty_line->l_dev) {
                    851:                                        ok = TRUE;
                    852:                                        break;
                    853:                                }
                    854:                }
                    855:                if (p->p_pgrp == 0)
                    856:                        lp = &notty;
                    857:                else {
                    858:                        for (lp = info.ttyline; lp->l_name[0] != 0; lp++)
                    859:                                if (lp->l_dev == u.u_ttyd)
                    860:                                        break;
                    861:                        if (lp->l_name[0] == 0)
                    862:                                lp = &notty;
                    863:                        else if (p->p_pptr != &proc[1]) {
                    864:                                if (fflag && p->p_pgrp == lp->l_pgrp)
                    865:                                        ok = TRUE;
                    866:                                if (bflag && p->p_pgrp != lp->l_pgrp &&
                    867:                                    (p->p_flag & SDETACH) == 0 &&
                    868:                                    p->p_stat != SSTOP)
                    869:                                        ok = TRUE;
                    870:                        }
                    871:                }
                    872:                if (select && !ok)
                    873:                        continue;
                    874:                pinfo(p) = (struct procinfo *)getcore(sizeof (struct procinfo));
                    875:                pinfo(p)->pi_time = u.u_vm.vm_utime + u.u_vm.vm_stime;
                    876:                pinfo(p)->pi_tty = lp;
                    877:                pinfo(p)->pi_cmd = getcmd(p);
                    878:        putonlist:
                    879:        /* we have a needed proc! */
                    880: 
                    881:                p->p_next = plist;
                    882:                plist = p;
                    883:                p->p_son = p->p_bro = 0;
                    884:        }
                    885: }
                    886: /*
                    887:  * mktree - sort the needed processes by subtree and at the top by user
                    888:  */
                    889: mktree()
                    890: {
                    891:        register struct proc *p, *pp, *lp;
                    892:        struct proc *op;
                    893:        struct proc proot;
                    894: 
                    895:        proot.p_bro = 0;
                    896: 
                    897:        for (p = plist; p; p = p->p_next) {     /* for all needed processes */
                    898:                if (p->p_pptr > &proc[1]) {
                    899:                        for (pp = plist; pp; pp = pp->p_next)
                    900:                                if (pp == p->p_pptr) {  /* if my parent */
                    901:                                        if (lp = pp->p_son) {   /* if siblings */
                    902:                                                for (op = 0; lp && lp->p_pid <
                    903:                                                        p->p_pid;
                    904:                                                        lp = (op = lp)->p_bro)
                    905:                                                        ;
                    906:                                                if (op) {
                    907:                                                        p->p_bro = lp;
                    908:                                                        op->p_bro = p;
                    909:                                                        break;
                    910:                                                }
                    911:                                        }
                    912:                                        p->p_bro = lp;  /* here if first or only */
                    913:                                        pp->p_son = p;
                    914:                                        break;
                    915:                                }
                    916:                        if (pp)         /* if we found the parent */
                    917:                                continue;
                    918:                }
                    919: 
                    920:                /* we have a top level process, sort into top level list */
                    921: 
                    922:                for (pp = (lp = &proot)->p_bro; pp; pp = (lp = pp)->p_bro)
                    923:                        if ((p->p_uid & 0377) < (pp->p_uid & 0377) ||
                    924:                                (p->p_uid & 0377) == (pp->p_uid & 0377) &&
                    925:                                p->p_pid < pp->p_pid)
                    926:                                break;
                    927:                p->p_bro = lp->p_bro;
                    928:                lp->p_bro = p;
                    929:        }
                    930:        plist = proot.p_bro;
                    931: }
                    932: 
                    933: action(p, md)
                    934: register struct proc *p;
                    935: register int md;
                    936: {
                    937: 
                    938:        if (p) {
                    939:                printp(p, md);
                    940:                if (p->p_son)
                    941:                        action(p->p_son, md+1);
                    942:                if (p->p_bro)
                    943:                        action(p->p_bro, md);
                    944:        }
                    945: }
                    946: 
                    947: /*
                    948:  * Pretty print the output according to the switches.
                    949:  */
                    950: printp(p, md)
                    951: register struct proc *p;
                    952: {
                    953:        register char *cp, *cp1;
                    954:        char    stat[10];
                    955:        static int lastuid;
                    956:        static char     *statnames[] = {"Unk ", "Wait", "Wait", "Run ",
                    957:                                "Init", "Exit", "Stop"};
                    958: 
                    959:        if (!heading) {
                    960:                heading++;
                    961:                printf("Ty User     ");
                    962:                if (lflag) {
                    963:                        printf("Stat");
                    964:                        if (vflag) printf(" Flgs Nice Pri ");
                    965:                        else printf(" ");
                    966:                        printf("Memory-kb  Time Wait?  ");
                    967:                        }
                    968:                if (Aflag)
                    969:                        printf("Address Proc.  Clock Alarm ");
                    970:                if (Sflag)
                    971:                        printf("Size  ");
                    972:                if (Gflag)
                    973:                        printf("Group ");
                    974:                printf("Proc#  Command\n");
                    975:        }
                    976:        printf("%.2s%c", pinfo(p)->pi_tty->l_name,
                    977:                p->p_pgrp == 0 ? ' ' :
                    978:                p->p_flag & SDETACH ? '_' :
                    979:                p->p_pgrp == pinfo(p)->pi_tty->l_pgrp ? '.' :
                    980:                ' ');
                    981: 
                    982:        if (md == 0) {
                    983:                lastuid = p->p_uid & 0377;
                    984:                cp = info.unames[lastuid];
                    985:                if (*cp)
                    986:                        printf("%-8.8s ", cp);
                    987:                else
                    988:                        printf("user%-4.4d ", lastuid);
                    989:        } else {
                    990:                if (md > 8)
                    991:                        md = 8;
                    992:                printf("%*s*", md, "");
                    993:                if ((p->p_uid & 0377) != lastuid) {     /* setuid process! */
                    994:                        lastuid = p->p_uid & 0377;
                    995:                        cp = info.unames[lastuid];
                    996:                } else
                    997:                        cp = "";
                    998:                md = 8 - md;
                    999:                printf("%-*.*s", md, md, cp);
                   1000:        }
                   1001:        if (lflag) {
                   1002:                cp = statnames[p->p_stat];
                   1003:                if (p->p_flag&SLOAD) {
                   1004:                        for (cp1 = stat; *cp1 = *cp; cp1++, cp++)
                   1005:                                if (*cp >= 'a' && *cp <= 'z')
                   1006:                                        *cp1 -= 'a' - 'A';
                   1007:                        cp = stat;
                   1008:                        }
                   1009:                printf("%-4.4s ", cp);
                   1010:                if (vflag) {
                   1011:                        cp = stat;
                   1012:                        if (p->p_flag & SSYS) *cp++ = 'U';
                   1013:                        if (p->p_flag&SLOCK) *cp++ = 'L';
                   1014:                        if (p->p_flag&STRC) *cp++ = 'T';
                   1015:                        if (p->p_flag&SWTED) *cp++ = 'W';
                   1016:                        if (p->p_flag&SSWAP) *cp++ = 'S';
                   1017:                        while(cp < &stat[5]) *cp++ = ' ';
                   1018:                        *cp = 0;
                   1019:                        printf("%-4.4s ",stat);
                   1020:                        if (p->p_nice != NZERO)
                   1021:                                printf("%4d", p->p_nice - NZERO);
                   1022:                        else
                   1023:                                printf("    ");
                   1024:                        if (p->p_stat != SZOMB)
                   1025:                                printf("%4d ", p->p_pri);
                   1026:                        else
                   1027:                                printf("     ");
                   1028:                }
                   1029:                if (p->p_stat != SZOMB) {
                   1030:                        printf("%4d", msize(procsize(p)) );
                   1031:                        if (p->p_textp)
                   1032:                                printf("+%4d ", msize(p->p_textp->x_size));
                   1033:                        else
                   1034:                                printf("      ");
                   1035:                        prcpu(pinfo(p)->pi_time);
                   1036:                } else
                   1037:                        printf("                ");
                   1038:                if (p->p_stat != SZOMB && p->p_stat != SRUN && p->p_stat != SSTOP)
                   1039:                        if (!Wflag && (cp = waitingfor(p)))
                   1040:                                printf("%-6.6s ", cp);
                   1041:                        else printf("%6x ", ABS((int)p->p_wchan));
                   1042:                else printf("       ");
                   1043:        }
                   1044:        if (Aflag)
                   1045:                printf("%6x %6x %6d%6d ", p->p_addr,
                   1046:                        (p - proc) * sizeof (struct proc) + info.kaddr[aproc],
                   1047:                        p->p_time, p->p_clktim);
                   1048:        if (Sflag)
                   1049:                printf("%5x ", procsize(p) );
                   1050:        if (Gflag)
                   1051:                printf("%5D ", p->p_pgrp);
                   1052:        printf("%5D  ", p->p_pid);
                   1053:        if (wflag)
                   1054:                printf("%s\n", pinfo(p)->pi_cmd);
                   1055:        else
                   1056:                printf("%-.*s\n", arglength, pinfo(p)->pi_cmd);
                   1057: }
                   1058: 
                   1059: /* print cpu time */
                   1060: 
                   1061: prcpu(time)
                   1062: long time;
                   1063: {
                   1064:        register unsigned i;
                   1065: 
                   1066:        if (time < 0)
                   1067:                printf(" ---- ");
                   1068:        else if (time < (long)hz * 60 * 10)             /* less than 10 minutes */
                   1069:                printf("%3d.%1d ",
                   1070:                        (int)(time / hz),
                   1071:                        (int)(time % hz / (hz / 10)));
                   1072:        else if (time < (long)hz * 60 * 60 * 10)/* less than 10 hours */
                   1073:                printf("%3d M ",
                   1074:                        (int)((time + (hz * 60) / 2) / (hz * 60)));
                   1075:        else {
                   1076:                i = (time + ((long)hz * 60 * 60) / 2) /
                   1077:                                        ((long)hz * 60 * 60);
                   1078:                if (i < 1000)
                   1079:                        printf("%3d H ", i);
                   1080:                else
                   1081:                        printf(" ---- ");
                   1082:        }
                   1083: }
                   1084: /* Determine what a process is waiting for and describe it. */
                   1085: 
                   1086: char *
                   1087: waitingfor(p)
                   1088: register struct proc *p;
                   1089: {
                   1090:        register caddr_t w;
                   1091:        register struct ttyline *lp;
                   1092:        register char *cp;
                   1093: 
                   1094:        w = p->p_wchan;
                   1095:        if (w == (caddr_t)0)
                   1096:                return "null";
                   1097:        if (w >= (char *)kproc && w < (char *)(kproc + nproc))
                   1098:                return "child";
                   1099:        if (w >= (char *)swbuf && w < (char *)(swbuf + nswbuf))
                   1100:                return "swap";
                   1101:        if (w == info.kaddr[arswbuf])
                   1102:                return "rswap";
                   1103:        if (w >= (char *)buf && w < (char *)(buf + nbuf))
                   1104:                return "diskio";
                   1105:        if (w >= info.kaddr[afile] && w < info.kaddr[afile] + sizeof(struct file) * nfile)
                   1106:                return "file";
                   1107:        if (w >= (char *)inode && w < (char *)(inode + ninode))
                   1108:                switch((w - (char *)inode) % sizeof(struct inode)) {
                   1109:                case 1:
                   1110:                        return "wpipe";
                   1111:                case 2:
                   1112:                        return "rpipe";
                   1113:                case 3:
                   1114:                        return "mutex";
                   1115:                case (int)&((struct inode *)0)->i_un.i_group.g_datq:
                   1116:                        return "rmux";
                   1117:                default:
                   1118:                        return "inode";
                   1119:                }
                   1120:        if (w == info.kaddr[achtbuf])
                   1121:                return "tapecn";
                   1122:        if (w == info.kaddr[ahpbuf])
                   1123:                return "rpdisk";
                   1124:        if (w == info.kaddr[ark7])
                   1125:                return "rkdisk";
                   1126:        if (w == info.kaddr[arhtbuf])
                   1127:                return "tapeio";
                   1128:        if (w == info.kaddr[alpdt])
                   1129:                return "printr";
                   1130:        if (w == info.kaddr[albolt])
                   1131:                return "lbolt";
                   1132:        if (w == info.kaddr[arunin])
                   1133:                return "runin";
                   1134:        if (w == info.kaddr[arunout])
                   1135:                return "runout";
                   1136:        if (w == info.kaddr[atout])
                   1137:                return "sleep";
                   1138:        if (w == info.kaddr[aipc])
                   1139:                return "ptrace";
                   1140:        if (w == info.kaddr[abfreeli])
                   1141:                return "buffer";
                   1142:        if (w == info.kaddr[amaplock])
                   1143:                return "ubmap";
                   1144:        if (w == info.kaddr[au])
                   1145:                return "pause";
                   1146:        if (w == info.kaddr[achrfclist])
                   1147:                return "chrfc";
                   1148:        for (lp = info.ttyline; lp->l_name[0]; lp++)
                   1149:                if (w >= (char *)lp->l_addr && w < (char *)lp->l_addr + sizeof (struct tty)) {
                   1150: #define TTY0 ((struct tty *)0)
                   1151:                        switch(w - (char *)lp->l_addr) {
                   1152:                        case (int)&TTY0->t_rawq:
                   1153:                                cp = "rtty??";
                   1154:                                break;
                   1155:                        case (int)&TTY0->t_outq:
                   1156:                                cp = "wtty??";
                   1157:                                break;
                   1158:                        case (int)&TTY0->t_state:
                   1159:                                cp = "otty??";
                   1160:                                break;
                   1161:                        default:
                   1162:                                cp = "?tty??";
                   1163:                        }
                   1164:                        cp[4] = lp->l_name[0];
                   1165:                        cp[5] = lp->l_name[1];
                   1166:                        return cp;
                   1167:                }
                   1168:        return 0;
                   1169: }
                   1170: 
                   1171: getu(mproc)
                   1172: register struct proc *mproc;
                   1173: {
                   1174:        struct pte *pteaddr, apte;
                   1175:        register int i;
                   1176:        int ncl, size;
                   1177: 
                   1178:        size = Sflag ? ctob(UPAGES) : sizeof (struct user);
                   1179:        if ((mproc->p_flag & SLOAD) == 0) {
                   1180:                lseek(swap, (long)ctob(mproc->p_swaddr), 0);
                   1181:                if (read(swap, (char *)&user.user, size) != size) {
                   1182:                        fprintf(stderr, "%a: cant read u for pid %d from %s\n",
                   1183:                            mproc->p_pid, swapf);
                   1184:                        return (0);
                   1185:                }
                   1186:                return (1);
                   1187:        }
                   1188:        pteaddr = &Usrptmap[btokmx(mproc->p_p0br) + mproc->p_szpt - 1];
                   1189:        lseek(kmem, (long)(mflag ? ABS(pteaddr) : (int)pteaddr), 0);
                   1190:        if (read(kmem, (char *)&apte, sizeof(apte)) != sizeof(apte)) {
                   1191:                printf("%a: cant read indir pte to get u for pid %d from %s\n",
                   1192:                    mproc->p_pid, swapf);
                   1193:                return (0);
                   1194:        }
                   1195:        lseek(mem, (long)
                   1196:            (ctob(apte.pg_pfnum+1) - (UPAGES+MAXARGPG) * sizeof (struct pte)),
                   1197:            0);
                   1198:        if (read(mem, (char *)pagetable, sizeof(pagetable)) != sizeof(pagetable)) {
                   1199:                printf("%a: cant read page table for u of pid %d from %s\n",
                   1200:                    mproc->p_pid, swapf);
                   1201:                return (0);
                   1202:        }
                   1203:        ncl = (size + NBPG*CLSIZE - 1) / (NBPG*CLSIZE);
                   1204:        while (--ncl >= 0) {
                   1205:                i = ncl * CLSIZE;
                   1206:                lseek(mem, (long)ctob(pagetable[MAXARGPG+i].pg_pfnum), 0);
                   1207:                if (read(mem, user.upages[i], CLSIZE*NBPG) != CLSIZE*NBPG) {
                   1208:                        printf("%a: cant read page %d of u of pid %d from %s\n",
                   1209:                            pagetable[MAXARGPG+i].pg_pfnum, mproc->p_pid, memf);
                   1210:                        return(0);
                   1211:                }
                   1212:        }
                   1213:        return (1);
                   1214: }
                   1215: char *
                   1216: getcmd(p)
                   1217: register struct proc *p;
                   1218: {
                   1219:        struct pte apte;
                   1220:        char argbuf[MAXARGPG * NBPG], *argptr;
                   1221:        register int *ip;
                   1222:        register char *cp, *cp1;
                   1223:        int cc, nbad, i;
                   1224: 
                   1225:        if (p->p_stat == SZOMB)
                   1226:                return "--Defunct--";
                   1227:        if ((p->p_flag&SLOAD) == 0 && Fflag)
                   1228:                return "--Swapped--";
                   1229:        if (p->p_flag & SSYS)
                   1230:                return p->p_pid == 0 ? "UNIX Swapper" :
                   1231:                        p->p_pid == 2 ? "UNIX Pager" : "UNIX";
                   1232:        for (i = 0; i < MAXARGPG; i++) {
                   1233:                argptr = &argbuf[(MAXARGPG - 1 - i) * NBPG];
                   1234:                apte = pagetable[MAXARGPG - 1 - i];
                   1235:                if ((p->p_flag & SLOAD) && apte.pg_fod == 0 && apte.pg_pfnum ) {
                   1236:                        lseek(mem, (long)ctob(apte.pg_pfnum), 0);
                   1237:                        if (read(mem, argptr, NBPG) != NBPG)
                   1238:                                return "---Mem read error (args)---";
                   1239:                } else if (Fflag)
                   1240:                        goto cheap;
                   1241:                else {
                   1242:                        lseek(swap, (long)ctob(u.u_smap.dm_map[0] + DMMIN - 1 - i), 0);
                   1243:                        if (read(swap, argptr, NBPG) != NBPG)
                   1244:                                return "---Swap read error (args)---";
                   1245:                }
                   1246:                /* Here block of stack is at argptr */
                   1247:                ip = (int *)&argptr[NBPG];
                   1248:                if (i == 0) {
                   1249:                        *--ip = 0;
                   1250:                        ip--;
                   1251:                }
                   1252:                while (ip > (int *)argptr && *--ip != 0)
                   1253:                        ;
                   1254:                if (ip > (int *)argptr || *ip == 0)
                   1255:                        break;
                   1256:        }
                   1257:        if (i >= MAXARGPG) {
                   1258: cheap:
                   1259:                argbuf[0] = '(';
                   1260:                strncpy(&argbuf[1], u.u_comm, sizeof(u.u_comm));
                   1261:                strcat(argbuf, ")");
                   1262:                return store(argbuf);
                   1263:        }
                   1264:        cp = (char *)(ip + 1);
                   1265:        if (*cp == '\0')
                   1266:                cp++;
                   1267:        nbad = 0;
                   1268:        for (cp1 = cp; cp1 < &argbuf[MAXARGPG*NBPG]; cp1++) {
                   1269:                cc = *cp1 & 0177;
                   1270:                if (cc == 0)
                   1271:                        *cp1 = ' ';
                   1272:                else if (cc < ' ' || cc == 0177) {
                   1273:                        if (++nbad >= 5) {
                   1274:                                *cp1++ = ' ';
                   1275:                                break;
                   1276:                        }
                   1277:                        *cp1 = '?';
                   1278:                } else if (!eflag && cc == '=') {
                   1279:                        *cp1 = 0;
                   1280:                        while (cp1 > cp && *--cp1 != ' ')
                   1281:                                *cp1 = 0;
                   1282:                        break;
                   1283:                }
                   1284:        }
                   1285:        while (*--cp1 == ' ')
                   1286:                *cp1 = 0;
                   1287:        if (!wflag && &cp[arglength] < (char *)&argbuf[MAXARGPG*NBPG - 1])
                   1288:                cp[arglength] = 0;
                   1289:        return store(cp);
                   1290: }
                   1291: 
                   1292: /*
                   1293:  * Store a string in core for later use.
                   1294:  */
                   1295: char *
                   1296: store(cp)
                   1297: char *cp;
                   1298: {
                   1299:        register char *src, *dst, *svdst;
                   1300: 
                   1301:        src = cp;
                   1302:        while (*src++);
                   1303:        svdst = getcore(src - cp);
                   1304:        dst = svdst;
                   1305:        src = cp;
                   1306:        while (*dst++ = *src++);
                   1307:        return(svdst);
                   1308: }
                   1309: 
                   1310: /*
                   1311:  * Allocate and return a pointer to the asked for amount of core
                   1312:  */
                   1313: char *
                   1314: getcore(cnt)
                   1315: register int cnt;
                   1316: {
                   1317:        static char *corep;
                   1318:        register char *ip;
                   1319:        register int incr;
                   1320:        char *sbrk();
                   1321: 
                   1322:        if (cnt > core) {
                   1323:                if (coreinit == 0) {
                   1324:                        coreinit++;
                   1325:                        if (topmem)
                   1326:                                brk(topmem);    /* after repeat!! */
                   1327:                        else
                   1328:                                topmem = sbrk(0);
                   1329:                        corep = topmem;
                   1330:                }
                   1331:                incr = cnt > 4096 ? cnt : 4096;
                   1332:                if (sbrk(incr) == 0)
                   1333:                        prexit("%a: out of memory!\n");
                   1334:                core += incr;
                   1335:        }
                   1336:        ip = corep;
                   1337:        core -= cnt;
                   1338:        corep += cnt;
                   1339:        return(ip);
                   1340: }
                   1341: #ifdef CHAOS
                   1342: #include "chunix/chsys.h"
                   1343: #include <chaos/chaos.h>
                   1344: 
                   1345: mkchttys(lp)
                   1346: register struct ttyline *lp;
                   1347: {
                   1348:        register struct connection **cnp;
                   1349:        register int i;
                   1350:        struct tty tty;
                   1351:        struct connection *Chconntab[CHNCONNS];
                   1352:        struct connection conn;
                   1353: 
                   1354:        lseek(kmem, (long)info.kaddr[aChconntab], 0);
                   1355:        read(kmem, (char *)Chconntab, sizeof(Chconntab));
                   1356:        for (i = 0, cnp = Chconntab; cnp < &Chconntab[CHNCONNS]; i++, cnp++) {
                   1357:                if (!*cnp)
                   1358:                        continue;
                   1359:                lseek(kmem, (long)*cnp, 0);
                   1360:                read(kmem, (char *)&conn, sizeof(conn));
                   1361:                if ((conn.cn_flags & CHTTY) == 0)
                   1362:                        continue;
                   1363:                lseek(kmem, (long)conn.cn_ttyp, 0);
                   1364:                read(kmem, (char *)&tty, sizeof(tty));
                   1365:                if (lp >= &info.ttyline[MAXTTYS])
                   1366:                        prexit("%a: too many ttys\n");
                   1367:                lp->l_addr = conn.cn_ttyp;
                   1368:                lp->l_pgrp = tty.t_pgrp;
                   1369:                lp->l_dev = tty.t_dev;
                   1370:                lp->l_name[0] = 'C';
                   1371:                lp->l_name[1] = i < 10 ? '0' + i :
                   1372:                        i - 10 <= 'z' - 'a' ? i - 10 + 'a' :
                   1373:                        i - 10 - ('z' - 'a') + 'A';
                   1374:                if (Tflag)
                   1375:                        printf("tty%-.2s: dev:%2d,%2d addr:%6x, rawq:%4d, canq:%d, outq:%4d, pgrp:%5d\n",
                   1376:                                lp->l_name, major(lp->l_dev), minor(lp->l_dev),
                   1377:                                ABS(lp->l_addr), tty.t_rawq.c_cc,
                   1378:                                tty.t_canq.c_cc, tty.t_outq.c_cc,
                   1379:                                tty.t_pgrp);
                   1380:                lp++;
                   1381:        }
                   1382: }
                   1383: #endif

unix.superglobalmegacorp.com

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