[BACK]Return to value.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tip

Annotation of src/usr.bin/tip/value.c, Revision 1.32

1.32    ! chl         1: /*     $OpenBSD: value.c,v 1.31 2010/07/02 07:55:00 nicm Exp $ */
1.4       millert     2: /*     $NetBSD: value.c,v 1.6 1997/02/11 09:24:09 mrg Exp $    */
1.1       deraadt     3:
                      4: /*
                      5:  * Copyright (c) 1983, 1993
                      6:  *     The Regents of the University of California.  All rights reserved.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
1.10      millert    16:  * 3. Neither the name of the University nor the names of its contributors
1.1       deraadt    17:  *    may be used to endorse or promote products derived from this software
                     18:  *    without specific prior written permission.
                     19:  *
                     20:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     21:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     22:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     23:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     24:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     25:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     26:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     27:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     28:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     29:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     30:  * SUCH DAMAGE.
                     31:  */
                     32:
1.30      nicm       33: #include <paths.h>
                     34:
1.1       deraadt    35: #include "tip.h"
                     36:
1.26      nicm       37: /*
                     38:  * Variable manipulation.
                     39:  */
                     40:
1.30      nicm       41: value_t vtable[] = {
                     42:        { "beautify",     V_BOOL,              "be",     NULL, 0 },
                     43:        { "baudrate",     V_NUMBER,            "ba",     NULL, 0 },
                     44:        { "connect",      V_STRING|V_READONLY, "cm",     NULL, 0 },
                     45:        { "device",       V_STRING|V_READONLY, "dv",     NULL, 0 },
                     46:        { "eofread",      V_STRING,            "eofr",   NULL, 0 },
                     47:        { "eofwrite",     V_STRING,            "eofw",   NULL, 0 },
                     48:        { "eol",          V_STRING,            NULL,     NULL, 0 },
                     49:        { "escape",       V_CHAR,              "es",     NULL, 0 },
                     50:        { "exceptions",   V_STRING,            "ex",     NULL, 0 },
                     51:        { "force",        V_CHAR,              "fo",     NULL, 0 },
                     52:        { "framesize",    V_NUMBER,            "fr",     NULL, 0 },
                     53:        { "host",         V_STRING|V_READONLY, "ho",     NULL, 0 },
                     54:        { "log",          V_STRING,            NULL,     NULL, 0 },
                     55:        { "prompt",       V_CHAR,              "pr",     NULL, 0 },
                     56:        { "raise",        V_BOOL,              "ra",     NULL, 0 },
                     57:        { "raisechar",    V_CHAR,              "rc",     NULL, 0 },
                     58:        { "record",       V_STRING,            "rec",    NULL, 0 },
                     59:        { "remote",       V_STRING|V_READONLY, NULL,     NULL, 0 },
                     60:        { "script",       V_BOOL,              "sc",     NULL, 0 },
                     61:        { "tabexpand",    V_BOOL,              "tab",    NULL, 0 },
                     62:        { "verbose",      V_BOOL,              "verb",   NULL, 0 },
                     63:        { "SHELL",        V_STRING,            NULL,     NULL, 0 },
                     64:        { "HOME",         V_STRING,            NULL,     NULL, 0 },
                     65:        { "echocheck",    V_BOOL,              "ec",     NULL, 0 },
                     66:        { "disconnect",   V_STRING,            "di",     NULL, 0 },
                     67:        { "tandem",       V_BOOL,              "ta",     NULL, 0 },
                     68:        { "linedelay",    V_NUMBER,            "ldelay", NULL, 0 },
                     69:        { "chardelay",    V_NUMBER,            "cdelay", NULL, 0 },
                     70:        { "etimeout",     V_NUMBER,            "et",     NULL, 0 },
                     71:        { "rawftp",       V_BOOL,              "raw",    NULL, 0 },
                     72:        { "halfduplex",   V_BOOL,              "hdx",    NULL, 0 },
                     73:        { "localecho",    V_BOOL,              "le",     NULL, 0 },
                     74:        { "parity",       V_STRING,            "par",    NULL, 0 },
                     75:        { "hardwareflow", V_BOOL,              "hf",     NULL, 0 },
                     76:        { "linedisc",     V_NUMBER,            "ld",     NULL, 0 },
                     77:        { "direct",       V_BOOL,              "dc",     NULL, 0 },
                     78:        { NULL,           0,                    NULL,    NULL, 0 },
                     79: };
                     80:
1.29      nicm       81: static int     vlookup(char *);
                     82: static void    vtoken(char *);
1.31      nicm       83: static size_t  vprint(value_t *);
                     84: static void    vprintall(void);
1.29      nicm       85: static char    *vinterp(char *, int);
1.13      moritz     86:
1.26      nicm       87: /* Get a string value. */
                     88: char *
                     89: vgetstr(int value)
                     90: {
1.28      nicm       91:        value_t *vp = &vtable[value];
                     92:        int      type;
                     93:
                     94:        type = vp->v_flags & V_TYPEMASK;
                     95:        if (type != V_STRING)
                     96:                errx(1, "variable %s not a string", vp->v_name);
                     97:        return (vp->v_string);
1.26      nicm       98: }
                     99:
                    100: /* Get a number value. */
                    101: int
                    102: vgetnum(int value)
                    103: {
1.28      nicm      104:        value_t *vp = &vtable[value];
                    105:        int      type;
                    106:
                    107:        type = vp->v_flags & V_TYPEMASK;
                    108:        if (type != V_NUMBER && type != V_BOOL && type != V_CHAR)
                    109:                errx(1, "variable %s not a number", vp->v_name);
                    110:        return (vp->v_number);
1.26      nicm      111: }
                    112:
                    113: /* Set a string value. */
                    114: void
                    115: vsetstr(int value, char *string)
                    116: {
1.28      nicm      117:        value_t *vp = &vtable[value];
                    118:        int      type;
                    119:
                    120:        type = vp->v_flags & V_TYPEMASK;
                    121:        if (type != V_STRING)
                    122:                errx(1, "variable %s not a string", vp->v_name);
                    123:
                    124:        if (value == RECORD && string != NULL)
                    125:                string = expand(string);
                    126:
1.30      nicm      127:        free(vp->v_string);
1.28      nicm      128:        if (string != NULL) {
                    129:                vp->v_string = strdup(string);
                    130:                if (vp->v_string == NULL)
                    131:                        err(1, "strdup");
                    132:        } else
                    133:                vp->v_string = NULL;
1.26      nicm      134: }
                    135:
                    136: /* Set a number value. */
                    137: void
                    138: vsetnum(int value, int number)
                    139: {
1.28      nicm      140:        value_t *vp = &vtable[value];
                    141:        int      type;
                    142:
                    143:        type = vp->v_flags & V_TYPEMASK;
                    144:        if (type != V_NUMBER && type != V_BOOL && type != V_CHAR)
                    145:                errx(1, "variable %s not a number", vp->v_name);
                    146:
                    147:        vp->v_number = number;
1.26      nicm      148: }
                    149:
1.31      nicm      150: /* Print a single variable and its value. */
                    151: static size_t
                    152: vprint(value_t *p)
                    153: {
                    154:        char    *cp;
                    155:        size_t   width;
                    156:
                    157:        width = size(p->v_name);
                    158:        switch (p->v_flags & V_TYPEMASK) {
                    159:        case V_BOOL:
                    160:                if (!p->v_number) {
                    161:                        width++;
                    162:                        putchar('!');
                    163:                }
                    164:                printf("%s", p->v_name);
                    165:                break;
                    166:        case V_STRING:
                    167:                printf("%s=", p->v_name);
                    168:                width++;
                    169:                if (p->v_string) {
                    170:                        cp = interp(p->v_string);
                    171:                        width += size(cp);
                    172:                        printf("%s", cp);
                    173:                }
                    174:                break;
                    175:        case V_NUMBER:
                    176:                width += 6;
                    177:                printf("%s=%-5d", p->v_name, p->v_number);
                    178:                break;
                    179:        case V_CHAR:
                    180:                printf("%s=", p->v_name);
                    181:                width++;
                    182:                if (p->v_number) {
                    183:                        cp = ctrl(p->v_number);
                    184:                        width += size(cp);
                    185:                        printf("%s", cp);
                    186:                }
                    187:                break;
                    188:        }
                    189:        return (width);
                    190: }
                    191:
                    192: /* Print all variables. */
                    193: static void
                    194: vprintall(void)
                    195: {
                    196:        value_t *vp;
                    197:        size_t   width;
                    198:
                    199: #define MIDDLE 35
                    200:        width = 0;
                    201:        for (vp = vtable; vp->v_name; vp++) {
                    202:                if (vp->v_flags & V_READONLY)
                    203:                        continue;
                    204:                if (width > 0 && width < MIDDLE) {
                    205:                        while (width++ < MIDDLE)
                    206:                                putchar(' ');
                    207:                }
                    208:                width += vprint(vp);
                    209:                if (width > MIDDLE) {
                    210:                        printf("\r\n");
                    211:                        width = 0;
                    212:                }
                    213:        }
                    214: #undef MIDDLE
                    215: }
                    216:
1.29      nicm      217: /* Find index of variable by name or abbreviation. */
                    218: static int
                    219: vlookup(char *s)
                    220: {
                    221:        value_t *vp;
                    222:        u_int    i;
                    223:
                    224:        for (i = 0; vtable[i].v_name != NULL; i++) {
                    225:                vp = &vtable[i];
                    226:                if (strcmp(vp->v_name, s) == 0 ||
                    227:                    (vp->v_abbrev != NULL && strcmp(vp->v_abbrev, s) == 0))
                    228:                        return (i);
                    229:        }
                    230:        return (-1);
                    231: }
                    232:
1.5       deraadt   233: void
1.11      deraadt   234: vinit(void)
1.1       deraadt   235: {
1.30      nicm      236:        struct passwd   *pw;
                    237:        value_t         *vp;
                    238:        char             file[FILENAME_MAX], *cp;
                    239:        int              written;
                    240:        FILE            *fp;
1.1       deraadt   241:
1.23      nicm      242:        /* Read environment variables. */
1.30      nicm      243:        if ((cp = getenv("HOME")) != NULL)
1.25      nicm      244:                vsetstr(HOME, cp);
1.30      nicm      245:        else {
                    246:                pw = getpwuid(getuid());
                    247:                if (pw != NULL && pw->pw_dir != NULL)
                    248:                        vsetstr(HOME, pw->pw_dir);
                    249:                else
                    250:                        vsetstr(HOME, "/");
                    251:        }
                    252:        if ((cp = getenv("SHELL")) != NULL)
1.25      nicm      253:                vsetstr(SHELL, cp);
1.30      nicm      254:        else
                    255:                vsetstr(SHELL, _PATH_BSHELL);
                    256:
                    257:        /* Clear the table and set the defaults. */
                    258:        for (vp = vtable; vp->v_name != NULL; vp++) {
                    259:                vp->v_string = NULL;
                    260:                vp->v_number = 0;
                    261:        }
                    262:        vsetnum(BEAUTIFY, 1);
                    263:        vsetnum(ESCAPE, '~');
                    264:        vsetnum(FORCE, CTRL('p'));
                    265:        vsetnum(PROMPT, '\n');
                    266:        vsetnum(TAND, 1);
                    267:        vsetnum(VERBOSE, 1);
                    268:        vsetstr(LOG, _PATH_ACULOG);
1.23      nicm      269:
                    270:        /* Read the .tiprc file in the HOME directory. */
1.25      nicm      271:        written = snprintf(file, sizeof(file), "%s/.tiprc", vgetstr(HOME));
1.16      moritz    272:        if (written < 0 || written >= sizeof(file)) {
1.4       millert   273:                (void)fprintf(stderr, "Home directory path too long: %s\n",
1.25      nicm      274:                    vgetstr(HOME));
1.3       millert   275:        } else {
1.11      deraadt   276:                if ((fp = fopen(file, "r")) != NULL) {
1.7       millert   277:                        char *tp;
1.3       millert   278:
1.15      ray       279:                        while (fgets(file, sizeof(file), fp) != NULL) {
1.3       millert   280:                                if (vflag)
                    281:                                        printf("set %s", file);
1.5       deraadt   282:                                if ((tp = strrchr(file, '\n')))
1.3       millert   283:                                        *tp = '\0';
                    284:                                vlex(file);
                    285:                        }
1.11      deraadt   286:                        fclose(fp);
1.1       deraadt   287:                }
                    288:        }
                    289: }
                    290:
1.5       deraadt   291: void
1.11      deraadt   292: vlex(char *s)
1.1       deraadt   293: {
1.11      deraadt   294:        char *cp;
1.1       deraadt   295:
1.31      nicm      296:        if (strcmp(s, "all") == 0)
                    297:                vprintall();
                    298:        else {
1.1       deraadt   299:                do {
1.5       deraadt   300:                        if ((cp = vinterp(s, ' ')))
1.1       deraadt   301:                                cp++;
                    302:                        vtoken(s);
                    303:                        s = cp;
                    304:                } while (s);
                    305:        }
                    306: }
                    307:
1.29      nicm      308: /* Set a variable from a token. */
1.1       deraadt   309: static void
1.11      deraadt   310: vtoken(char *s)
1.1       deraadt   311: {
1.29      nicm      312:        value_t         *vp;
                    313:        int             i, value;
                    314:        char            *cp;
                    315:        const char      *cause;
1.1       deraadt   316:
1.5       deraadt   317:        if ((cp = strchr(s, '='))) {
1.1       deraadt   318:                *cp = '\0';
1.29      nicm      319:                if ((i = vlookup(s)) != -1) {
                    320:                        vp = &vtable[i];
                    321:                        if (vp->v_flags & V_READONLY) {
                    322:                                printf("access denied\r\n");
                    323:                                return;
                    324:                        }
1.1       deraadt   325:                        cp++;
1.29      nicm      326:                        switch (vp->v_flags & V_TYPEMASK) {
                    327:                        case V_STRING:
                    328:                                vsetstr(i, cp);
                    329:                                break;
                    330:                        case V_BOOL:
                    331:                                vsetnum(i, 1);
                    332:                                break;
                    333:                        case V_NUMBER:
                    334:                                value = strtonum(cp, 0, INT_MAX, &cause);
                    335:                                if (cause != NULL) {
                    336:                                        printf("%s: number %s\r\n", s, cause);
                    337:                                        return;
                    338:                                }
                    339:                                vsetnum(i, value);
                    340:                                break;
                    341:                        case V_CHAR:
                    342:                                if (cp[0] != '\0' && cp[1] != '\0') {
                    343:                                        printf("%s: character too big\r\n", s);
                    344:                                        return;
                    345:                                }
                    346:                                vsetnum(i, *cp);
1.1       deraadt   347:                        }
1.29      nicm      348:                        vp->v_flags |= V_CHANGED;
1.1       deraadt   349:                        return;
                    350:                }
1.5       deraadt   351:        } else if ((cp = strchr(s, '?'))) {
1.1       deraadt   352:                *cp = '\0';
1.29      nicm      353:                if ((i = vlookup(s)) != -1) {
1.31      nicm      354:                        if (vprint(&vtable[i]) > 0)
                    355:                                printf("\r\n");
1.1       deraadt   356:                        return;
                    357:                }
                    358:        } else {
                    359:                if (*s != '!')
1.29      nicm      360:                        i = vlookup(s);
1.1       deraadt   361:                else
1.29      nicm      362:                        i = vlookup(s + 1);
                    363:                if (i != -1) {
                    364:                        vp = &vtable[i];
                    365:                        if (vp->v_flags & V_READONLY) {
                    366:                                printf("%s: access denied\r\n", s);
                    367:                                return;
                    368:                        }
                    369:                        if ((vp->v_flags & V_TYPEMASK) != V_BOOL) {
                    370:                                printf("%s: not a boolean\r\n", s);
                    371:                                return;
                    372:                        }
                    373:                        vsetnum(i, *s != '!');
                    374:                        vp->v_flags |= V_CHANGED;
1.1       deraadt   375:                        return;
                    376:                }
                    377:        }
                    378:        printf("%s: unknown variable\r\n", s);
                    379: }
                    380:
1.13      moritz    381: static char *
1.11      deraadt   382: vinterp(char *s, int stop)
1.1       deraadt   383: {
1.7       millert   384:        char *p = s, c;
1.1       deraadt   385:        int num;
                    386:
1.11      deraadt   387:        while ((c = *s++) && c != stop) {
1.1       deraadt   388:                switch (c) {
                    389:
                    390:                case '^':
                    391:                        if (*s)
                    392:                                *p++ = *s++ - 0100;
                    393:                        else
                    394:                                *p++ = c;
                    395:                        break;
                    396:
                    397:                case '\\':
                    398:                        num = 0;
                    399:                        c = *s++;
                    400:                        if (c >= '0' && c <= '7')
                    401:                                num = (num<<3)+(c-'0');
                    402:                        else {
1.7       millert   403:                                char *q = "n\nr\rt\tb\bf\f";
1.1       deraadt   404:
                    405:                                for (; *q; q++)
                    406:                                        if (c == *q++) {
                    407:                                                *p++ = *q;
                    408:                                                goto cont;
                    409:                                        }
                    410:                                *p++ = c;
                    411:                        cont:
                    412:                                break;
                    413:                        }
                    414:                        if ((c = *s++) >= '0' && c <= '7') {
                    415:                                num = (num<<3)+(c-'0');
                    416:                                if ((c = *s++) >= '0' && c <= '7')
                    417:                                        num = (num<<3)+(c-'0');
                    418:                                else
                    419:                                        s--;
                    420:                        } else
                    421:                                s--;
                    422:                        *p++ = num;
                    423:                        break;
                    424:
                    425:                default:
                    426:                        *p++ = c;
                    427:                }
1.11      deraadt   428:        }
1.1       deraadt   429:        *p = '\0';
                    430:        return (c == stop ? s-1 : NULL);
                    431: }