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

1.1       root        1: /*
                      2:  * Miscellaneous functions
                      3:  */
                      4: 
                      5: #include <stddef.h>
                      6: #include <stdlib.h>
                      7: #include <limits.h>
                      8: #include <string.h>
                      9: #include <signal.h>
                     10: #include <errno.h>
                     11: #include <setjmp.h>
                     12: #include <sys/types.h>
                     13: #include <sys/stat.h>
                     14: #include <access.h>
                     15: #include "sh.h"
                     16: #include "expand.h"
                     17: #include "table.h"
                     18: 
                     19: char ctypes [UCHAR_MAX];       /* type bits for unsigned char */
                     20: 
                     21: /*
                     22:  * Fast character classes
                     23:  */
                     24: void
                     25: setctypes(s, t)
                     26:        register Const char *s;
                     27:        register int t;
                     28: {
                     29:        register int i;
                     30: 
                     31:        if ((t&C_IFS)) {
                     32:                for (i = 0; i < UCHAR_MAX; i++)
                     33:                        ctypes[i] &=~ C_IFS;
                     34:                ctypes[0] |= C_IFS; /* include \0 in C_IFS */
                     35:        }
                     36:        ctypes[(unsigned char) *s++] |= t;      /* allow leading \0 in string */
                     37:        while (*s != 0)
                     38:                ctypes[(unsigned char) *s++] |= t;
                     39: }
                     40: 
                     41: void
                     42: initctypes()
                     43: {
                     44:        register int c;
                     45: 
                     46:        for (c = 'a'; c <= 'z'; c++)
                     47:                ctypes[c] |= C_ALPHA;
                     48:        for (c = 'A'; c <= 'Z'; c++)
                     49:                ctypes[c] |= C_ALPHA;
                     50:        ctypes['_'] |= C_ALPHA;
                     51:        setctypes("0123456789", C_DIGIT);
                     52:        setctypes("\0 \t\n|&;<>()", C_LEX1);
                     53:        setctypes("*@#!$-?", C_VAR1);
                     54:        setctypes("=-+?#%", C_SUBOP);
                     55: }
                     56: 
                     57: /* convert unsigned long to base N string */
                     58: 
                     59: char *
                     60: ulton(n, base)
                     61:        register unsigned long n;
                     62:        int base;
                     63: {
                     64:        register char *p;
                     65:        static char buf [20];
                     66: 
                     67:        p = &buf[sizeof(buf)];
                     68:        *--p = '\0';
                     69:        do {
                     70:                *--p = "0123456789ABCDEF"[n%base];
                     71:                n /= base;
                     72:        } while (n != 0);
                     73:        return p;
                     74: }
                     75: 
                     76: char *
                     77: strsave(s, ap)
                     78:        register char *s;
                     79:        Area *ap;
                     80: {
                     81:        return strcpy((char*) alloc((size_t)strlen(s)+1, ap), s);
                     82: }
                     83: 
                     84: static struct option {
                     85:        char *name;
                     86:        int flag;
                     87: } options[] = {
                     88:        {"allexport",   FEXPORT},
                     89:        {"bgnice",      FBGNICE},
                     90: #if EDIT
                     91:        {"emacs",       FEMACS},
                     92: #endif
                     93:        {"errexit",     FERREXIT},
                     94:        {"hashall",     FHASHALL},
                     95:        {"ignoreeof",   FIGNEOF},
                     96:        {"interactive", FTALKING},
                     97:        {"keyword",     FKEYWORD},
                     98:        {"markdirs",    FMARKDIRS},
                     99:        {"monitor",     FMONITOR},
                    100:        {"noexec",      FNOEXEC},
                    101:        {"noglob",      FNOGLOB},
                    102:        {"nounset",     FNOUNSET},
                    103:        {"privileged",  FPRIVILEGED},
                    104:        {"stdin",       FSTDIN},
                    105:        {"trackall",    FHASHALL},
                    106:        {"verbose",     FVERBOSE},
                    107:        {"xtrace",      FXTRACE},
                    108:        {NULL,          0}
                    109: };     
                    110: 
                    111: /*
                    112:  * translate -o option into F* constant
                    113:  */
                    114: int
                    115: option(n)
                    116:        Const char *n;
                    117: {
                    118:        register struct option *op;
                    119: 
                    120:        for (op = options; op->name != NULL; op++)
                    121:                if (strcmp(op->name, n) == 0)
                    122:                        return op->flag;
                    123:        return 0;
                    124: }
                    125: 
                    126: char *
                    127: getoptions()
                    128: {
                    129:        register int c;
                    130:        char m [26+1];
                    131:        register char *cp = m;
                    132: 
                    133:        for (c = 'a'; c <= 'z'; c++)
                    134:                if (flag[FLAG(c)])
                    135:                        *cp++ = (char) c;
                    136:        *cp = 0;
                    137:        return strsave(m, ATEMP);
                    138: }
                    139: 
                    140: void
                    141: printoptions()
                    142: {
                    143:        register struct option *op;
                    144: 
                    145:        for (op = options; op->name != NULL; op++)
                    146:                if (flag[op->flag])
                    147:                        shellf("%s ", op->name);
                    148:        shellf("\n");
                    149: }
                    150:        
                    151: /* atoi with error detection */
                    152: 
                    153: getn(as)
                    154:        char *as;
                    155: {
                    156:        register char *s;
                    157:        register int n;
                    158: 
                    159:        s = as;
                    160:        if (*s == '-')
                    161:                s++;
                    162:        for (n = 0; digit(*s); s++)
                    163:                n = (n*10) + (*s-'0');
                    164:        if (*s)
                    165:                errorf("%s: bad number\n", as);
                    166:        return (*as == '-') ? -n : n;
                    167: }
                    168: 
                    169: /*
                    170:  * stripped down strerror for kill and exec
                    171:  */
                    172: char *
                    173: strerror(i)
                    174:        int i;
                    175: {
                    176:        switch (i) {
                    177:          case EINVAL:
                    178:                return "Invalid argument";
                    179:          case EACCES:
                    180:                return "Permission denied";
                    181:          case ESRCH:
                    182:                return "No such process";
                    183:          case EPERM:
                    184:                return "Not owner";
                    185:          case ENOENT:
                    186:                return "No such file or directory";
                    187:          case ENOTDIR:
                    188:                return "Not a directory";
                    189:          case ENOEXEC:
                    190:                return "Exec format error";
                    191:          case ENOMEM:
                    192:                return "Not enough memory";
                    193:          case E2BIG:
                    194:                return "Argument list too long or program too large";
                    195:          default:
                    196:                return "Unknown system error";
                    197:        }
                    198: }
                    199: 
                    200: xpexpand(xp)
                    201:        register XPtrV *xp;
                    202: {
                    203:        int n = XPsize(*xp);
                    204:        Void **vp;
                    205:        register Void **dvp, **svp;
                    206: 
                    207:        vp = alloc(sizeofN(Void*, n*2), ATEMP);
                    208:        for (svp = xp->beg, dvp = vp; svp < xp->cur; )
                    209:                *dvp++ = *svp++;
                    210:        afree((Void*) xp->beg, ATEMP);
                    211:        xp->beg = vp;
                    212:        xp->cur = vp + n;
                    213:        xp->end = vp + n*2;
                    214: }
                    215: 
                    216: /* -------- gmatch.c -------- */
                    217: 
                    218: /*
                    219:  * int gmatch(string, pattern)
                    220:  * char *string, *pattern;
                    221:  *
                    222:  * Match a pattern as in sh(1).
                    223:  * pattern character are prefixed with MAGIC by expand.
                    224:  */
                    225: 
                    226: #define        NOT     '!'     /* might use ^ */
                    227: 
                    228: static char    *cclass ARGS((char *, int c));
                    229: 
                    230: int
                    231: gmatch(s, p)
                    232:        register unsigned char *s, *p;
                    233: {
                    234:        register int sc, pc;
                    235: 
                    236:        if (s == NULL || p == NULL)
                    237:                return 0;
                    238:        while ((pc = *p++) != 0) {
                    239:                sc = *s++;
                    240:                if (pc ==  MAGIC) {
                    241:                        switch (*p++) {
                    242:                          case '[':
                    243:                                if ((p = cclass(p, sc)) == NULL)
                    244:                                        return (0);
                    245:                                break;
                    246: 
                    247:                          case '?':
                    248:                                if (sc == 0)
                    249:                                        return (0);
                    250:                                break;
                    251: 
                    252:                          case '*':
                    253:                                s--;
                    254:                                do {
                    255:                                        if (*p == '\0' || gmatch(s, p)) {
                    256:                                                return (1);
                    257:                                        }
                    258:                                } while (*s++ != '\0');
                    259:                                return (0);
                    260: 
                    261:                        }
                    262:                } else
                    263:                        if (sc != pc)
                    264:                                return 0;
                    265:        }
                    266:        return (*s == 0);
                    267: }
                    268: 
                    269: static char *
                    270: cclass(p, sub)
                    271:        register char *p;
                    272:        register int sub;
                    273: {
                    274:        register int c, d, not, found = 0;
                    275: 
                    276:        if ((not = *p == NOT))
                    277:                p++;
                    278:        do {
                    279:                if (*p == '\0')
                    280:                        return NULL;
                    281:                c = *p;
                    282:                if (p[1] == '-' && p[2] != ']') {
                    283:                        d = p[2];
                    284:                        p++;
                    285:                } else
                    286:                        d = c;
                    287:                if (c == sub || c <= sub && sub <= d)
                    288:                        found = 1;
                    289:        } while (*++p != ']');
                    290: 
                    291:        return (found != not) ? p+1 : NULL;
                    292: }
                    293: 
                    294: /* -------- qsort.c -------- */
                    295: 
                    296: /*
                    297:  * quick sort of array of generic pointers to objects.
                    298:  */
                    299: 
                    300: void
                    301: qsortp(base, n, f)
                    302:        Void **base;            /* base address */
                    303:        size_t n;               /* elements */
                    304:        int (*f)();             /* compare function */
                    305: {
                    306:        qsort1(base, base + n, f);
                    307: }
                    308: 
                    309: #define        swap2(a, b)     {\
                    310:        register Void *t; t = *(a); *(a) = *(b); *(b) = t;\
                    311: }
                    312: #define        swap3(a, b, c)  {\
                    313:        register Void *t; t = *(a); *(a) = *(c); *(c) = *(b); *(b) = t;\
                    314: }
                    315: 
                    316: qsort1(base, lim, f)
                    317:        Void **base, **lim;
                    318:        int (*f)();
                    319: {
                    320:        register Void **i, **j;
                    321:        register Void **lptr, **hptr;
                    322:        size_t n;
                    323:        int c;
                    324: 
                    325:   top:
                    326:        n = (lim - base) / 2;
                    327:        if (n == 0)
                    328:                return;
                    329:        hptr = lptr = base+n;
                    330:        i = base;
                    331:        j = lim - 1;
                    332: 
                    333:        for (;;) {
                    334:                if (i < lptr) {
                    335:                        if ((c = (*f)(*i, *lptr)) == 0) {
                    336:                                lptr --;
                    337:                                swap2(i, lptr);
                    338:                                continue;
                    339:                        }
                    340:                        if (c < 0) {
                    341:                                i += 1;
                    342:                                continue;
                    343:                        }
                    344:                }
                    345: 
                    346:          begin:
                    347:                if (j > hptr) {
                    348:                        if ((c = (*f)(*hptr, *j)) == 0) {
                    349:                                hptr ++;
                    350:                                swap2(hptr, j);
                    351:                                goto begin;
                    352:                        }
                    353:                        if (c > 0) {
                    354:                                if (i == lptr) {
                    355:                                        hptr ++;
                    356:                                        swap3(i, hptr, j);
                    357:                                        i = lptr += 1;
                    358:                                        goto begin;
                    359:                                }
                    360:                                swap2(i, j);
                    361:                                j -= 1;
                    362:                                i += 1;
                    363:                                continue;
                    364:                        }
                    365:                        j -= 1;
                    366:                        goto begin;
                    367:                }
                    368: 
                    369:                if (i == lptr) {
                    370:                        if (lptr-base >= lim-hptr) {
                    371:                                qsort1(hptr+1, lim, f);
                    372:                                lim = lptr;
                    373:                        } else {
                    374:                                qsort1(base, lptr, f);
                    375:                                base = hptr+1;
                    376:                        }
                    377:                        goto top;
                    378:                }
                    379: 
                    380:                lptr -= 1;
                    381:                swap3(j, lptr, i);
                    382:                j = hptr -= 1;
                    383:        }
                    384: }
                    385: 
                    386: int
                    387: xstrcmp(p1, p2)
                    388:        Void *p1, *p2;
                    389: {
                    390:        return (strcmp((char *)p1, (char *)p2));
                    391: }
                    392: 
                    393: #if COHERENT
                    394: /*
                    395:  * check to see if new mail has arrived in the mailbox specified by $MAIL.
                    396:  * if so, issue a friendly message.
                    397:  */
                    398: void
                    399: mail()
                    400: {
                    401:        char    *mp;                              /* MAIL */
                    402:        char    *mcp;                             /* MAILCHECK */
                    403:        static  time_t  interval = MAILINTERVAL;  /* seconds between checks */
                    404:        static  time_t  lasttime;
                    405:        time_t          currtime, time();
                    406:        static  long    mailsize = -1;
                    407:        struct  stat    sbuf;
                    408: 
                    409:        if (((mp = strval(global("MAIL"))) == NULL) || *mp == '\0')
                    410:                return;
                    411:        if ((mcp = strval(global("MAILCHECK"))) != NULL && *mcp != '\0')
                    412:                if ((interval = (time_t)getn(mcp)) < 0)
                    413:                        interval = MAILINTERVAL;
                    414: 
                    415:        currtime = time((time_t *)0);
                    416:        if ((currtime - lasttime) < interval)
                    417:                return;
                    418:        lasttime = currtime;
                    419: 
                    420:        if (stat(mp, &sbuf) < 0) {
                    421:                mailsize = 0;
                    422:        } else {
                    423:                if (sbuf.st_size != 0 && sbuf.st_size > mailsize) {
                    424:                        if (mailsize == -1)
                    425:                                printf("You have mail.\n");
                    426:                        else
                    427:                                printf("You have new mail.\n");
                    428:                }
                    429:                mailsize = sbuf.st_size;
                    430:        }
                    431: }
                    432: 
                    433: /*
                    434:  * modified version of access() which makes sure that anything
                    435:  * executable is really a file. This fixes a bug (misfeature) where
                    436:  * directories found along $PATH are treated as unexecutable executables.
                    437:  */
                    438: eaccess(name, mode)
                    439: char   *name;
                    440: int    mode;
                    441: {
                    442:        struct  stat    sbuf;
                    443:        int     ret;
                    444: 
                    445:        if ((mode & AEXEC) == 0)
                    446:                return access(name, mode);
                    447:        if ((ret = access(name, mode)) != 0)
                    448:                return ret;
                    449:        if (stat(name, &sbuf) < 0)
                    450:                return 1;
                    451:        return ((sbuf.st_mode & S_IFMT) != S_IFREG);
                    452: }
                    453: #endif /* COHERENT */

unix.superglobalmegacorp.com

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