xref: /csrg-svn/usr.bin/tip/value.c (revision 62315)
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