Annotation of 42BSD/undoc/sps/sps.c, revision 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.