119802Sdist /*
2*62315Sbostic * Copyright (c) 1983, 1993
3*62315Sbostic * The Regents of the University of California. All rights reserved.
435464Sbostic *
542770Sbostic * %sccs.include.redist.c%
619802Sdist */
719802Sdist
813280Ssam #ifndef lint
9*62315Sbostic static char sccsid[] = "@(#)value.c 8.1 (Berkeley) 06/06/93";
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 */
vinit()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
6046866Sbostic static int vaccess();
6146866Sbostic
623700Sroot /*VARARGS1*/
vassign(p,v)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
10746866Sbostic static void vprint();
10846866Sbostic
vlex(s)1093700Sroot vlex(s)
1104963Ssam register char *s;
1113700Sroot {
1123700Sroot register value_t *p;
11346866Sbostic 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
13546866Sbostic static void
vtoken(s)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
17546866Sbostic static void
vprint(p)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
vaccess(mode,rw)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 *
vlookup(s)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 *
vinterp(s,stop)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
vstring(s,v)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