Annotation of 43BSDReno/bin/adb/common_source/command.c, revision 1.1.1.1

1.1       root        1: #ifndef lint
                      2: static char sccsid[] = "@(#)command.c  5.4 (Berkeley) 9/26/89";
                      3: #endif
                      4: 
                      5: /*
                      6:  * adb - commands
                      7:  */
                      8: 
                      9: #include "defs.h"
                     10: #include <ctype.h>
                     11: #include <sys/wait.h>
                     12: #include <paths.h>
                     13: 
                     14: extern char BADEQ[];           /* "unexpected `='" */
                     15: extern char NOMATCH[];         /* "cannot locate value" */
                     16: extern char BADVAR[];          /* "bad variable" */
                     17: extern char BADCOM[];          /* "bad command" */
                     18: extern char NOFORK[];          /* "try again" */
                     19: 
                     20: /*
                     21:  * executing is used in main() to see if it is necessary to
                     22:  * delete any breakpoints that might have been set; if an
                     23:  * error occurs while a subprocess command is running, executing
                     24:  * will be set.
                     25:  */
                     26: int    executing;
                     27: 
                     28: /* lastcom remembers the previous command */
                     29: static struct {
                     30:        int     c;              /* the command */
                     31:        int     star;           /* true iff it was in alternate space */
                     32: } lastcom;
                     33: 
                     34: /*
                     35:  * Execute the given command buffer.
                     36:  * If defcom is nonzero, it is used as the default command.
                     37:  */
                     38: command(buf, defcom)
                     39:        char *buf;
                     40:        int defcom;
                     41: {
                     42: 
                     43:        lp = buf;
                     44:        do {
                     45:                cmds(defcom);
                     46:                flushbuf();
                     47:        } while (rdc() == ';');
                     48:        unreadc();
                     49: }
                     50: 
                     51: static
                     52: cmds(defcom)
                     53:        int defcom;
                     54: {
                     55:        int c;
                     56:        struct reglist *reg;
                     57: 
                     58:        /*
                     59:         * Pick up the optional first expression (`dot'),
                     60:         * then, if the next character is a comma, pick up
                     61:         * the second optional expression (`ecount').
                     62:         */
                     63:        if (gavedot = oexpr())
                     64:                ditto = dot = edot = expv;
                     65:        else
                     66:                edot = dot;     /* probably equal, but possibly truncating */
                     67:        if (rdc() == ',') {
                     68:                if (!oexpr())
                     69:                        error("count expected");
                     70:                gavecount = 1;
                     71:                ecount = expv;
                     72:        } else {
                     73:                gavecount = 0;
                     74:                ecount = 1;
                     75:                unreadc();
                     76:        }
                     77: 
                     78:        /*
                     79:         * Pick up the command.  If there is no command, do the
                     80:         * previous (or default) command, and if no dot was given,
                     81:         * use the `next' dot.
                     82:         */
                     83:        c = rdc();
                     84:        if (eol(c)) {
                     85:                if (defcom != 0) {
                     86:                        lastcom.c = defcom;
                     87:                        lastcom.star = 0;
                     88:                }
                     89:                if (!gavedot)
                     90:                        dot = inkdot(dotinc);
                     91:                unreadc();
                     92:        } else {
                     93:                lastcom.c = c;
                     94:                lastcom.star = 0;
                     95:        }
                     96: 
                     97:        switch (lastcom.c) {
                     98: 
                     99:        case '=':
                    100:                fmtcom(SP_NONE, 1);
                    101:                break;
                    102: 
                    103:        case '/':
                    104:                fmtcom(SP_DATA, 0);
                    105:                break;
                    106: 
                    107:        case '?':
                    108:                fmtcom(SP_INSTR, 0);
                    109:                break;
                    110: 
                    111:        case '>':
                    112:                lastcom.c = 0;
                    113:                if ((reg = reglookup()) != NULL) {
                    114:                        if (setreg(reg, edot))
                    115:                                prints("register write failed");
                    116:                        break;
                    117:                }
                    118:                if ((c = varlookup(rdc())) != -1)
                    119:                        var[c] = edot;
                    120:                else
                    121:                        error(BADVAR);
                    122:                break;
                    123: 
                    124:        case '!':
                    125:                lastcom.c = 0;
                    126:                shell();
                    127:                break;
                    128: 
                    129:        case '$':
                    130:                lastcom.c = 0;
                    131:                printtrace(nextchar());
                    132:                break;
                    133: 
                    134:        case ':':
                    135:                if (!executing) {
                    136:                        executing = 1;
                    137:                        subpcs(nextchar());
                    138:                        executing = 0;
                    139:                        lastcom.c = 0;
                    140:                }
                    141:                break;
                    142: 
                    143:        case 0:
                    144:                prints("adb\n");
                    145:                break;
                    146: 
                    147:        default:
                    148:                error(BADCOM);
                    149:                /* NOTREACHED */
                    150:        }
                    151: }
                    152: 
                    153: /*
                    154:  * Perform a format-based command (one in ? / or =).
                    155:  */
                    156: static
                    157: fmtcom(space, eqcom)
                    158:        int space, eqcom;
                    159: {
                    160:        /* special commands m, lL, wW do not operate in SP_NONE (`=') */
                    161:        void mcom(), lcom(), wcom();
                    162:        static struct fcmd {
                    163:                int     c;
                    164:                void    (*fn)();
                    165:        } fcmd[] = {
                    166:                { 'm', mcom },
                    167:                { 'l', lcom }, { 'L', lcom },
                    168:                { 'w', wcom }, { 'W', wcom },
                    169:                0
                    170:        };
                    171:        register struct fcmd *f;
                    172:        register int c;
                    173:        int ptype = space;
                    174:        static char stformat[LINELEN] = "X\"= \"^i";
                    175:        static char eqformat[LINELEN] = "z";
                    176: 
                    177:        /*
                    178:         * Are we operating in the alternate `star' space?
                    179:         */
                    180:        if (!eqcom) {
                    181:                if (rdc() == '*')
                    182:                        lastcom.star = 1;
                    183:                else
                    184:                        unreadc();
                    185:                if (lastcom.star) {
                    186:                        space |= SP_STAR;
                    187:                        /* print as data for instr, and vice versa */
                    188:                        ptype = (SP_DATA + SP_INSTR) - ptype;
                    189:                }
                    190:        }
                    191: 
                    192:        /*
                    193:         * Check for the special commands first.
                    194:         */
                    195:        c = rdc();
                    196:        for (f = fcmd; f->c; f++) {
                    197:                if (c == f->c) {
                    198:                        if (eqcom)
                    199:                                error(BADEQ);
                    200:                        (*f->fn)(space, ptype, isupper(c));
                    201:                        return;
                    202:                }
                    203:        }
                    204:        unreadc();
                    205:        getformat(eqcom ? eqformat : stformat, LINELEN);
                    206:        scanform(!eqcom, eqcom ? eqformat : stformat, space, ptype);
                    207: }
                    208: 
                    209: /*
                    210:  * Set a map (?m, /m commands).
                    211:  */
                    212: /* ARGSUSED */
                    213: static void
                    214: mcom(space, ptype, fullword)
                    215:        int space, ptype, fullword;
                    216: {
                    217:        register struct map *smap;
                    218:        register struct m1 *mm;
                    219:        char c;
                    220: 
                    221:        smap = space & SP_DATA ? &datmap : &txtmap;
                    222:        mm = space & SP_STAR ? &smap->m2 : &smap->m1;
                    223:        if (oexpr()) {
                    224:                mm->b = expv;
                    225:                if (oexpr()) {
                    226:                        mm->e = expv;
                    227:                        if (oexpr())
                    228:                                mm->f = expv;
                    229:                }
                    230:        }
                    231:        if ((c = rdc()) == '?')
                    232:                smap->ufd = symfile.fd;
                    233:        else if (c == '/')
                    234:                smap->ufd = corefile.fd;
                    235:        else
                    236:                unreadc();
                    237: }
                    238: 
                    239: /*
                    240:  * Locate a value (l, L commands).
                    241:  */
                    242: static void
                    243: lcom(space, ptype, fullword)
                    244:        int space, ptype, fullword;
                    245: {
                    246:        register expr_t val, mask;
                    247:        addr_t savdot;
                    248: 
                    249:        /* search for exp */
                    250:        savdot = dot;
                    251:        val = rexpr();
                    252:        if (oexpr())
                    253:                mask = expv;
                    254:        else
                    255:                mask = ~0L;
                    256:        if (fullword) {
                    257:                expr_t w;
                    258: 
                    259:                dotinc = sizeof(w);
                    260:                for (;;) {
                    261:                        (void) adbread(space, dot, &w, sizeof(w));
                    262:                        if (iserr() || (w & mask) == val)
                    263:                                break;
                    264:                        dot = inkdot(sizeof(w));
                    265:                }
                    266:        } else {
                    267:                hword_t hw;
                    268: 
                    269:                dotinc = sizeof(hw);
                    270:                mask = (hword_t)mask;
                    271:                val = (hword_t)val;
                    272:                for (;;) {
                    273:                        (void) adbread(space, dot, &hw, sizeof(hw));
                    274:                        if (iserr() || (hw & mask) == val)
                    275:                                break;
                    276:                        dot = inkdot(sizeof(hw));
                    277:                }
                    278:        }
                    279:        if (iserr()) {
                    280:                dot = savdot;
                    281:                errflag = NOMATCH;
                    282:        }
                    283:        psymoff("%R", dot, ptype, maxoff, "");
                    284: }
                    285: 
                    286: /*
                    287:  * Write new values (w, W).
                    288:  */
                    289: static void
                    290: wcom(space, ptype, fullword)
                    291:        int space, ptype, fullword;
                    292: {
                    293:        addr_t savdot;
                    294:        hword_t hw;
                    295: 
                    296:        (void) rexpr();
                    297:        do {
                    298:                savdot = dot;
                    299:                pdot();
                    300:                showdot(fullword, space, ptype);        /* also advances */
                    301:                errflag = NULL;
                    302:                dot = savdot;
                    303:                if (fullword)
                    304:                        (void) adbwrite(space, dot, &expv, sizeof(expv));
                    305:                else {
                    306:                        hw = expv;
                    307:                        (void) adbwrite(space, dot, &hw, sizeof(hw));
                    308:                }
                    309:                savdot = dot;
                    310:                adbprintf("=%8t");
                    311:                showdot(fullword, space, ptype);
                    312:                printc('\n');
                    313:        } while (oexpr() && !iserr());
                    314:        dot = savdot;
                    315:        checkerr();
                    316: }
                    317: 
                    318: /*
                    319:  * Do a shell escape.
                    320:  *
                    321:  * THE vfork CODE BELOW IS CURRENTLY BROKEN
                    322:  * MUST CHANGE signal TO sigvec BELOW
                    323:  */
                    324: static
                    325: shell()
                    326: {
                    327:        int rc, unixpid;
                    328:        union wait status;
                    329:        char *argp = lp;
                    330:        char *getenv(), *eshell = getenv("SHELL");
                    331: 
                    332:        if (eshell == 0)
                    333:                eshell = _PATH_BSHELL;
                    334:        while (readchar() != '\n')
                    335:                /* void */;
                    336: #ifndef VFORK
                    337: #define vfork fork
                    338: #endif
                    339:        if ((unixpid = vfork()) == 0) {
                    340:                *lp = 0;
                    341:                (void) signal(SIGINT, sigint);
                    342:                (void) signal(SIGQUIT, sigquit);
                    343:                execl(eshell, "sh", "-c", argp, (char *)NULL);
                    344:                _exit(16);
                    345:                /* NOTREACHED */
                    346:        }
                    347: #ifdef VFORK
                    348:        *lp = '\n';
                    349: #endif
                    350:        if (unixpid == -1)
                    351:                error(NOFORK);
                    352:        (void) signal(SIGINT, SIG_IGN);
                    353:        while ((rc = wait(&status)) != unixpid && rc != -1)
                    354:                /* void */;
                    355:        (void) signal(SIGINT, intcatch);
                    356:        prints("!");
                    357:        unreadc();
                    358: }
                    359: 
                    360: /*
                    361:  * Read a format into the given buffer.  If nothing is
                    362:  * read, leave the buffer alone.
                    363:  */
                    364: static
                    365: getformat(buf, n)
                    366:        char *buf;
                    367:        register int n;
                    368: {
                    369:        register char *p = buf;
                    370:        register int c, quote = 0;
                    371: 
                    372:        while ((c = readchar()), quote ? c != '\n' : !eol(c)) {
                    373:                if (c == '"')
                    374:                        quote = !quote;
                    375:                if (--n > 0)
                    376:                        *p++ = c;
                    377:        }
                    378:        unreadc();
                    379:        if (p != buf)           /* nonempty */
                    380:                *p++ = 0;
                    381: }
                    382: 
                    383: /*
                    384:  * Convert a (one-character) variable name to an index, or -1 for
                    385:  * error.
                    386:  */
                    387: varlookup(name)
                    388:        register int name;
                    389: {
                    390: 
                    391:        if (isdigit(name))
                    392:                return (name - '0');
                    393:        if (isalpha(name))
                    394:                return (isupper(name) ? name - 'A' + 10 : name - 'a' + 10);
                    395:        return (-1);
                    396: }
                    397: 
                    398: /* 
                    399:  * If the text at the current input point matches a register name,
                    400:  * consume that text and return a pointer to the register; otherwise
                    401:  * leave it unconsumed and return NULL.
                    402:  */
                    403: struct reglist *
                    404: reglookup()
                    405: {
                    406:        register struct reglist *p;
                    407:        register char *a, *b, c0, c1;
                    408:        char *oldlp = lp;
                    409:        extern struct reglist reglist[];
                    410: 
                    411:        c0 = rdc();
                    412:        c1 = readchar();
                    413:        for (p = reglist; (a = p->r_name) != NULL; p++) {
                    414:                if (*a++ != c0 || *a++ != c1)
                    415:                        continue;
                    416:                b = lp;
                    417:                do {
                    418:                        if (*a == 0) {  /* name matched: stop short */
                    419:                                lp = b;
                    420:                                return (p);
                    421:                        }
                    422:                } while (*a++ == *b++);
                    423:        }
                    424:        lp = oldlp;
                    425:        return (NULL);
                    426: }

unix.superglobalmegacorp.com

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