[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.30

1.30    ! nicm        1: /*     $OpenBSD: value.c,v 1.29 2010/07/02 07:09:57 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.1       deraadt    81: #define MIDDLE 35
                     82:
1.29      nicm       83: static int     vlookup(char *);
                     84: static void    vtoken(char *);
                     85: static void    vprint(value_t *);
                     86: static char    *vinterp(char *, int);
1.13      moritz     87:
1.14      moritz     88: static size_t col = 0;
1.1       deraadt    89:
1.26      nicm       90: /* Get a string value. */
                     91: char *
                     92: vgetstr(int value)
                     93: {
1.28      nicm       94:        value_t *vp = &vtable[value];
                     95:        int      type;
                     96:
                     97:        type = vp->v_flags & V_TYPEMASK;
                     98:        if (type != V_STRING)
                     99:                errx(1, "variable %s not a string", vp->v_name);
                    100:        return (vp->v_string);
1.26      nicm      101: }
                    102:
                    103: /* Get a number value. */
                    104: int
                    105: vgetnum(int value)
                    106: {
1.28      nicm      107:        value_t *vp = &vtable[value];
                    108:        int      type;
                    109:
                    110:        type = vp->v_flags & V_TYPEMASK;
                    111:        if (type != V_NUMBER && type != V_BOOL && type != V_CHAR)
                    112:                errx(1, "variable %s not a number", vp->v_name);
                    113:        return (vp->v_number);
1.26      nicm      114: }
                    115:
                    116: /* Set a string value. */
                    117: void
                    118: vsetstr(int value, char *string)
                    119: {
1.28      nicm      120:        value_t *vp = &vtable[value];
                    121:        int      type;
                    122:
                    123:        type = vp->v_flags & V_TYPEMASK;
                    124:        if (type != V_STRING)
                    125:                errx(1, "variable %s not a string", vp->v_name);
                    126:
                    127:        if (value == RECORD && string != NULL)
                    128:                string = expand(string);
                    129:
1.30    ! nicm      130:        free(vp->v_string);
1.28      nicm      131:        if (string != NULL) {
                    132:                vp->v_string = strdup(string);
                    133:                if (vp->v_string == NULL)
                    134:                        err(1, "strdup");
                    135:        } else
                    136:                vp->v_string = NULL;
1.26      nicm      137: }
                    138:
                    139: /* Set a number value. */
                    140: void
                    141: vsetnum(int value, int number)
                    142: {
1.28      nicm      143:        value_t *vp = &vtable[value];
                    144:        int      type;
                    145:
                    146:        type = vp->v_flags & V_TYPEMASK;
                    147:        if (type != V_NUMBER && type != V_BOOL && type != V_CHAR)
                    148:                errx(1, "variable %s not a number", vp->v_name);
                    149:
                    150:        vp->v_number = number;
1.26      nicm      151: }
                    152:
1.29      nicm      153: /* Find index of variable by name or abbreviation. */
                    154: static int
                    155: vlookup(char *s)
                    156: {
                    157:        value_t *vp;
                    158:        u_int    i;
                    159:
                    160:        for (i = 0; vtable[i].v_name != NULL; i++) {
                    161:                vp = &vtable[i];
                    162:                if (strcmp(vp->v_name, s) == 0 ||
                    163:                    (vp->v_abbrev != NULL && strcmp(vp->v_abbrev, s) == 0))
                    164:                        return (i);
                    165:        }
                    166:        return (-1);
                    167: }
                    168:
1.5       deraadt   169: void
1.11      deraadt   170: vinit(void)
1.1       deraadt   171: {
1.30    ! nicm      172:        struct passwd   *pw;
        !           173:        value_t         *vp;
        !           174:        char             file[FILENAME_MAX], *cp;
        !           175:        int              written;
        !           176:        FILE            *fp;
1.1       deraadt   177:
1.23      nicm      178:        /* Read environment variables. */
1.30    ! nicm      179:        if ((cp = getenv("HOME")) != NULL)
1.25      nicm      180:                vsetstr(HOME, cp);
1.30    ! nicm      181:        else {
        !           182:                pw = getpwuid(getuid());
        !           183:                if (pw != NULL && pw->pw_dir != NULL)
        !           184:                        vsetstr(HOME, pw->pw_dir);
        !           185:                else
        !           186:                        vsetstr(HOME, "/");
        !           187:        }
        !           188:        if ((cp = getenv("SHELL")) != NULL)
1.25      nicm      189:                vsetstr(SHELL, cp);
1.30    ! nicm      190:        else
        !           191:                vsetstr(SHELL, _PATH_BSHELL);
        !           192:
        !           193:        /* Clear the table and set the defaults. */
        !           194:        for (vp = vtable; vp->v_name != NULL; vp++) {
        !           195:                vp->v_string = NULL;
        !           196:                vp->v_number = 0;
        !           197:        }
        !           198:        vsetnum(BEAUTIFY, 1);
        !           199:        vsetnum(ESCAPE, '~');
        !           200:        vsetnum(FORCE, CTRL('p'));
        !           201:        vsetnum(PROMPT, '\n');
        !           202:        vsetnum(TAND, 1);
        !           203:        vsetnum(VERBOSE, 1);
        !           204:        vsetstr(LOG, _PATH_ACULOG);
1.23      nicm      205:
                    206:        /* Read the .tiprc file in the HOME directory. */
1.25      nicm      207:        written = snprintf(file, sizeof(file), "%s/.tiprc", vgetstr(HOME));
1.16      moritz    208:        if (written < 0 || written >= sizeof(file)) {
1.4       millert   209:                (void)fprintf(stderr, "Home directory path too long: %s\n",
1.25      nicm      210:                    vgetstr(HOME));
1.3       millert   211:        } else {
1.11      deraadt   212:                if ((fp = fopen(file, "r")) != NULL) {
1.7       millert   213:                        char *tp;
1.3       millert   214:
1.15      ray       215:                        while (fgets(file, sizeof(file), fp) != NULL) {
1.3       millert   216:                                if (vflag)
                    217:                                        printf("set %s", file);
1.5       deraadt   218:                                if ((tp = strrchr(file, '\n')))
1.3       millert   219:                                        *tp = '\0';
                    220:                                vlex(file);
                    221:                        }
1.11      deraadt   222:                        fclose(fp);
1.1       deraadt   223:                }
                    224:        }
                    225: }
                    226:
1.5       deraadt   227: void
1.11      deraadt   228: vlex(char *s)
1.1       deraadt   229: {
1.7       millert   230:        value_t *p;
1.11      deraadt   231:        char *cp;
1.1       deraadt   232:
1.19      nicm      233:        if (strcmp(s, "all") == 0) {
1.1       deraadt   234:                for (p = vtable; p->v_name; p++)
1.20      nicm      235:                        vprint(p);
1.1       deraadt   236:        } else {
                    237:                do {
1.5       deraadt   238:                        if ((cp = vinterp(s, ' ')))
1.1       deraadt   239:                                cp++;
                    240:                        vtoken(s);
                    241:                        s = cp;
                    242:                } while (s);
                    243:        }
                    244:        if (col > 0) {
                    245:                printf("\r\n");
                    246:                col = 0;
                    247:        }
                    248: }
                    249:
1.29      nicm      250: /* Set a variable from a token. */
1.1       deraadt   251: static void
1.11      deraadt   252: vtoken(char *s)
1.1       deraadt   253: {
1.29      nicm      254:        value_t         *vp;
                    255:        int             i, value;
                    256:        char            *cp;
                    257:        const char      *cause;
1.1       deraadt   258:
1.5       deraadt   259:        if ((cp = strchr(s, '='))) {
1.1       deraadt   260:                *cp = '\0';
1.29      nicm      261:                if ((i = vlookup(s)) != -1) {
                    262:                        vp = &vtable[i];
                    263:                        if (vp->v_flags & V_READONLY) {
                    264:                                printf("access denied\r\n");
                    265:                                return;
                    266:                        }
1.1       deraadt   267:                        cp++;
1.29      nicm      268:                        switch (vp->v_flags & V_TYPEMASK) {
                    269:                        case V_STRING:
                    270:                                vsetstr(i, cp);
                    271:                                break;
                    272:                        case V_BOOL:
                    273:                                vsetnum(i, 1);
                    274:                                break;
                    275:                        case V_NUMBER:
                    276:                                value = strtonum(cp, 0, INT_MAX, &cause);
                    277:                                if (cause != NULL) {
                    278:                                        printf("%s: number %s\r\n", s, cause);
                    279:                                        return;
                    280:                                }
                    281:                                vsetnum(i, value);
                    282:                                break;
                    283:                        case V_CHAR:
                    284:                                if (cp[0] != '\0' && cp[1] != '\0') {
                    285:                                        printf("%s: character too big\r\n", s);
                    286:                                        return;
                    287:                                }
                    288:                                vsetnum(i, *cp);
1.1       deraadt   289:                        }
1.29      nicm      290:                        vp->v_flags |= V_CHANGED;
1.1       deraadt   291:                        return;
                    292:                }
1.5       deraadt   293:        } else if ((cp = strchr(s, '?'))) {
1.1       deraadt   294:                *cp = '\0';
1.29      nicm      295:                if ((i = vlookup(s)) != -1) {
                    296:                        vprint(&vtable[i]);
1.1       deraadt   297:                        return;
                    298:                }
                    299:        } else {
                    300:                if (*s != '!')
1.29      nicm      301:                        i = vlookup(s);
1.1       deraadt   302:                else
1.29      nicm      303:                        i = vlookup(s + 1);
                    304:                if (i != -1) {
                    305:                        vp = &vtable[i];
                    306:                        if (vp->v_flags & V_READONLY) {
                    307:                                printf("%s: access denied\r\n", s);
                    308:                                return;
                    309:                        }
                    310:                        if ((vp->v_flags & V_TYPEMASK) != V_BOOL) {
                    311:                                printf("%s: not a boolean\r\n", s);
                    312:                                return;
                    313:                        }
                    314:                        vsetnum(i, *s != '!');
                    315:                        vp->v_flags |= V_CHANGED;
1.1       deraadt   316:                        return;
                    317:                }
                    318:        }
                    319:        printf("%s: unknown variable\r\n", s);
                    320: }
                    321:
                    322: static void
1.11      deraadt   323: vprint(value_t *p)
1.1       deraadt   324: {
1.7       millert   325:        char *cp;
1.1       deraadt   326:
                    327:        if (col > 0 && col < MIDDLE)
                    328:                while (col++ < MIDDLE)
                    329:                        putchar(' ');
                    330:        col += size(p->v_name);
1.21      nicm      331:        switch (p->v_flags & V_TYPEMASK) {
1.1       deraadt   332:
1.21      nicm      333:        case V_BOOL:
1.26      nicm      334:                if (!p->v_number) {
1.1       deraadt   335:                        col++;
                    336:                        putchar('!');
                    337:                }
                    338:                printf("%s", p->v_name);
                    339:                break;
                    340:
1.21      nicm      341:        case V_STRING:
1.1       deraadt   342:                printf("%s=", p->v_name);
                    343:                col++;
1.26      nicm      344:                if (p->v_string) {
                    345:                        cp = interp(p->v_string);
1.1       deraadt   346:                        col += size(cp);
                    347:                        printf("%s", cp);
                    348:                }
                    349:                break;
                    350:
1.21      nicm      351:        case V_NUMBER:
1.1       deraadt   352:                col += 6;
1.26      nicm      353:                printf("%s=%-5d", p->v_name, p->v_number);
1.1       deraadt   354:                break;
                    355:
1.21      nicm      356:        case V_CHAR:
1.1       deraadt   357:                printf("%s=", p->v_name);
                    358:                col++;
1.26      nicm      359:                if (p->v_number) {
                    360:                        cp = ctrl(p->v_number);
1.1       deraadt   361:                        col += size(cp);
                    362:                        printf("%s", cp);
                    363:                }
                    364:                break;
                    365:        }
                    366:        if (col >= MIDDLE) {
                    367:                col = 0;
                    368:                printf("\r\n");
                    369:                return;
                    370:        }
                    371: }
                    372:
1.13      moritz    373: static char *
1.11      deraadt   374: vinterp(char *s, int stop)
1.1       deraadt   375: {
1.7       millert   376:        char *p = s, c;
1.1       deraadt   377:        int num;
                    378:
1.11      deraadt   379:        while ((c = *s++) && c != stop) {
1.1       deraadt   380:                switch (c) {
                    381:
                    382:                case '^':
                    383:                        if (*s)
                    384:                                *p++ = *s++ - 0100;
                    385:                        else
                    386:                                *p++ = c;
                    387:                        break;
                    388:
                    389:                case '\\':
                    390:                        num = 0;
                    391:                        c = *s++;
                    392:                        if (c >= '0' && c <= '7')
                    393:                                num = (num<<3)+(c-'0');
                    394:                        else {
1.7       millert   395:                                char *q = "n\nr\rt\tb\bf\f";
1.1       deraadt   396:
                    397:                                for (; *q; q++)
                    398:                                        if (c == *q++) {
                    399:                                                *p++ = *q;
                    400:                                                goto cont;
                    401:                                        }
                    402:                                *p++ = c;
                    403:                        cont:
                    404:                                break;
                    405:                        }
                    406:                        if ((c = *s++) >= '0' && c <= '7') {
                    407:                                num = (num<<3)+(c-'0');
                    408:                                if ((c = *s++) >= '0' && c <= '7')
                    409:                                        num = (num<<3)+(c-'0');
                    410:                                else
                    411:                                        s--;
                    412:                        } else
                    413:                                s--;
                    414:                        *p++ = num;
                    415:                        break;
                    416:
                    417:                default:
                    418:                        *p++ = c;
                    419:                }
1.11      deraadt   420:        }
1.1       deraadt   421:        *p = '\0';
                    422:        return (c == stop ? s-1 : NULL);
                    423: }