value.c revision 28365
17527Sjkh/* 27527Sjkh * Copyright (c) 1983, 1993 37527Sjkh * The Regents of the University of California. All rights reserved. 47527Sjkh * 57527Sjkh * Redistribution and use in source and binary forms, with or without 67527Sjkh * modification, are permitted provided that the following conditions 77527Sjkh * are met: 87527Sjkh * 1. Redistributions of source code must retain the above copyright 97527Sjkh * notice, this list of conditions and the following disclaimer. 107527Sjkh * 2. Redistributions in binary form must reproduce the above copyright 117527Sjkh * notice, this list of conditions and the following disclaimer in the 127527Sjkh * documentation and/or other materials provided with the distribution. 137527Sjkh * 3. All advertising materials mentioning features or use of this software 147527Sjkh * must display the following acknowledgement: 157527Sjkh * This product includes software developed by the University of 167527Sjkh * California, Berkeley and its contributors. 177527Sjkh * 4. Neither the name of the University nor the names of its contributors 187527Sjkh * may be used to endorse or promote products derived from this software 197527Sjkh * without specific prior written permission. 207527Sjkh * 217527Sjkh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 227527Sjkh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 237527Sjkh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 247527Sjkh * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 257527Sjkh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 267527Sjkh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 277527Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 287527Sjkh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 297527Sjkh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 307527Sjkh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 317527Sjkh * SUCH DAMAGE. 327527Sjkh */ 337527Sjkh 347527Sjkh#ifndef lint 3528365Scharnier#if 0 367527Sjkhstatic char sccsid[] = "@(#)value.c 8.1 (Berkeley) 6/6/93"; 3728365Scharnier#endif 3828365Scharnierstatic const char rcsid[] = 3928365Scharnier "$Id$"; 407527Sjkh#endif /* not lint */ 417527Sjkh 427527Sjkh#include "tip.h" 437527Sjkh 447527Sjkh#define MIDDLE 35 457527Sjkh 467527Sjkhstatic value_t *vlookup(); 4728365Scharnierint vstring __P((char *, char *)); 4828365Scharniervoid vlex __P((char *)); 4928365Scharniervoid vassign __P((value_t *, char *)); 5028365Scharnier 517527Sjkhstatic int col = 0; 527527Sjkh 537527Sjkh/* 547527Sjkh * Variable manipulation 557527Sjkh */ 5628365Scharniervoid 577527Sjkhvinit() 587527Sjkh{ 597527Sjkh register value_t *p; 607527Sjkh register char *cp; 617527Sjkh FILE *f; 627527Sjkh char file[256]; 637527Sjkh 647527Sjkh for (p = vtable; p->v_name != NULL; p++) { 657527Sjkh if (p->v_type&ENVIRON) 6628365Scharnier if ((cp = getenv(p->v_name))) 677527Sjkh p->v_value = cp; 687527Sjkh if (p->v_type&IREMOTE) 697527Sjkh number(p->v_value) = *address(p->v_value); 707527Sjkh } 717527Sjkh /* 727527Sjkh * Read the .tiprc file in the HOME directory 737527Sjkh * for sets 747527Sjkh */ 757527Sjkh strcpy(file, value(HOME)); 767527Sjkh strcat(file, "/.tiprc"); 777527Sjkh if ((f = fopen(file, "r")) != NULL) { 787527Sjkh register char *tp; 797527Sjkh 807527Sjkh while (fgets(file, sizeof(file)-1, f) != NULL) { 817527Sjkh if (vflag) 827527Sjkh printf("set %s", file); 8328365Scharnier if ((tp = rindex(file, '\n'))) 847527Sjkh *tp = '\0'; 857527Sjkh vlex(file); 867527Sjkh } 877527Sjkh fclose(f); 887527Sjkh } 897527Sjkh /* 907527Sjkh * To allow definition of exception prior to fork 917527Sjkh */ 927527Sjkh vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC); 937527Sjkh} 947527Sjkh 957527Sjkhstatic int vaccess(); 967527Sjkh 977527Sjkh/*VARARGS1*/ 9828365Scharniervoid 997527Sjkhvassign(p, v) 1007527Sjkh register value_t *p; 1017527Sjkh char *v; 1027527Sjkh{ 1037527Sjkh 1047527Sjkh if (!vaccess(p->v_access, WRITE)) { 1057527Sjkh printf("access denied\r\n"); 1067527Sjkh return; 1077527Sjkh } 1087527Sjkh switch (p->v_type&TMASK) { 1097527Sjkh 1107527Sjkh case STRING: 1117527Sjkh if (p->v_value && equal(p->v_value, v)) 1127527Sjkh return; 1137527Sjkh if (!(p->v_type&(ENVIRON|INIT))) 1147527Sjkh free(p->v_value); 1157527Sjkh if ((p->v_value = malloc(size(v)+1)) == NOSTR) { 1167527Sjkh printf("out of core\r\n"); 1177527Sjkh return; 1187527Sjkh } 1197527Sjkh p->v_type &= ~(ENVIRON|INIT); 1207527Sjkh strcpy(p->v_value, v); 1217527Sjkh break; 1227527Sjkh 1237527Sjkh case NUMBER: 1247527Sjkh if (number(p->v_value) == number(v)) 1257527Sjkh return; 1267527Sjkh number(p->v_value) = number(v); 1277527Sjkh break; 1287527Sjkh 1297527Sjkh case BOOL: 1307527Sjkh if (boolean(p->v_value) == (*v != '!')) 1317527Sjkh return; 1327527Sjkh boolean(p->v_value) = (*v != '!'); 1337527Sjkh break; 1347527Sjkh 1357527Sjkh case CHAR: 1367527Sjkh if (character(p->v_value) == *v) 1377527Sjkh return; 1387527Sjkh character(p->v_value) = *v; 1397527Sjkh } 1407527Sjkh p->v_access |= CHANGED; 1417527Sjkh} 1427527Sjkh 1437527Sjkhstatic void vprint(); 1447527Sjkh 14528365Scharniervoid 1467527Sjkhvlex(s) 1477527Sjkh register char *s; 1487527Sjkh{ 1497527Sjkh register value_t *p; 1507527Sjkh static void vtoken(); 1517527Sjkh 1527527Sjkh if (equal(s, "all")) { 1537527Sjkh for (p = vtable; p->v_name; p++) 1547527Sjkh if (vaccess(p->v_access, READ)) 1557527Sjkh vprint(p); 1567527Sjkh } else { 1577527Sjkh register char *cp; 1587527Sjkh 1597527Sjkh do { 16028365Scharnier if ((cp = vinterp(s, ' '))) 1617527Sjkh cp++; 1627527Sjkh vtoken(s); 1637527Sjkh s = cp; 1647527Sjkh } while (s); 1657527Sjkh } 1667527Sjkh if (col > 0) { 1677527Sjkh printf("\r\n"); 1687527Sjkh col = 0; 1697527Sjkh } 1707527Sjkh} 1717527Sjkh 1727527Sjkhstatic void 1737527Sjkhvtoken(s) 1747527Sjkh register char *s; 1757527Sjkh{ 1767527Sjkh register value_t *p; 1777527Sjkh register char *cp; 1787527Sjkh char *expand(); 1797527Sjkh 18028365Scharnier if ((cp = index(s, '='))) { 1817527Sjkh *cp = '\0'; 18228365Scharnier if ((p = vlookup(s))) { 1837527Sjkh cp++; 1847527Sjkh if (p->v_type&NUMBER) 1857527Sjkh vassign(p, atoi(cp)); 1867527Sjkh else { 1877527Sjkh if (strcmp(s, "record") == 0) 1887527Sjkh cp = expand(cp); 1897527Sjkh vassign(p, cp); 1907527Sjkh } 1917527Sjkh return; 1927527Sjkh } 19328365Scharnier } else if ((cp = index(s, '?'))) { 1947527Sjkh *cp = '\0'; 1957527Sjkh if ((p = vlookup(s)) && vaccess(p->v_access, READ)) { 1967527Sjkh vprint(p); 1977527Sjkh return; 1987527Sjkh } 1997527Sjkh } else { 2007527Sjkh if (*s != '!') 2017527Sjkh p = vlookup(s); 2027527Sjkh else 2037527Sjkh p = vlookup(s+1); 2047527Sjkh if (p != NOVAL) { 2057527Sjkh vassign(p, s); 2067527Sjkh return; 2077527Sjkh } 2087527Sjkh } 2097527Sjkh printf("%s: unknown variable\r\n", s); 2107527Sjkh} 2117527Sjkh 2127527Sjkhstatic void 2137527Sjkhvprint(p) 2147527Sjkh register value_t *p; 2157527Sjkh{ 2167527Sjkh register char *cp; 2177527Sjkh extern char *interp(), *ctrl(); 2187527Sjkh 2197527Sjkh if (col > 0 && col < MIDDLE) 2207527Sjkh while (col++ < MIDDLE) 2217527Sjkh putchar(' '); 2227527Sjkh col += size(p->v_name); 2237527Sjkh switch (p->v_type&TMASK) { 2247527Sjkh 2257527Sjkh case BOOL: 2267527Sjkh if (boolean(p->v_value) == FALSE) { 2277527Sjkh col++; 2287527Sjkh putchar('!'); 2297527Sjkh } 2307527Sjkh printf("%s", p->v_name); 2317527Sjkh break; 2327527Sjkh 2337527Sjkh case STRING: 2347527Sjkh printf("%s=", p->v_name); 2357527Sjkh col++; 2367527Sjkh if (p->v_value) { 2377527Sjkh cp = interp(p->v_value, NULL); 2387527Sjkh col += size(cp); 2397527Sjkh printf("%s", cp); 2407527Sjkh } 2417527Sjkh break; 2427527Sjkh 2437527Sjkh case NUMBER: 2447527Sjkh col += 6; 2457527Sjkh printf("%s=%-5d", p->v_name, number(p->v_value)); 2467527Sjkh break; 2477527Sjkh 2487527Sjkh case CHAR: 2497527Sjkh printf("%s=", p->v_name); 2507527Sjkh col++; 2517527Sjkh if (p->v_value) { 2527527Sjkh cp = ctrl(character(p->v_value)); 2537527Sjkh col += size(cp); 2547527Sjkh printf("%s", cp); 2557527Sjkh } 2567527Sjkh break; 2577527Sjkh } 2587527Sjkh if (col >= MIDDLE) { 2597527Sjkh col = 0; 2607527Sjkh printf("\r\n"); 2617527Sjkh return; 2627527Sjkh } 2637527Sjkh} 2647527Sjkh 2657527Sjkh 2667527Sjkhstatic int 2677527Sjkhvaccess(mode, rw) 2687527Sjkh register unsigned mode, rw; 2697527Sjkh{ 2707527Sjkh if (mode & (rw<<PUBLIC)) 2717527Sjkh return (1); 2727527Sjkh if (mode & (rw<<PRIVATE)) 2737527Sjkh return (1); 2747527Sjkh return ((mode & (rw<<ROOT)) && getuid() == 0); 2757527Sjkh} 2767527Sjkh 2777527Sjkhstatic value_t * 2787527Sjkhvlookup(s) 2797527Sjkh register char *s; 2807527Sjkh{ 2817527Sjkh register value_t *p; 2827527Sjkh 2837527Sjkh for (p = vtable; p->v_name; p++) 2847527Sjkh if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s))) 2857527Sjkh return (p); 2867527Sjkh return (NULL); 2877527Sjkh} 2887527Sjkh 2897527Sjkhchar * 2907527Sjkhvinterp(s, stop) 2917527Sjkh register char *s; 2927527Sjkh char stop; 2937527Sjkh{ 2947527Sjkh register char *p = s, c; 2957527Sjkh int num; 2967527Sjkh 2977527Sjkh while ((c = *s++) && c != stop) 2987527Sjkh switch (c) { 2997527Sjkh 3007527Sjkh case '^': 3017527Sjkh if (*s) 3027527Sjkh *p++ = *s++ - 0100; 3037527Sjkh else 3047527Sjkh *p++ = c; 3057527Sjkh break; 3067527Sjkh 3077527Sjkh case '\\': 3087527Sjkh num = 0; 3097527Sjkh c = *s++; 3107527Sjkh if (c >= '0' && c <= '7') 3117527Sjkh num = (num<<3)+(c-'0'); 3127527Sjkh else { 3137527Sjkh register char *q = "n\nr\rt\tb\bf\f"; 3147527Sjkh 3157527Sjkh for (; *q; q++) 3167527Sjkh if (c == *q++) { 3177527Sjkh *p++ = *q; 3187527Sjkh goto cont; 3197527Sjkh } 3207527Sjkh *p++ = c; 3217527Sjkh cont: 3227527Sjkh break; 3237527Sjkh } 3247527Sjkh if ((c = *s++) >= '0' && c <= '7') { 3257527Sjkh num = (num<<3)+(c-'0'); 3267527Sjkh if ((c = *s++) >= '0' && c <= '7') 3277527Sjkh num = (num<<3)+(c-'0'); 3287527Sjkh else 3297527Sjkh s--; 3307527Sjkh } else 3317527Sjkh s--; 3327527Sjkh *p++ = num; 3337527Sjkh break; 3347527Sjkh 3357527Sjkh default: 3367527Sjkh *p++ = c; 3377527Sjkh } 3387527Sjkh *p = '\0'; 3397527Sjkh return (c == stop ? s-1 : NULL); 3407527Sjkh} 3417527Sjkh 3427527Sjkh/* 3437527Sjkh * assign variable s with value v (for NUMBER or STRING or CHAR types) 3447527Sjkh */ 3457527Sjkh 34628365Scharnierint 3477527Sjkhvstring(s,v) 3487527Sjkh register char *s; 3497527Sjkh register char *v; 3507527Sjkh{ 3517527Sjkh register value_t *p; 3527527Sjkh char *expand(); 3537527Sjkh 3548874Srgrimes p = vlookup(s); 3557527Sjkh if (p == 0) 3567527Sjkh return (1); 3577527Sjkh if (p->v_type&NUMBER) 3587527Sjkh vassign(p, atoi(v)); 3597527Sjkh else { 3607527Sjkh if (strcmp(s, "record") == 0) 3617527Sjkh v = expand(v); 3627527Sjkh vassign(p, v); 3637527Sjkh } 3647527Sjkh return (0); 3657527Sjkh} 366