value.c revision 7527
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 357527Sjkhstatic char sccsid[] = "@(#)value.c 8.1 (Berkeley) 6/6/93"; 367527Sjkh#endif /* not lint */ 377527Sjkh 387527Sjkh#include "tip.h" 397527Sjkh 407527Sjkh#define MIDDLE 35 417527Sjkh 427527Sjkhstatic value_t *vlookup(); 437527Sjkhstatic int col = 0; 447527Sjkh 457527Sjkh/* 467527Sjkh * Variable manipulation 477527Sjkh */ 487527Sjkhvinit() 497527Sjkh{ 507527Sjkh register value_t *p; 517527Sjkh register char *cp; 527527Sjkh FILE *f; 537527Sjkh char file[256]; 547527Sjkh 557527Sjkh for (p = vtable; p->v_name != NULL; p++) { 567527Sjkh if (p->v_type&ENVIRON) 577527Sjkh if (cp = getenv(p->v_name)) 587527Sjkh p->v_value = cp; 597527Sjkh if (p->v_type&IREMOTE) 607527Sjkh number(p->v_value) = *address(p->v_value); 617527Sjkh } 627527Sjkh /* 637527Sjkh * Read the .tiprc file in the HOME directory 647527Sjkh * for sets 657527Sjkh */ 667527Sjkh strcpy(file, value(HOME)); 677527Sjkh strcat(file, "/.tiprc"); 687527Sjkh if ((f = fopen(file, "r")) != NULL) { 697527Sjkh register char *tp; 707527Sjkh 717527Sjkh while (fgets(file, sizeof(file)-1, f) != NULL) { 727527Sjkh if (vflag) 737527Sjkh printf("set %s", file); 747527Sjkh if (tp = rindex(file, '\n')) 757527Sjkh *tp = '\0'; 767527Sjkh vlex(file); 777527Sjkh } 787527Sjkh fclose(f); 797527Sjkh } 807527Sjkh /* 817527Sjkh * To allow definition of exception prior to fork 827527Sjkh */ 837527Sjkh vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC); 847527Sjkh} 857527Sjkh 867527Sjkhstatic int vaccess(); 877527Sjkh 887527Sjkh/*VARARGS1*/ 897527Sjkhvassign(p, v) 907527Sjkh register value_t *p; 917527Sjkh char *v; 927527Sjkh{ 937527Sjkh 947527Sjkh if (!vaccess(p->v_access, WRITE)) { 957527Sjkh printf("access denied\r\n"); 967527Sjkh return; 977527Sjkh } 987527Sjkh switch (p->v_type&TMASK) { 997527Sjkh 1007527Sjkh case STRING: 1017527Sjkh if (p->v_value && equal(p->v_value, v)) 1027527Sjkh return; 1037527Sjkh if (!(p->v_type&(ENVIRON|INIT))) 1047527Sjkh free(p->v_value); 1057527Sjkh if ((p->v_value = malloc(size(v)+1)) == NOSTR) { 1067527Sjkh printf("out of core\r\n"); 1077527Sjkh return; 1087527Sjkh } 1097527Sjkh p->v_type &= ~(ENVIRON|INIT); 1107527Sjkh strcpy(p->v_value, v); 1117527Sjkh break; 1127527Sjkh 1137527Sjkh case NUMBER: 1147527Sjkh if (number(p->v_value) == number(v)) 1157527Sjkh return; 1167527Sjkh number(p->v_value) = number(v); 1177527Sjkh break; 1187527Sjkh 1197527Sjkh case BOOL: 1207527Sjkh if (boolean(p->v_value) == (*v != '!')) 1217527Sjkh return; 1227527Sjkh boolean(p->v_value) = (*v != '!'); 1237527Sjkh break; 1247527Sjkh 1257527Sjkh case CHAR: 1267527Sjkh if (character(p->v_value) == *v) 1277527Sjkh return; 1287527Sjkh character(p->v_value) = *v; 1297527Sjkh } 1307527Sjkh p->v_access |= CHANGED; 1317527Sjkh} 1327527Sjkh 1337527Sjkhstatic void vprint(); 1347527Sjkh 1357527Sjkhvlex(s) 1367527Sjkh register char *s; 1377527Sjkh{ 1387527Sjkh register value_t *p; 1397527Sjkh static void vtoken(); 1407527Sjkh 1417527Sjkh if (equal(s, "all")) { 1427527Sjkh for (p = vtable; p->v_name; p++) 1437527Sjkh if (vaccess(p->v_access, READ)) 1447527Sjkh vprint(p); 1457527Sjkh } else { 1467527Sjkh register char *cp; 1477527Sjkh 1487527Sjkh do { 1497527Sjkh if (cp = vinterp(s, ' ')) 1507527Sjkh cp++; 1517527Sjkh vtoken(s); 1527527Sjkh s = cp; 1537527Sjkh } while (s); 1547527Sjkh } 1557527Sjkh if (col > 0) { 1567527Sjkh printf("\r\n"); 1577527Sjkh col = 0; 1587527Sjkh } 1597527Sjkh} 1607527Sjkh 1617527Sjkhstatic void 1627527Sjkhvtoken(s) 1637527Sjkh register char *s; 1647527Sjkh{ 1657527Sjkh register value_t *p; 1667527Sjkh register char *cp; 1677527Sjkh char *expand(); 1687527Sjkh 1697527Sjkh if (cp = index(s, '=')) { 1707527Sjkh *cp = '\0'; 1717527Sjkh if (p = vlookup(s)) { 1727527Sjkh cp++; 1737527Sjkh if (p->v_type&NUMBER) 1747527Sjkh vassign(p, atoi(cp)); 1757527Sjkh else { 1767527Sjkh if (strcmp(s, "record") == 0) 1777527Sjkh cp = expand(cp); 1787527Sjkh vassign(p, cp); 1797527Sjkh } 1807527Sjkh return; 1817527Sjkh } 1827527Sjkh } else if (cp = index(s, '?')) { 1837527Sjkh *cp = '\0'; 1847527Sjkh if ((p = vlookup(s)) && vaccess(p->v_access, READ)) { 1857527Sjkh vprint(p); 1867527Sjkh return; 1877527Sjkh } 1887527Sjkh } else { 1897527Sjkh if (*s != '!') 1907527Sjkh p = vlookup(s); 1917527Sjkh else 1927527Sjkh p = vlookup(s+1); 1937527Sjkh if (p != NOVAL) { 1947527Sjkh vassign(p, s); 1957527Sjkh return; 1967527Sjkh } 1977527Sjkh } 1987527Sjkh printf("%s: unknown variable\r\n", s); 1997527Sjkh} 2007527Sjkh 2017527Sjkhstatic void 2027527Sjkhvprint(p) 2037527Sjkh register value_t *p; 2047527Sjkh{ 2057527Sjkh register char *cp; 2067527Sjkh extern char *interp(), *ctrl(); 2077527Sjkh 2087527Sjkh if (col > 0 && col < MIDDLE) 2097527Sjkh while (col++ < MIDDLE) 2107527Sjkh putchar(' '); 2117527Sjkh col += size(p->v_name); 2127527Sjkh switch (p->v_type&TMASK) { 2137527Sjkh 2147527Sjkh case BOOL: 2157527Sjkh if (boolean(p->v_value) == FALSE) { 2167527Sjkh col++; 2177527Sjkh putchar('!'); 2187527Sjkh } 2197527Sjkh printf("%s", p->v_name); 2207527Sjkh break; 2217527Sjkh 2227527Sjkh case STRING: 2237527Sjkh printf("%s=", p->v_name); 2247527Sjkh col++; 2257527Sjkh if (p->v_value) { 2267527Sjkh cp = interp(p->v_value, NULL); 2277527Sjkh col += size(cp); 2287527Sjkh printf("%s", cp); 2297527Sjkh } 2307527Sjkh break; 2317527Sjkh 2327527Sjkh case NUMBER: 2337527Sjkh col += 6; 2347527Sjkh printf("%s=%-5d", p->v_name, number(p->v_value)); 2357527Sjkh break; 2367527Sjkh 2377527Sjkh case CHAR: 2387527Sjkh printf("%s=", p->v_name); 2397527Sjkh col++; 2407527Sjkh if (p->v_value) { 2417527Sjkh cp = ctrl(character(p->v_value)); 2427527Sjkh col += size(cp); 2437527Sjkh printf("%s", cp); 2447527Sjkh } 2457527Sjkh break; 2467527Sjkh } 2477527Sjkh if (col >= MIDDLE) { 2487527Sjkh col = 0; 2497527Sjkh printf("\r\n"); 2507527Sjkh return; 2517527Sjkh } 2527527Sjkh} 2537527Sjkh 2547527Sjkh 2557527Sjkhstatic int 2567527Sjkhvaccess(mode, rw) 2577527Sjkh register unsigned mode, rw; 2587527Sjkh{ 2597527Sjkh if (mode & (rw<<PUBLIC)) 2607527Sjkh return (1); 2617527Sjkh if (mode & (rw<<PRIVATE)) 2627527Sjkh return (1); 2637527Sjkh return ((mode & (rw<<ROOT)) && getuid() == 0); 2647527Sjkh} 2657527Sjkh 2667527Sjkhstatic value_t * 2677527Sjkhvlookup(s) 2687527Sjkh register char *s; 2697527Sjkh{ 2707527Sjkh register value_t *p; 2717527Sjkh 2727527Sjkh for (p = vtable; p->v_name; p++) 2737527Sjkh if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s))) 2747527Sjkh return (p); 2757527Sjkh return (NULL); 2767527Sjkh} 2777527Sjkh 2787527Sjkhchar * 2797527Sjkhvinterp(s, stop) 2807527Sjkh register char *s; 2817527Sjkh char stop; 2827527Sjkh{ 2837527Sjkh register char *p = s, c; 2847527Sjkh int num; 2857527Sjkh 2867527Sjkh while ((c = *s++) && c != stop) 2877527Sjkh switch (c) { 2887527Sjkh 2897527Sjkh case '^': 2907527Sjkh if (*s) 2917527Sjkh *p++ = *s++ - 0100; 2927527Sjkh else 2937527Sjkh *p++ = c; 2947527Sjkh break; 2957527Sjkh 2967527Sjkh case '\\': 2977527Sjkh num = 0; 2987527Sjkh c = *s++; 2997527Sjkh if (c >= '0' && c <= '7') 3007527Sjkh num = (num<<3)+(c-'0'); 3017527Sjkh else { 3027527Sjkh register char *q = "n\nr\rt\tb\bf\f"; 3037527Sjkh 3047527Sjkh for (; *q; q++) 3057527Sjkh if (c == *q++) { 3067527Sjkh *p++ = *q; 3077527Sjkh goto cont; 3087527Sjkh } 3097527Sjkh *p++ = c; 3107527Sjkh cont: 3117527Sjkh break; 3127527Sjkh } 3137527Sjkh if ((c = *s++) >= '0' && c <= '7') { 3147527Sjkh num = (num<<3)+(c-'0'); 3157527Sjkh if ((c = *s++) >= '0' && c <= '7') 3167527Sjkh num = (num<<3)+(c-'0'); 3177527Sjkh else 3187527Sjkh s--; 3197527Sjkh } else 3207527Sjkh s--; 3217527Sjkh *p++ = num; 3227527Sjkh break; 3237527Sjkh 3247527Sjkh default: 3257527Sjkh *p++ = c; 3267527Sjkh } 3277527Sjkh *p = '\0'; 3287527Sjkh return (c == stop ? s-1 : NULL); 3297527Sjkh} 3307527Sjkh 3317527Sjkh/* 3327527Sjkh * assign variable s with value v (for NUMBER or STRING or CHAR types) 3337527Sjkh */ 3347527Sjkh 3357527Sjkhvstring(s,v) 3367527Sjkh register char *s; 3377527Sjkh register char *v; 3387527Sjkh{ 3397527Sjkh register value_t *p; 3407527Sjkh char *expand(); 3417527Sjkh 3427527Sjkh p = vlookup(s); 3437527Sjkh if (p == 0) 3447527Sjkh return (1); 3457527Sjkh if (p->v_type&NUMBER) 3467527Sjkh vassign(p, atoi(v)); 3477527Sjkh else { 3487527Sjkh if (strcmp(s, "record") == 0) 3497527Sjkh v = expand(v); 3507527Sjkh vassign(p, v); 3517527Sjkh } 3527527Sjkh return (0); 3537527Sjkh} 354