value.c revision 129004
188276Smarkm/* $OpenBSD: value.c,v 1.7 2001/10/24 18:38:58 millert Exp $ */ 288276Smarkm/* $NetBSD: value.c,v 1.6 1997/02/11 09:24:09 mrg Exp $ */ 388276Smarkm 47527Sjkh/* 57527Sjkh * Copyright (c) 1983, 1993 67527Sjkh * The Regents of the University of California. All rights reserved. 77527Sjkh * 87527Sjkh * Redistribution and use in source and binary forms, with or without 97527Sjkh * modification, are permitted provided that the following conditions 107527Sjkh * are met: 117527Sjkh * 1. Redistributions of source code must retain the above copyright 127527Sjkh * notice, this list of conditions and the following disclaimer. 137527Sjkh * 2. Redistributions in binary form must reproduce the above copyright 147527Sjkh * notice, this list of conditions and the following disclaimer in the 157527Sjkh * documentation and/or other materials provided with the distribution. 167527Sjkh * 3. All advertising materials mentioning features or use of this software 177527Sjkh * must display the following acknowledgement: 187527Sjkh * This product includes software developed by the University of 197527Sjkh * California, Berkeley and its contributors. 207527Sjkh * 4. Neither the name of the University nor the names of its contributors 217527Sjkh * may be used to endorse or promote products derived from this software 227527Sjkh * without specific prior written permission. 237527Sjkh * 247527Sjkh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 257527Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 267527Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 277527Sjkh * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 287527Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 297527Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 307527Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 317527Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 327527Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 337527Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 347527Sjkh * SUCH DAMAGE. 357527Sjkh */ 367527Sjkh 3788276Smarkm#include <sys/cdefs.h> 3888276Smarkm__FBSDID("$FreeBSD: head/usr.bin/tip/tip/value.c 129004 2004-05-06 13:25:09Z stefanf $"); 3988276Smarkm 407527Sjkh#ifndef lint 4128365Scharnier#if 0 427527Sjkhstatic char sccsid[] = "@(#)value.c 8.1 (Berkeley) 6/6/93"; 4388276Smarkmstatic char rcsid[] = "$OpenBSD: value.c,v 1.7 2001/10/24 18:38:58 millert Exp $"; 4428365Scharnier#endif 457527Sjkh#endif /* not lint */ 467527Sjkh 477527Sjkh#include "tip.h" 487527Sjkh 497527Sjkh#define MIDDLE 35 507527Sjkh 517527Sjkhstatic value_t *vlookup(); 527527Sjkhstatic int col = 0; 537527Sjkh 547527Sjkh/* 557527Sjkh * Variable manipulation 567527Sjkh */ 5728365Scharniervoid 587527Sjkhvinit() 597527Sjkh{ 6088276Smarkm value_t *p; 6188276Smarkm char *cp; 627527Sjkh FILE *f; 6388276Smarkm char file[FILENAME_MAX]; 647527Sjkh 657527Sjkh for (p = vtable; p->v_name != NULL; p++) { 667527Sjkh if (p->v_type&ENVIRON) 6728365Scharnier if ((cp = getenv(p->v_name))) 687527Sjkh p->v_value = cp; 697527Sjkh if (p->v_type&IREMOTE) 7088276Smarkm setnumber(p->v_value, *address(p->v_value)); 717527Sjkh } 727527Sjkh /* 737527Sjkh * Read the .tiprc file in the HOME directory 747527Sjkh * for sets 757527Sjkh */ 7688276Smarkm if (strlen(value(HOME)) + sizeof("/.tiprc") > sizeof(file)) { 7788276Smarkm (void)fprintf(stderr, "Home directory path too long: %s\n", 7888276Smarkm value(HOME)); 7988276Smarkm } else { 8088276Smarkm snprintf(file, sizeof file, "%s/.tiprc", value(HOME)); 8188276Smarkm if ((f = fopen(file, "r")) != NULL) { 8288276Smarkm char *tp; 837527Sjkh 8488276Smarkm while (fgets(file, sizeof(file)-1, f) != NULL) { 8588276Smarkm if (vflag) 8688276Smarkm printf("set %s", file); 8788276Smarkm if ((tp = strrchr(file, '\n'))) 8888276Smarkm *tp = '\0'; 8988276Smarkm vlex(file); 9088276Smarkm } 9188276Smarkm fclose(f); 927527Sjkh } 937527Sjkh } 947527Sjkh /* 957527Sjkh * To allow definition of exception prior to fork 967527Sjkh */ 977527Sjkh vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC); 987527Sjkh} 997527Sjkh 1007527Sjkhstatic int vaccess(); 1017527Sjkh 1027527Sjkh/*VARARGS1*/ 10328365Scharniervoid 1047527Sjkhvassign(p, v) 10588276Smarkm value_t *p; 1067527Sjkh char *v; 1077527Sjkh{ 1087527Sjkh 1097527Sjkh if (!vaccess(p->v_access, WRITE)) { 1107527Sjkh printf("access denied\r\n"); 1117527Sjkh return; 1127527Sjkh } 1137527Sjkh switch (p->v_type&TMASK) { 1147527Sjkh 1157527Sjkh case STRING: 1167527Sjkh if (p->v_value && equal(p->v_value, v)) 1177527Sjkh return; 1187527Sjkh if (!(p->v_type&(ENVIRON|INIT))) 1197527Sjkh free(p->v_value); 12088276Smarkm if ((p->v_value = strdup(v)) == NOSTR) { 1217527Sjkh printf("out of core\r\n"); 1227527Sjkh return; 1237527Sjkh } 1247527Sjkh p->v_type &= ~(ENVIRON|INIT); 1257527Sjkh break; 1267527Sjkh 1277527Sjkh case NUMBER: 1287527Sjkh if (number(p->v_value) == number(v)) 1297527Sjkh return; 13088276Smarkm setnumber(p->v_value, number(v)); 1317527Sjkh break; 1327527Sjkh 1337527Sjkh case BOOL: 1347527Sjkh if (boolean(p->v_value) == (*v != '!')) 1357527Sjkh return; 13688276Smarkm setboolean(p->v_value, (*v != '!')); 1377527Sjkh break; 1387527Sjkh 1397527Sjkh case CHAR: 1407527Sjkh if (character(p->v_value) == *v) 1417527Sjkh return; 14288276Smarkm setcharacter(p->v_value, *v); 1437527Sjkh } 1447527Sjkh p->v_access |= CHANGED; 1457527Sjkh} 1467527Sjkh 1477527Sjkhstatic void vprint(); 14888276Smarkmstatic void vtoken(); 1497527Sjkh 15028365Scharniervoid 1517527Sjkhvlex(s) 15288276Smarkm char *s; 1537527Sjkh{ 15488276Smarkm value_t *p; 1557527Sjkh 1567527Sjkh if (equal(s, "all")) { 1577527Sjkh for (p = vtable; p->v_name; p++) 1587527Sjkh if (vaccess(p->v_access, READ)) 1597527Sjkh vprint(p); 1607527Sjkh } else { 16188276Smarkm char *cp; 1627527Sjkh 1637527Sjkh do { 16428365Scharnier if ((cp = vinterp(s, ' '))) 1657527Sjkh cp++; 1667527Sjkh vtoken(s); 1677527Sjkh s = cp; 1687527Sjkh } while (s); 1697527Sjkh } 1707527Sjkh if (col > 0) { 1717527Sjkh printf("\r\n"); 1727527Sjkh col = 0; 1737527Sjkh } 1747527Sjkh} 1757527Sjkh 1767527Sjkhstatic void 1777527Sjkhvtoken(s) 17888276Smarkm char *s; 1797527Sjkh{ 18088276Smarkm value_t *p; 18188276Smarkm char *cp; 1827527Sjkh char *expand(); 1837527Sjkh 18488276Smarkm if ((cp = strchr(s, '='))) { 1857527Sjkh *cp = '\0'; 18628365Scharnier if ((p = vlookup(s))) { 1877527Sjkh cp++; 1887527Sjkh if (p->v_type&NUMBER) 18988276Smarkm vassign(p, atoi(cp)); 1907527Sjkh else { 1917527Sjkh if (strcmp(s, "record") == 0) 1927527Sjkh cp = expand(cp); 1937527Sjkh vassign(p, cp); 1947527Sjkh } 1957527Sjkh return; 1967527Sjkh } 19788276Smarkm } else if ((cp = strchr(s, '?'))) { 1987527Sjkh *cp = '\0'; 1997527Sjkh if ((p = vlookup(s)) && vaccess(p->v_access, READ)) { 2007527Sjkh vprint(p); 2017527Sjkh return; 2027527Sjkh } 2037527Sjkh } else { 2047527Sjkh if (*s != '!') 2057527Sjkh p = vlookup(s); 2067527Sjkh else 2077527Sjkh p = vlookup(s+1); 2087527Sjkh if (p != NOVAL) { 2097527Sjkh vassign(p, s); 2107527Sjkh return; 2117527Sjkh } 2127527Sjkh } 2137527Sjkh printf("%s: unknown variable\r\n", s); 2147527Sjkh} 2157527Sjkh 2167527Sjkhstatic void 2177527Sjkhvprint(p) 21888276Smarkm value_t *p; 2197527Sjkh{ 22088276Smarkm char *cp; 2217527Sjkh 2227527Sjkh if (col > 0 && col < MIDDLE) 2237527Sjkh while (col++ < MIDDLE) 2247527Sjkh putchar(' '); 2257527Sjkh col += size(p->v_name); 2267527Sjkh switch (p->v_type&TMASK) { 2277527Sjkh 2287527Sjkh case BOOL: 2297527Sjkh if (boolean(p->v_value) == FALSE) { 2307527Sjkh col++; 2317527Sjkh putchar('!'); 2327527Sjkh } 2337527Sjkh printf("%s", p->v_name); 2347527Sjkh break; 2357527Sjkh 2367527Sjkh case STRING: 2377527Sjkh printf("%s=", p->v_name); 2387527Sjkh col++; 2397527Sjkh if (p->v_value) { 240129004Sstefanf cp = interp(p->v_value); 2417527Sjkh col += size(cp); 2427527Sjkh printf("%s", cp); 2437527Sjkh } 2447527Sjkh break; 2457527Sjkh 2467527Sjkh case NUMBER: 2477527Sjkh col += 6; 24888276Smarkm printf("%s=%-5ld", p->v_name, number(p->v_value)); 2497527Sjkh break; 2507527Sjkh 2517527Sjkh case CHAR: 2527527Sjkh printf("%s=", p->v_name); 2537527Sjkh col++; 2547527Sjkh if (p->v_value) { 2557527Sjkh cp = ctrl(character(p->v_value)); 2567527Sjkh col += size(cp); 2577527Sjkh printf("%s", cp); 2587527Sjkh } 2597527Sjkh break; 2607527Sjkh } 2617527Sjkh if (col >= MIDDLE) { 2627527Sjkh col = 0; 2637527Sjkh printf("\r\n"); 2647527Sjkh return; 2657527Sjkh } 2667527Sjkh} 2677527Sjkh 2687527Sjkh 2697527Sjkhstatic int 2707527Sjkhvaccess(mode, rw) 27188276Smarkm unsigned mode, rw; 2727527Sjkh{ 2737527Sjkh if (mode & (rw<<PUBLIC)) 2747527Sjkh return (1); 2757527Sjkh if (mode & (rw<<PRIVATE)) 2767527Sjkh return (1); 2777527Sjkh return ((mode & (rw<<ROOT)) && getuid() == 0); 2787527Sjkh} 2797527Sjkh 2807527Sjkhstatic value_t * 2817527Sjkhvlookup(s) 28288276Smarkm char *s; 2837527Sjkh{ 28488276Smarkm value_t *p; 2857527Sjkh 2867527Sjkh for (p = vtable; p->v_name; p++) 2877527Sjkh if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s))) 2887527Sjkh return (p); 2897527Sjkh return (NULL); 2907527Sjkh} 2917527Sjkh 2927527Sjkhchar * 2937527Sjkhvinterp(s, stop) 29488276Smarkm char *s; 2957527Sjkh char stop; 2967527Sjkh{ 29788276Smarkm char *p = s, c; 2987527Sjkh int num; 2997527Sjkh 3007527Sjkh while ((c = *s++) && c != stop) 3017527Sjkh switch (c) { 3027527Sjkh 3037527Sjkh case '^': 3047527Sjkh if (*s) 3057527Sjkh *p++ = *s++ - 0100; 3067527Sjkh else 3077527Sjkh *p++ = c; 3087527Sjkh break; 3097527Sjkh 3107527Sjkh case '\\': 3117527Sjkh num = 0; 3127527Sjkh c = *s++; 3137527Sjkh if (c >= '0' && c <= '7') 3147527Sjkh num = (num<<3)+(c-'0'); 3157527Sjkh else { 31688276Smarkm char *q = "n\nr\rt\tb\bf\f"; 3177527Sjkh 3187527Sjkh for (; *q; q++) 3197527Sjkh if (c == *q++) { 3207527Sjkh *p++ = *q; 3217527Sjkh goto cont; 3227527Sjkh } 3237527Sjkh *p++ = c; 3247527Sjkh cont: 3257527Sjkh break; 3267527Sjkh } 3277527Sjkh if ((c = *s++) >= '0' && c <= '7') { 3287527Sjkh num = (num<<3)+(c-'0'); 3297527Sjkh if ((c = *s++) >= '0' && c <= '7') 3307527Sjkh num = (num<<3)+(c-'0'); 3317527Sjkh else 3327527Sjkh s--; 3337527Sjkh } else 3347527Sjkh s--; 3357527Sjkh *p++ = num; 3367527Sjkh break; 3377527Sjkh 3387527Sjkh default: 3397527Sjkh *p++ = c; 3407527Sjkh } 3417527Sjkh *p = '\0'; 3427527Sjkh return (c == stop ? s-1 : NULL); 3437527Sjkh} 3447527Sjkh 3457527Sjkh/* 3467527Sjkh * assign variable s with value v (for NUMBER or STRING or CHAR types) 3477527Sjkh */ 34828365Scharnierint 3497527Sjkhvstring(s,v) 35088276Smarkm char *s; 35188276Smarkm char *v; 3527527Sjkh{ 35388276Smarkm value_t *p; 3547527Sjkh char *expand(); 3557527Sjkh 35688276Smarkm p = vlookup(s); 3577527Sjkh if (p == 0) 3587527Sjkh return (1); 3597527Sjkh if (p->v_type&NUMBER) 36088276Smarkm vassign(p, atoi(v)); 3617527Sjkh else { 3627527Sjkh if (strcmp(s, "record") == 0) 3637527Sjkh v = expand(v); 3647527Sjkh vassign(p, v); 3657527Sjkh } 3667527Sjkh return (0); 3677527Sjkh} 368