Annotation of coherent/a/usr/bob/korn/c_ksh.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * built-in Korn commands: c_*
                      3:  */
                      4: 
                      5: static char *RCSid = "$Header: c_ksh.c,v 3.1 88/11/03 09:14:21 egisin Exp $";
                      6: 
                      7: #include <stddef.h>
                      8: #include <stdlib.h>
                      9: #include <stdio.h>
                     10: #include <string.h>
                     11: #include <errno.h>
                     12: #include <setjmp.h>
                     13: #include <signal.h>
                     14: #include "sh.h"
                     15: #include "table.h"
                     16: 
                     17: int
                     18: c_hash(wp)
                     19:        register char **wp;
                     20: {
                     21:        register int i;
                     22:        register struct tbl *tp, **p;
                     23: 
                     24:        wp++;
                     25:        if (*wp == NULL) {
                     26:                for (p = tsort(&commands); (tp = *p++) != NULL; )
                     27:                        if ((tp->flag&ISSET))
                     28:                                printf("%s\n", tp->val.s);
                     29:                return 0;
                     30:        }
                     31: 
                     32:        if (strcmp(*wp, "-r") == 0)
                     33:                flushcom(1);
                     34:        while (*wp != NULL)
                     35:                findcom(*wp++, 1);
                     36:        return 0;
                     37: }
                     38: 
                     39: int
                     40: c_print(wp)
                     41:        register char **wp;
                     42: {
                     43:        int nl = 1;
                     44:        int expand = 1;
                     45:        FILE *f = stdout;
                     46: 
                     47:        for (wp++; *wp != NULL && **wp == '-'; wp++) {
                     48:                register char *s = *wp + 1;
                     49:                if (*s == '\0') {
                     50:                        wp++;
                     51:                        break;
                     52:                }
                     53:                while (*s) switch (*s++) {
                     54:                  case 'n':
                     55:                        nl = 0;
                     56:                        break;
                     57:                  case 'e':
                     58:                        expand = 1;
                     59:                        break;
                     60:                  case 'r':
                     61:                        expand = 0;
                     62:                        break;
                     63:                  case 'u':
                     64:                        if (!digit(*s) || (f = shf[*s++-'0']) == NULL)
                     65:                                errorf("bad -u argument\n");
                     66:                        break;
                     67:                }
                     68:        }
                     69: 
                     70:        while (*wp != NULL) {
                     71:                register char *s = *wp;
                     72:                register int c;
                     73:                while ((c = *s++) != '\0')
                     74:                        if (expand && c == '\\') {
                     75:                                switch ((c = *s++)) {
                     76:                                case 'b': c = '\b'; break;
                     77:                                case 'c': nl = 0; continue; /* AT&T brain damage */
                     78:                                case 'f': c = '\f'; break;
                     79:                                case 'n': c = '\n'; break;
                     80:                                case 'r': c = '\r'; break;
                     81:                                case 't': c = '\t'; break;
                     82:                                case 'v': c = 0x0B; break;
                     83:                                case '0': case '1': case '2': case '3':
                     84:                                case '4': case '5': case '6': case '7':
                     85:                                        c = c - '0';
                     86:                                        if (*s >= '0' && *s <= '7')
                     87:                                                c = 8*c + *s++ - '0';
                     88:                                        if (*s >= '0' && *s <= '7')
                     89:                                                c = 8*c + *s++ - '0';
                     90:                                        break;
                     91:                                case '\\': break;
                     92:                                default:
                     93:                                        putc('\\', f);
                     94:                                }
                     95:                                putc(c, f);
                     96:                        } else
                     97:                                putc(c, f);
                     98:                if (*++wp != NULL)
                     99:                        putc(' ', f);
                    100:        }
                    101:        if (nl)
                    102:                putc('\n', f);
                    103:        return 0;
                    104: }
                    105: 
                    106: /* todo: handle case where id is both lexical and command */
                    107: int
                    108: c_whence(wp)
                    109:        register char **wp;
                    110: {
                    111:        register struct tbl *tp;
                    112:        char *id;
                    113:        int vflag = 0;
                    114: 
                    115:        for (wp++; (id = *wp) != NULL && *id == '-'; wp++)
                    116:                if (id[1] == 'v')
                    117:                        vflag = 1;
                    118: 
                    119:        while ((id = *wp++) != NULL) {
                    120:                tp = tsearch(&lexicals, id, hash(id));
                    121:                if (tp == NULL)
                    122:                        tp = findcom(id, 1);
                    123:                if (vflag)
                    124:                        switch ((tp == NULL) ? CNONE : tp->type) {
                    125:                          case CNONE:
                    126:                                printf("%s is unknown\n", id);
                    127:                                break;
                    128:                          case CSHELL:
                    129:                                printf("%s is a shell builtin\n", id);
                    130:                                break;
                    131:                          case CFUNC:
                    132:                                printf("%s is a function\n", id);
                    133:                                fptreef(stdout, "function %s %T\n", id, tp->val.t);
                    134:                                break;
                    135:                          case CEXEC:
                    136:                                printf("%s is %s\n", id,
                    137:                                       (tp->flag&ISSET) ? tp->val.s : "unknown");
                    138:                                break;
                    139:                          case CALIAS:
                    140:                                printf("%s is the alias '%s'\n", id, tp->val.s);
                    141:                                break;
                    142:                          case CKEYWD:
                    143:                                printf("%s is a shell keyword\n", id);
                    144:                                break;
                    145:                          default:
                    146:                                printf("%s is *GOK*\n", id);
                    147:                                break;
                    148:                        }
                    149:                else
                    150:                        switch ((tp == NULL) ? CNONE : tp->type) {
                    151:                          case CNONE:
                    152:                                printf("\n");
                    153:                                break;
                    154:                          case CSHELL:
                    155:                                printf("builtin %s\n", id);
                    156:                                break;
                    157:                          case CFUNC:
                    158:                                printf("%s\n", id);
                    159:                                break;
                    160:                          case CEXEC:
                    161:                                printf("%s\n", (tp->flag&ISSET) ? tp->val.s : id);
                    162:                                break;
                    163:                          case CALIAS:
                    164:                                printf("%s\n", tp->val.s);
                    165:                                break;
                    166:                          case CKEYWD:
                    167:                                printf("%s\n", id);
                    168:                                break;
                    169:                          default:
                    170:                                printf("*GOK*\n");
                    171:                                break;
                    172:                        }
                    173:        }
                    174:        return 0;
                    175: }
                    176: 
                    177: int
                    178: c_typeset(wp)
                    179:        register char **wp;
                    180: {
                    181:        register char *id;
                    182:        struct block *l = e.loc;
                    183:        register struct tbl *vp, **p;
                    184:        int fset = 0, fclr = 0;
                    185:        int thing = 0, func = 0;
                    186: 
                    187:        for (wp++; (id = *wp) != NULL && (*id == '-' || *id == '+'); wp++) {
                    188:                int flag = 0;
                    189:                thing = *id;
                    190:                while (*++id != '\0') switch (*id) {
                    191:                  case 'f':
                    192:                        flag |= FUNCT;
                    193:                        func = 1;
                    194:                        break;
                    195:                  case 'i':
                    196:                        flag |= INTEGER;
                    197:                        break;
                    198:                  case 'r':
                    199:                        flag |= RDONLY;
                    200:                        break;
                    201:                  case 'x':
                    202:                        flag |= EXPORT;
                    203:                        break;
                    204:                  case 't':
                    205:                        flag |= TRACE;
                    206:                        break;
                    207:                  default:
                    208:                        errorf("unknown flag -%c\n", *id);
                    209:                }
                    210:                if (flag != 0) { /* + or - with options */
                    211:                        if (thing == '-')
                    212:                                fset |= flag;
                    213:                        else
                    214:                                fclr |= flag;
                    215:                        thing = 0;
                    216:                }
                    217:        }
                    218: 
                    219:        /* list variables and attributes */
                    220:        if (*wp == NULL) {
                    221:                for (l = e.loc; l != NULL; l = l->next) {
                    222:                    for (p = tsort((func==0) ? &l->vars : &l->funs);
                    223:                         (vp = *p++) != NULL; )
                    224:                        if ((vp->flag&ISSET))
                    225:                            if (thing == 0 && fclr == 0 && fset == 0) {
                    226:                                printf("typeset ");
                    227:                                if ((vp->flag&INTEGER))
                    228:                                        printf("-i ");
                    229:                                if ((vp->flag&EXPORT))
                    230:                                        printf("-x ");
                    231:                                if ((vp->flag&RDONLY))
                    232:                                        printf("-r ");
                    233:                                if ((vp->flag&TRACE)) 
                    234:                                        printf("-t ");
                    235:                                printf("%s\n", vp->name);
                    236:                            } else
                    237:                            if (thing == '+' ||
                    238:                                fclr && (vp->flag&fclr) == fclr) {
                    239:                                printf("%s\n", vp->name);
                    240:                            } else
                    241:                            if (thing == '-' ||
                    242:                                fset && (vp->flag&fset) == fset) {
                    243:                                if (fset&FUNCT)
                    244:                                    printf("function %s\n", vp->name);
                    245:                                else
                    246:                                    printf("%s=%s\n", vp->name, strval(vp));
                    247:                            }
                    248:                }
                    249:                return (0);
                    250:        }
                    251: 
                    252:        fset |= LOCAL;
                    253:        for (; *wp != NULL; wp++)
                    254: #if 0
                    255:                if (func) {
                    256:                } else
                    257: #endif
                    258:                if (typeset(*wp, fset, fclr) == NULL)
                    259:                        errorf("%s: not identifier\n", *wp);
                    260:        return 0;
                    261: }
                    262:        
                    263: int
                    264: c_alias(wp)
                    265:        register char **wp;
                    266: {
                    267:        register struct table *t = &lexicals;
                    268:        register struct tbl *ap, **p;
                    269:        register int i;
                    270:        int rv = 0;
                    271: 
                    272:        if (*++wp != NULL && strcmp(*wp, "-d") == 0) {
                    273:                t = &homedirs;
                    274:                wp++;
                    275:        }
                    276: 
                    277:        if (*wp == NULL)
                    278:                for (p = tsort(t); (ap = *p++) != NULL; )
                    279:                        if (ap->type == CALIAS && (ap->flag&DEFINED))
                    280:                                printf("%s='%s'\n", ap->name, ap->val.s);
                    281: 
                    282:        for (; *wp != NULL; wp++) {
                    283:                register char *id = *wp;
                    284:                register char *val = strchr(id, '=');
                    285: 
                    286:                if (val == NULL) {
                    287:                        ap = tsearch(t, id, hash(id));
                    288:                        if (ap != NULL && ap->type == CALIAS && (ap->flag&DEFINED))
                    289:                                printf("%s='%s'\n", ap->name, ap->val.s);
                    290:                        else
                    291:                                rv = 1;
                    292:                } else {
                    293:                        *val++ = '\0';
                    294:                        ap = tenter(t, id, hash(id));
                    295:                        if (ap->type == CKEYWD)
                    296:                                errorf("cannot alias keyword\n");
                    297:                        if ((ap->flag&ALLOC)) {
                    298:                                afree((Void*)ap->val.s, APERM);
                    299:                                ap->flag &=~ ALLOC|ISSET;
                    300:                        }
                    301:                        ap->type = CALIAS;
                    302:                        ap->val.s = strsave(val, APERM);
                    303:                        ap->flag |= DEFINED|ALLOC|ISSET;
                    304:                }
                    305:        }
                    306:        return rv;
                    307: }
                    308: 
                    309: int
                    310: c_unalias(wp)
                    311:        register char **wp;
                    312: {
                    313:        register struct table *t = &lexicals;
                    314:        register struct tbl *ap;
                    315: 
                    316:        if (*++wp != NULL && strcmp(*wp, "-d") == 0) {
                    317:                t = &homedirs;
                    318:                wp++;
                    319:        }
                    320: 
                    321:        for (; *wp != NULL; wp++) {
                    322:                ap = tsearch(t, *wp, hash(*wp));
                    323:                if (ap == NULL || ap->type != CALIAS)
                    324:                        continue;
                    325:                if ((ap->flag&ALLOC))
                    326:                        afree((Void*)ap->val.s, APERM);
                    327:                ap->flag &=~ DEFINED|ISSET|ALLOC;
                    328:        }
                    329:        return 0;
                    330: }
                    331: 
                    332: int
                    333: c_let(wp)
                    334:        char **wp;
                    335: {
                    336:        int rv = 1;
                    337: 
                    338:        for (wp++; *wp; wp++)
                    339:                rv = evaluate(*wp) == 0;
                    340:        return rv;
                    341: }
                    342: 
                    343: int
                    344: c_jobs(wp)
                    345:        char **wp;
                    346: {
                    347:        j_jobs();
                    348:        return 0;
                    349: }
                    350: 
                    351: #if JOBS
                    352: int
                    353: c_fgbg(wp)
                    354:        register char **wp;
                    355: {
                    356:        int bg = strcmp(*wp, "bg") == 0;
                    357: 
                    358:        if (!flag[FMONITOR])
                    359:                errorf("Job control not enabled\n");
                    360:        wp++;
                    361:        j_resume(j_lookup((*wp == NULL) ? "%" : *wp), bg);
                    362:        return 0;
                    363: }
                    364: #endif
                    365: 
                    366: int
                    367: c_kill(wp)
                    368:        register char **wp;
                    369: {
                    370:        register char *cp;
                    371:        int sig = SIGTERM;
                    372:        int rv = 0;
                    373: 
                    374:        if (*++wp == NULL)
                    375:                errorf("Usage: kill [-l] [-signal] {pid|job} ...\n");
                    376:        if (strcmp(*wp, "-l") == 0) {
                    377:                register struct trap *p = sigtraps;
                    378:                for (sig = 0; sig < SIGNALS; sig++, p++)
                    379:                        if (p->signal)
                    380:                                printf("%2d %8s %s\n", p->signal, p->name, p->mess);
                    381:                return 0;
                    382:        }
                    383: 
                    384:        for (; (cp = *wp) != NULL; wp++)
                    385:                if (*cp == '-' || isalpha(*cp)) {
                    386:                        struct trap *p;
                    387:                        p = gettrap((*cp == '-') ? cp+1 : cp);
                    388:                        if (p == NULL)
                    389:                                errorf("bad signal %s\n",
                    390:                                        (*cp == '-') ? cp+1 : cp);
                    391:                        sig = p->signal;
                    392:                } else if (digit(*cp)) {
                    393:                        if (kill(atoi(cp), sig) < 0) {
                    394:                                shellf("%s: %s\n", cp, strerror(errno));
                    395:                                rv++;
                    396:                        }
                    397:                } else if (*cp == '%')
                    398:                        j_kill(j_lookup(cp), sig);
                    399:                else
                    400:                        errorf("invalid argument\n");
                    401:        return rv;
                    402: }
                    403: 
                    404: int
                    405: c_bind(wp)
                    406:        register char **wp;
                    407: {
                    408:        int macro = 0;
                    409:        register char *cp;
                    410: 
                    411:        for (wp++; (cp = *wp) != NULL && *cp == '-'; wp++)
                    412:                if (cp[1] == 'm')
                    413:                        macro = 1;
                    414: 
                    415:        if (*wp == NULL)        /* list all */
                    416:                x_bind((char*)NULL, (char*)NULL, 0);
                    417: 
                    418:        for (; *wp != NULL; wp++) {
                    419:                cp = strchr(*wp, '=');
                    420:                if (cp != NULL)
                    421:                        *cp++ = 0;
                    422:                x_bind(*wp, cp, macro);
                    423:        }
                    424: 
                    425:        return 0;
                    426: }
                    427: 
                    428: extern c_fc();
                    429: extern c_getopts();
                    430: 
                    431: Const struct builtin kshbuiltins [] = {
                    432:        {"print", c_print},
                    433:        {"getopts", c_getopts},
                    434:        {"=typeset", c_typeset},
                    435:        {"whence", c_whence},
                    436:        {"alias", c_alias},
                    437:        {"unalias", c_unalias},
                    438:        {"hash", c_hash},
                    439:        {"let", c_let},
                    440:        {"fc", c_fc},
                    441:        {"jobs", c_jobs},
                    442:        {"kill", c_kill},
                    443: #if JOBS
                    444:        {"fg", c_fgbg},
                    445:        {"bg", c_fgbg},
                    446: #endif
                    447: #if EDIT
                    448:        {"bind", c_bind},
                    449: #endif
                    450:        {NULL, NULL}
                    451: };
                    452: 

unix.superglobalmegacorp.com

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