119802Sdist /* 235464Sbostic * Copyright (c) 1983 The Regents of the University of California. 335464Sbostic * All rights reserved. 435464Sbostic * 5*42770Sbostic * %sccs.include.redist.c% 619802Sdist */ 719802Sdist 813280Ssam #ifndef lint 9*42770Sbostic static char sccsid[] = "@(#)value.c 5.3 (Berkeley) 06/01/90"; 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 603700Sroot /*VARARGS1*/ 613700Sroot vassign(p, v) 624963Ssam register value_t *p; 634963Ssam char *v; 643700Sroot { 653700Sroot 663700Sroot if (!vaccess(p->v_access, WRITE)) { 673700Sroot printf("access denied\r\n"); 683700Sroot return; 693700Sroot } 705138Ssam switch (p->v_type&TMASK) { 713700Sroot 725138Ssam case STRING: 735138Ssam if (equal(p->v_value, v)) 745138Ssam return; 755138Ssam if (!(p->v_type&(ENVIRON|INIT))) 765138Ssam free(p->v_value); 775138Ssam if ((p->v_value = malloc(size(v)+1)) == NOSTR) { 785138Ssam printf("out of core\r\n"); 795138Ssam return; 805138Ssam } 815138Ssam p->v_type &= ~(ENVIRON|INIT); 825138Ssam strcpy(p->v_value, v); 835138Ssam break; 843700Sroot 855138Ssam case NUMBER: 865138Ssam if (number(p->v_value) == number(v)) 875138Ssam return; 885138Ssam number(p->v_value) = number(v); 895138Ssam break; 903700Sroot 915138Ssam case BOOL: 925138Ssam if (boolean(p->v_value) == (*v != '!')) 935138Ssam return; 945138Ssam boolean(p->v_value) = (*v != '!'); 955138Ssam break; 963700Sroot 975138Ssam case CHAR: 985138Ssam if (character(p->v_value) == *v) 995138Ssam return; 1005138Ssam character(p->v_value) = *v; 1013700Sroot } 1023700Sroot p->v_access |= CHANGED; 1033700Sroot } 1043700Sroot 1053700Sroot vlex(s) 1064963Ssam register char *s; 1073700Sroot { 1083700Sroot register value_t *p; 1093700Sroot 1103700Sroot if (equal(s, "all")) { 1113700Sroot for (p = vtable; p->v_name; p++) 1123700Sroot if (vaccess(p->v_access, READ)) 1133700Sroot vprint(p); 1143700Sroot } else { 1153700Sroot register char *cp; 1163700Sroot 1173700Sroot do { 1183700Sroot if (cp = vinterp(s, ' ')) 1193700Sroot cp++; 1203700Sroot vtoken(s); 1213700Sroot s = cp; 1223700Sroot } while (s); 1233700Sroot } 1243700Sroot if (col > 0) { 1253700Sroot printf("\r\n"); 1263700Sroot col = 0; 1273700Sroot } 1283700Sroot } 1293700Sroot 1303700Sroot static int 1313700Sroot vtoken(s) 1324963Ssam register char *s; 1333700Sroot { 1343700Sroot register value_t *p; 1353700Sroot register char *cp; 13613140Sralph char *expand(); 1373700Sroot 1383700Sroot if (cp = index(s, '=')) { 1393700Sroot *cp = '\0'; 1403700Sroot if (p = vlookup(s)) { 1413700Sroot cp++; 1423700Sroot if (p->v_type&NUMBER) 1433700Sroot vassign(p, atoi(cp)); 14413140Sralph else { 14513140Sralph if (strcmp(s, "record") == 0) 14613140Sralph cp = expand(cp); 1473700Sroot vassign(p, cp); 14813140Sralph } 1493700Sroot return; 1503700Sroot } 1513700Sroot } else if (cp = index(s, '?')) { 1523700Sroot *cp = '\0'; 1533700Sroot if ((p = vlookup(s)) && vaccess(p->v_access, READ)) { 1543700Sroot vprint(p); 1553700Sroot return; 1563700Sroot } 1573700Sroot } else { 1583700Sroot if (*s != '!') 1593700Sroot p = vlookup(s); 1603700Sroot else 1613700Sroot p = vlookup(s+1); 1623700Sroot if (p != NOVAL) { 1633700Sroot vassign(p, s); 1643700Sroot return; 1653700Sroot } 1663700Sroot } 1673700Sroot printf("%s: unknown variable\r\n", s); 1683700Sroot } 1693700Sroot 1703700Sroot static int 1713700Sroot vprint(p) 1724963Ssam register value_t *p; 1733700Sroot { 1743700Sroot register char *cp; 1753700Sroot extern char *interp(), *ctrl(); 1763700Sroot 1773700Sroot if (col > 0 && col < MIDDLE) 1783700Sroot while (col++ < MIDDLE) 1793700Sroot putchar(' '); 1803700Sroot col += size(p->v_name); 1815138Ssam switch (p->v_type&TMASK) { 1825138Ssam 1835138Ssam case BOOL: 1845138Ssam if (boolean(p->v_value) == FALSE) { 1853700Sroot col++; 1865138Ssam putchar('!'); 1875138Ssam } 1885138Ssam printf("%s", p->v_name); 1895138Ssam break; 1905138Ssam 1915138Ssam case STRING: 1925138Ssam printf("%s=", p->v_name); 1935138Ssam col++; 1945138Ssam if (p->v_value) { 19513140Sralph cp = interp(p->v_value, NULL); 1965138Ssam col += size(cp); 1975138Ssam printf("%s", cp); 1985138Ssam } 1995138Ssam break; 2005138Ssam 2015138Ssam case NUMBER: 2025138Ssam col += 6; 2035138Ssam printf("%s=%-5d", p->v_name, number(p->v_value)); 2045138Ssam break; 2055138Ssam 2065138Ssam case CHAR: 2075138Ssam printf("%s=", p->v_name); 2085138Ssam col++; 2095138Ssam if (p->v_value) { 2105138Ssam cp = ctrl(character(p->v_value)); 2115138Ssam col += size(cp); 2125138Ssam printf("%s", cp); 2135138Ssam } 2145138Ssam break; 2153700Sroot } 2163700Sroot if (col >= MIDDLE) { 2173700Sroot col = 0; 2183700Sroot printf("\r\n"); 2193700Sroot return; 2203700Sroot } 2213700Sroot } 2223700Sroot 2233700Sroot 2243700Sroot static int 2253700Sroot vaccess(mode, rw) 2264963Ssam register unsigned mode, rw; 2273700Sroot { 2283700Sroot if (mode & (rw<<PUBLIC)) 2295138Ssam return (1); 2303700Sroot if (mode & (rw<<PRIVATE)) 2315138Ssam return (1); 2325138Ssam return ((mode & (rw<<ROOT)) && getuid() == 0); 2333700Sroot } 2343700Sroot 2353700Sroot static value_t * 2363700Sroot vlookup(s) 2374963Ssam register char *s; 2383700Sroot { 2393700Sroot register value_t *p; 2403700Sroot 2413700Sroot for (p = vtable; p->v_name; p++) 2423700Sroot if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s))) 2435138Ssam return (p); 2445138Ssam return (NULL); 2453700Sroot } 2463700Sroot 2473700Sroot char * 2483700Sroot vinterp(s, stop) 2494963Ssam register char *s; 2505138Ssam char stop; 2513700Sroot { 2523700Sroot register char *p = s, c; 2533700Sroot int num; 2543700Sroot 2555138Ssam while ((c = *s++) && c != stop) 2565138Ssam switch (c) { 2575138Ssam 2583700Sroot case '^': 2593700Sroot if (*s) 2603700Sroot *p++ = *s++ - 0100; 2613700Sroot else 2623700Sroot *p++ = c; 2633700Sroot break; 2643700Sroot 2653700Sroot case '\\': 2663700Sroot num = 0; 2673700Sroot c = *s++; 2683700Sroot if (c >= '0' && c <= '7') 2693700Sroot num = (num<<3)+(c-'0'); 2703700Sroot else { 2713700Sroot register char *q = "n\nr\rt\tb\bf\f"; 2723700Sroot 2733700Sroot for (; *q; q++) 2743700Sroot if (c == *q++) { 2753700Sroot *p++ = *q; 2763700Sroot goto cont; 2773700Sroot } 2783700Sroot *p++ = c; 2793700Sroot cont: 2803700Sroot break; 2813700Sroot } 2823700Sroot if ((c = *s++) >= '0' && c <= '7') { 2833700Sroot num = (num<<3)+(c-'0'); 2843700Sroot if ((c = *s++) >= '0' && c <= '7') 2853700Sroot num = (num<<3)+(c-'0'); 2863700Sroot else 2873700Sroot s--; 2883700Sroot } else 2893700Sroot s--; 2903700Sroot *p++ = num; 2913700Sroot break; 2923700Sroot 2933700Sroot default: 2943700Sroot *p++ = c; 2955138Ssam } 2963700Sroot *p = '\0'; 2975138Ssam return (c == stop ? s-1 : NULL); 2983700Sroot } 29913140Sralph 30013140Sralph /* 30113140Sralph * assign variable s with value v (for NUMBER or STRING or CHAR types) 30213140Sralph */ 30313140Sralph 30413140Sralph vstring(s,v) 30513140Sralph register char *s; 30613140Sralph register char *v; 30713140Sralph { 30813140Sralph register value_t *p; 30913140Sralph char *expand(); 31013140Sralph 31113280Ssam p = vlookup(s); 31213280Ssam if (p == 0) 31313280Ssam return (1); 31413280Ssam if (p->v_type&NUMBER) 31513280Ssam vassign(p, atoi(v)); 31613280Ssam else { 31713280Ssam if (strcmp(s, "record") == 0) 31813280Ssam v = expand(v); 31913280Ssam vassign(p, v); 32013280Ssam } 32113280Ssam return (0); 32213140Sralph } 323