119802Sdist /* 235464Sbostic * Copyright (c) 1983 The Regents of the University of California. 335464Sbostic * All rights reserved. 435464Sbostic * 542770Sbostic * %sccs.include.redist.c% 619802Sdist */ 719802Sdist 813280Ssam #ifndef lint 9*46866Sbostic static char sccsid[] = "@(#)value.c 5.5 (Berkeley) 03/02/91"; 1035464Sbostic #endif /* not lint */ 1113280Ssam 123700Sroot #include "tip.h" 133700Sroot 143700Sroot #define MIDDLE 35 153700Sroot 163700Sroot static value_t *vlookup(); 173700Sroot static int col = 0; 183700Sroot 193700Sroot /* 203700Sroot * Variable manipulation 213700Sroot */ 223700Sroot vinit() 233700Sroot { 243700Sroot register value_t *p; 253700Sroot register char *cp; 263700Sroot FILE *f; 273700Sroot char file[256]; 283700Sroot 293700Sroot for (p = vtable; p->v_name != NULL; p++) { 303700Sroot if (p->v_type&ENVIRON) 313700Sroot if (cp = getenv(p->v_name)) 323700Sroot p->v_value = cp; 333700Sroot if (p->v_type&IREMOTE) 343700Sroot number(p->v_value) = *address(p->v_value); 353700Sroot } 363700Sroot /* 373700Sroot * Read the .tiprc file in the HOME directory 383700Sroot * for sets 393700Sroot */ 403700Sroot strcpy(file, value(HOME)); 413700Sroot strcat(file, "/.tiprc"); 423700Sroot if ((f = fopen(file, "r")) != NULL) { 433700Sroot register char *tp; 443700Sroot 453700Sroot while (fgets(file, sizeof(file)-1, f) != NULL) { 463700Sroot if (vflag) 473700Sroot printf("set %s", file); 483700Sroot if (tp = rindex(file, '\n')) 493700Sroot *tp = '\0'; 503700Sroot vlex(file); 513700Sroot } 523700Sroot fclose(f); 533700Sroot } 543700Sroot /* 553700Sroot * To allow definition of exception prior to fork 563700Sroot */ 573700Sroot vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC); 583700Sroot } 593700Sroot 60*46866Sbostic static int vaccess(); 61*46866Sbostic 623700Sroot /*VARARGS1*/ 633700Sroot vassign(p, v) 644963Ssam register value_t *p; 654963Ssam char *v; 663700Sroot { 673700Sroot 683700Sroot if (!vaccess(p->v_access, WRITE)) { 693700Sroot printf("access denied\r\n"); 703700Sroot return; 713700Sroot } 725138Ssam switch (p->v_type&TMASK) { 733700Sroot 745138Ssam case STRING: 7545842Stef if (p->v_value && equal(p->v_value, v)) 765138Ssam return; 775138Ssam if (!(p->v_type&(ENVIRON|INIT))) 785138Ssam free(p->v_value); 795138Ssam if ((p->v_value = malloc(size(v)+1)) == NOSTR) { 805138Ssam printf("out of core\r\n"); 815138Ssam return; 825138Ssam } 835138Ssam p->v_type &= ~(ENVIRON|INIT); 845138Ssam strcpy(p->v_value, v); 855138Ssam break; 863700Sroot 875138Ssam case NUMBER: 885138Ssam if (number(p->v_value) == number(v)) 895138Ssam return; 905138Ssam number(p->v_value) = number(v); 915138Ssam break; 923700Sroot 935138Ssam case BOOL: 945138Ssam if (boolean(p->v_value) == (*v != '!')) 955138Ssam return; 965138Ssam boolean(p->v_value) = (*v != '!'); 975138Ssam break; 983700Sroot 995138Ssam case CHAR: 1005138Ssam if (character(p->v_value) == *v) 1015138Ssam return; 1025138Ssam character(p->v_value) = *v; 1033700Sroot } 1043700Sroot p->v_access |= CHANGED; 1053700Sroot } 1063700Sroot 107*46866Sbostic static void vprint(); 108*46866Sbostic 1093700Sroot vlex(s) 1104963Ssam register char *s; 1113700Sroot { 1123700Sroot register value_t *p; 113*46866Sbostic static void vtoken(); 1143700Sroot 1153700Sroot if (equal(s, "all")) { 1163700Sroot for (p = vtable; p->v_name; p++) 1173700Sroot if (vaccess(p->v_access, READ)) 1183700Sroot vprint(p); 1193700Sroot } else { 1203700Sroot register char *cp; 1213700Sroot 1223700Sroot do { 1233700Sroot if (cp = vinterp(s, ' ')) 1243700Sroot cp++; 1253700Sroot vtoken(s); 1263700Sroot s = cp; 1273700Sroot } while (s); 1283700Sroot } 1293700Sroot if (col > 0) { 1303700Sroot printf("\r\n"); 1313700Sroot col = 0; 1323700Sroot } 1333700Sroot } 1343700Sroot 135*46866Sbostic static void 1363700Sroot vtoken(s) 1374963Ssam register char *s; 1383700Sroot { 1393700Sroot register value_t *p; 1403700Sroot register char *cp; 14113140Sralph char *expand(); 1423700Sroot 1433700Sroot if (cp = index(s, '=')) { 1443700Sroot *cp = '\0'; 1453700Sroot if (p = vlookup(s)) { 1463700Sroot cp++; 1473700Sroot if (p->v_type&NUMBER) 1483700Sroot vassign(p, atoi(cp)); 14913140Sralph else { 15013140Sralph if (strcmp(s, "record") == 0) 15113140Sralph cp = expand(cp); 1523700Sroot vassign(p, cp); 15313140Sralph } 1543700Sroot return; 1553700Sroot } 1563700Sroot } else if (cp = index(s, '?')) { 1573700Sroot *cp = '\0'; 1583700Sroot if ((p = vlookup(s)) && vaccess(p->v_access, READ)) { 1593700Sroot vprint(p); 1603700Sroot return; 1613700Sroot } 1623700Sroot } else { 1633700Sroot if (*s != '!') 1643700Sroot p = vlookup(s); 1653700Sroot else 1663700Sroot p = vlookup(s+1); 1673700Sroot if (p != NOVAL) { 1683700Sroot vassign(p, s); 1693700Sroot return; 1703700Sroot } 1713700Sroot } 1723700Sroot printf("%s: unknown variable\r\n", s); 1733700Sroot } 1743700Sroot 175*46866Sbostic static void 1763700Sroot vprint(p) 1774963Ssam register value_t *p; 1783700Sroot { 1793700Sroot register char *cp; 1803700Sroot extern char *interp(), *ctrl(); 1813700Sroot 1823700Sroot if (col > 0 && col < MIDDLE) 1833700Sroot while (col++ < MIDDLE) 1843700Sroot putchar(' '); 1853700Sroot col += size(p->v_name); 1865138Ssam switch (p->v_type&TMASK) { 1875138Ssam 1885138Ssam case BOOL: 1895138Ssam if (boolean(p->v_value) == FALSE) { 1903700Sroot col++; 1915138Ssam putchar('!'); 1925138Ssam } 1935138Ssam printf("%s", p->v_name); 1945138Ssam break; 1955138Ssam 1965138Ssam case STRING: 1975138Ssam printf("%s=", p->v_name); 1985138Ssam col++; 1995138Ssam if (p->v_value) { 20013140Sralph cp = interp(p->v_value, NULL); 2015138Ssam col += size(cp); 2025138Ssam printf("%s", cp); 2035138Ssam } 2045138Ssam break; 2055138Ssam 2065138Ssam case NUMBER: 2075138Ssam col += 6; 2085138Ssam printf("%s=%-5d", p->v_name, number(p->v_value)); 2095138Ssam break; 2105138Ssam 2115138Ssam case CHAR: 2125138Ssam printf("%s=", p->v_name); 2135138Ssam col++; 2145138Ssam if (p->v_value) { 2155138Ssam cp = ctrl(character(p->v_value)); 2165138Ssam col += size(cp); 2175138Ssam printf("%s", cp); 2185138Ssam } 2195138Ssam break; 2203700Sroot } 2213700Sroot if (col >= MIDDLE) { 2223700Sroot col = 0; 2233700Sroot printf("\r\n"); 2243700Sroot return; 2253700Sroot } 2263700Sroot } 2273700Sroot 2283700Sroot 2293700Sroot static int 2303700Sroot vaccess(mode, rw) 2314963Ssam register unsigned mode, rw; 2323700Sroot { 2333700Sroot if (mode & (rw<<PUBLIC)) 2345138Ssam return (1); 2353700Sroot if (mode & (rw<<PRIVATE)) 2365138Ssam return (1); 2375138Ssam return ((mode & (rw<<ROOT)) && getuid() == 0); 2383700Sroot } 2393700Sroot 2403700Sroot static value_t * 2413700Sroot vlookup(s) 2424963Ssam register char *s; 2433700Sroot { 2443700Sroot register value_t *p; 2453700Sroot 2463700Sroot for (p = vtable; p->v_name; p++) 2473700Sroot if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s))) 2485138Ssam return (p); 2495138Ssam return (NULL); 2503700Sroot } 2513700Sroot 2523700Sroot char * 2533700Sroot vinterp(s, stop) 2544963Ssam register char *s; 2555138Ssam char stop; 2563700Sroot { 2573700Sroot register char *p = s, c; 2583700Sroot int num; 2593700Sroot 2605138Ssam while ((c = *s++) && c != stop) 2615138Ssam switch (c) { 2625138Ssam 2633700Sroot case '^': 2643700Sroot if (*s) 2653700Sroot *p++ = *s++ - 0100; 2663700Sroot else 2673700Sroot *p++ = c; 2683700Sroot break; 2693700Sroot 2703700Sroot case '\\': 2713700Sroot num = 0; 2723700Sroot c = *s++; 2733700Sroot if (c >= '0' && c <= '7') 2743700Sroot num = (num<<3)+(c-'0'); 2753700Sroot else { 2763700Sroot register char *q = "n\nr\rt\tb\bf\f"; 2773700Sroot 2783700Sroot for (; *q; q++) 2793700Sroot if (c == *q++) { 2803700Sroot *p++ = *q; 2813700Sroot goto cont; 2823700Sroot } 2833700Sroot *p++ = c; 2843700Sroot cont: 2853700Sroot break; 2863700Sroot } 2873700Sroot if ((c = *s++) >= '0' && c <= '7') { 2883700Sroot num = (num<<3)+(c-'0'); 2893700Sroot if ((c = *s++) >= '0' && c <= '7') 2903700Sroot num = (num<<3)+(c-'0'); 2913700Sroot else 2923700Sroot s--; 2933700Sroot } else 2943700Sroot s--; 2953700Sroot *p++ = num; 2963700Sroot break; 2973700Sroot 2983700Sroot default: 2993700Sroot *p++ = c; 3005138Ssam } 3013700Sroot *p = '\0'; 3025138Ssam return (c == stop ? s-1 : NULL); 3033700Sroot } 30413140Sralph 30513140Sralph /* 30613140Sralph * assign variable s with value v (for NUMBER or STRING or CHAR types) 30713140Sralph */ 30813140Sralph 30913140Sralph vstring(s,v) 31013140Sralph register char *s; 31113140Sralph register char *v; 31213140Sralph { 31313140Sralph register value_t *p; 31413140Sralph char *expand(); 31513140Sralph 31613280Ssam p = vlookup(s); 31713280Ssam if (p == 0) 31813280Ssam return (1); 31913280Ssam if (p->v_type&NUMBER) 32013280Ssam vassign(p, atoi(v)); 32113280Ssam else { 32213280Ssam if (strcmp(s, "record") == 0) 32313280Ssam v = expand(v); 32413280Ssam vassign(p, v); 32513280Ssam } 32613280Ssam return (0); 32713140Sralph } 328