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