value.c revision 28365
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
3528365Scharnier#if 0
367527Sjkhstatic char sccsid[] = "@(#)value.c	8.1 (Berkeley) 6/6/93";
3728365Scharnier#endif
3828365Scharnierstatic const char rcsid[] =
3928365Scharnier	"$Id$";
407527Sjkh#endif /* not lint */
417527Sjkh
427527Sjkh#include "tip.h"
437527Sjkh
447527Sjkh#define MIDDLE	35
457527Sjkh
467527Sjkhstatic value_t *vlookup();
4728365Scharnierint vstring __P((char *, char *));
4828365Scharniervoid vlex __P((char *));
4928365Scharniervoid vassign __P((value_t *, char *));
5028365Scharnier
517527Sjkhstatic int col = 0;
527527Sjkh
537527Sjkh/*
547527Sjkh * Variable manipulation
557527Sjkh */
5628365Scharniervoid
577527Sjkhvinit()
587527Sjkh{
597527Sjkh	register value_t *p;
607527Sjkh	register char *cp;
617527Sjkh	FILE *f;
627527Sjkh	char file[256];
637527Sjkh
647527Sjkh	for (p = vtable; p->v_name != NULL; p++) {
657527Sjkh		if (p->v_type&ENVIRON)
6628365Scharnier			if ((cp = getenv(p->v_name)))
677527Sjkh				p->v_value = cp;
687527Sjkh		if (p->v_type&IREMOTE)
697527Sjkh			number(p->v_value) = *address(p->v_value);
707527Sjkh	}
717527Sjkh	/*
727527Sjkh	 * Read the .tiprc file in the HOME directory
737527Sjkh	 *  for sets
747527Sjkh	 */
757527Sjkh	strcpy(file, value(HOME));
767527Sjkh	strcat(file, "/.tiprc");
777527Sjkh	if ((f = fopen(file, "r")) != NULL) {
787527Sjkh		register char *tp;
797527Sjkh
807527Sjkh		while (fgets(file, sizeof(file)-1, f) != NULL) {
817527Sjkh			if (vflag)
827527Sjkh				printf("set %s", file);
8328365Scharnier			if ((tp = rindex(file, '\n')))
847527Sjkh				*tp = '\0';
857527Sjkh			vlex(file);
867527Sjkh		}
877527Sjkh		fclose(f);
887527Sjkh	}
897527Sjkh	/*
907527Sjkh	 * To allow definition of exception prior to fork
917527Sjkh	 */
927527Sjkh	vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC);
937527Sjkh}
947527Sjkh
957527Sjkhstatic int vaccess();
967527Sjkh
977527Sjkh/*VARARGS1*/
9828365Scharniervoid
997527Sjkhvassign(p, v)
1007527Sjkh	register value_t *p;
1017527Sjkh	char *v;
1027527Sjkh{
1037527Sjkh
1047527Sjkh	if (!vaccess(p->v_access, WRITE)) {
1057527Sjkh		printf("access denied\r\n");
1067527Sjkh		return;
1077527Sjkh	}
1087527Sjkh	switch (p->v_type&TMASK) {
1097527Sjkh
1107527Sjkh	case STRING:
1117527Sjkh		if (p->v_value && equal(p->v_value, v))
1127527Sjkh			return;
1137527Sjkh		if (!(p->v_type&(ENVIRON|INIT)))
1147527Sjkh			free(p->v_value);
1157527Sjkh		if ((p->v_value = malloc(size(v)+1)) == NOSTR) {
1167527Sjkh			printf("out of core\r\n");
1177527Sjkh			return;
1187527Sjkh		}
1197527Sjkh		p->v_type &= ~(ENVIRON|INIT);
1207527Sjkh		strcpy(p->v_value, v);
1217527Sjkh		break;
1227527Sjkh
1237527Sjkh	case NUMBER:
1247527Sjkh		if (number(p->v_value) == number(v))
1257527Sjkh			return;
1267527Sjkh		number(p->v_value) = number(v);
1277527Sjkh		break;
1287527Sjkh
1297527Sjkh	case BOOL:
1307527Sjkh		if (boolean(p->v_value) == (*v != '!'))
1317527Sjkh			return;
1327527Sjkh		boolean(p->v_value) = (*v != '!');
1337527Sjkh		break;
1347527Sjkh
1357527Sjkh	case CHAR:
1367527Sjkh		if (character(p->v_value) == *v)
1377527Sjkh			return;
1387527Sjkh		character(p->v_value) = *v;
1397527Sjkh	}
1407527Sjkh	p->v_access |= CHANGED;
1417527Sjkh}
1427527Sjkh
1437527Sjkhstatic void vprint();
1447527Sjkh
14528365Scharniervoid
1467527Sjkhvlex(s)
1477527Sjkh	register char *s;
1487527Sjkh{
1497527Sjkh	register value_t *p;
1507527Sjkh	static void vtoken();
1517527Sjkh
1527527Sjkh	if (equal(s, "all")) {
1537527Sjkh		for (p = vtable; p->v_name; p++)
1547527Sjkh			if (vaccess(p->v_access, READ))
1557527Sjkh				vprint(p);
1567527Sjkh	} else {
1577527Sjkh		register char *cp;
1587527Sjkh
1597527Sjkh		do {
16028365Scharnier			if ((cp = vinterp(s, ' ')))
1617527Sjkh				cp++;
1627527Sjkh			vtoken(s);
1637527Sjkh			s = cp;
1647527Sjkh		} while (s);
1657527Sjkh	}
1667527Sjkh	if (col > 0) {
1677527Sjkh		printf("\r\n");
1687527Sjkh		col = 0;
1697527Sjkh	}
1707527Sjkh}
1717527Sjkh
1727527Sjkhstatic void
1737527Sjkhvtoken(s)
1747527Sjkh	register char *s;
1757527Sjkh{
1767527Sjkh	register value_t *p;
1777527Sjkh	register char *cp;
1787527Sjkh	char *expand();
1797527Sjkh
18028365Scharnier	if ((cp = index(s, '='))) {
1817527Sjkh		*cp = '\0';
18228365Scharnier		if ((p = vlookup(s))) {
1837527Sjkh			cp++;
1847527Sjkh			if (p->v_type&NUMBER)
1857527Sjkh				vassign(p, atoi(cp));
1867527Sjkh			else {
1877527Sjkh				if (strcmp(s, "record") == 0)
1887527Sjkh					cp = expand(cp);
1897527Sjkh				vassign(p, cp);
1907527Sjkh			}
1917527Sjkh			return;
1927527Sjkh		}
19328365Scharnier	} else if ((cp = index(s, '?'))) {
1947527Sjkh		*cp = '\0';
1957527Sjkh		if ((p = vlookup(s)) && vaccess(p->v_access, READ)) {
1967527Sjkh			vprint(p);
1977527Sjkh			return;
1987527Sjkh		}
1997527Sjkh	} else {
2007527Sjkh		if (*s != '!')
2017527Sjkh			p = vlookup(s);
2027527Sjkh		else
2037527Sjkh			p = vlookup(s+1);
2047527Sjkh		if (p != NOVAL) {
2057527Sjkh			vassign(p, s);
2067527Sjkh			return;
2077527Sjkh		}
2087527Sjkh	}
2097527Sjkh	printf("%s: unknown variable\r\n", s);
2107527Sjkh}
2117527Sjkh
2127527Sjkhstatic void
2137527Sjkhvprint(p)
2147527Sjkh	register value_t *p;
2157527Sjkh{
2167527Sjkh	register char *cp;
2177527Sjkh	extern char *interp(), *ctrl();
2187527Sjkh
2197527Sjkh	if (col > 0 && col < MIDDLE)
2207527Sjkh		while (col++ < MIDDLE)
2217527Sjkh			putchar(' ');
2227527Sjkh	col += size(p->v_name);
2237527Sjkh	switch (p->v_type&TMASK) {
2247527Sjkh
2257527Sjkh	case BOOL:
2267527Sjkh		if (boolean(p->v_value) == FALSE) {
2277527Sjkh			col++;
2287527Sjkh			putchar('!');
2297527Sjkh		}
2307527Sjkh		printf("%s", p->v_name);
2317527Sjkh		break;
2327527Sjkh
2337527Sjkh	case STRING:
2347527Sjkh		printf("%s=", p->v_name);
2357527Sjkh		col++;
2367527Sjkh		if (p->v_value) {
2377527Sjkh			cp = interp(p->v_value, NULL);
2387527Sjkh			col += size(cp);
2397527Sjkh			printf("%s", cp);
2407527Sjkh		}
2417527Sjkh		break;
2427527Sjkh
2437527Sjkh	case NUMBER:
2447527Sjkh		col += 6;
2457527Sjkh		printf("%s=%-5d", p->v_name, number(p->v_value));
2467527Sjkh		break;
2477527Sjkh
2487527Sjkh	case CHAR:
2497527Sjkh		printf("%s=", p->v_name);
2507527Sjkh		col++;
2517527Sjkh		if (p->v_value) {
2527527Sjkh			cp = ctrl(character(p->v_value));
2537527Sjkh			col += size(cp);
2547527Sjkh			printf("%s", cp);
2557527Sjkh		}
2567527Sjkh		break;
2577527Sjkh	}
2587527Sjkh	if (col >= MIDDLE) {
2597527Sjkh		col = 0;
2607527Sjkh		printf("\r\n");
2617527Sjkh		return;
2627527Sjkh	}
2637527Sjkh}
2647527Sjkh
2657527Sjkh
2667527Sjkhstatic int
2677527Sjkhvaccess(mode, rw)
2687527Sjkh	register unsigned mode, rw;
2697527Sjkh{
2707527Sjkh	if (mode & (rw<<PUBLIC))
2717527Sjkh		return (1);
2727527Sjkh	if (mode & (rw<<PRIVATE))
2737527Sjkh		return (1);
2747527Sjkh	return ((mode & (rw<<ROOT)) && getuid() == 0);
2757527Sjkh}
2767527Sjkh
2777527Sjkhstatic value_t *
2787527Sjkhvlookup(s)
2797527Sjkh	register char *s;
2807527Sjkh{
2817527Sjkh	register value_t *p;
2827527Sjkh
2837527Sjkh	for (p = vtable; p->v_name; p++)
2847527Sjkh		if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
2857527Sjkh			return (p);
2867527Sjkh	return (NULL);
2877527Sjkh}
2887527Sjkh
2897527Sjkhchar *
2907527Sjkhvinterp(s, stop)
2917527Sjkh	register char *s;
2927527Sjkh	char stop;
2937527Sjkh{
2947527Sjkh	register char *p = s, c;
2957527Sjkh	int num;
2967527Sjkh
2977527Sjkh	while ((c = *s++) && c != stop)
2987527Sjkh		switch (c) {
2997527Sjkh
3007527Sjkh		case '^':
3017527Sjkh			if (*s)
3027527Sjkh				*p++ = *s++ - 0100;
3037527Sjkh			else
3047527Sjkh				*p++ = c;
3057527Sjkh			break;
3067527Sjkh
3077527Sjkh		case '\\':
3087527Sjkh			num = 0;
3097527Sjkh			c = *s++;
3107527Sjkh			if (c >= '0' && c <= '7')
3117527Sjkh				num = (num<<3)+(c-'0');
3127527Sjkh			else {
3137527Sjkh				register char *q = "n\nr\rt\tb\bf\f";
3147527Sjkh
3157527Sjkh				for (; *q; q++)
3167527Sjkh					if (c == *q++) {
3177527Sjkh						*p++ = *q;
3187527Sjkh						goto cont;
3197527Sjkh					}
3207527Sjkh				*p++ = c;
3217527Sjkh			cont:
3227527Sjkh				break;
3237527Sjkh			}
3247527Sjkh			if ((c = *s++) >= '0' && c <= '7') {
3257527Sjkh				num = (num<<3)+(c-'0');
3267527Sjkh				if ((c = *s++) >= '0' && c <= '7')
3277527Sjkh					num = (num<<3)+(c-'0');
3287527Sjkh				else
3297527Sjkh					s--;
3307527Sjkh			} else
3317527Sjkh				s--;
3327527Sjkh			*p++ = num;
3337527Sjkh			break;
3347527Sjkh
3357527Sjkh		default:
3367527Sjkh			*p++ = c;
3377527Sjkh		}
3387527Sjkh	*p = '\0';
3397527Sjkh	return (c == stop ? s-1 : NULL);
3407527Sjkh}
3417527Sjkh
3427527Sjkh/*
3437527Sjkh * assign variable s with value v (for NUMBER or STRING or CHAR types)
3447527Sjkh */
3457527Sjkh
34628365Scharnierint
3477527Sjkhvstring(s,v)
3487527Sjkh	register char *s;
3497527Sjkh	register char *v;
3507527Sjkh{
3517527Sjkh	register value_t *p;
3527527Sjkh	char *expand();
3537527Sjkh
3548874Srgrimes	p = vlookup(s);
3557527Sjkh	if (p == 0)
3567527Sjkh		return (1);
3577527Sjkh	if (p->v_type&NUMBER)
3587527Sjkh		vassign(p, atoi(v));
3597527Sjkh	else {
3607527Sjkh		if (strcmp(s, "record") == 0)
3617527Sjkh			v = expand(v);
3627527Sjkh		vassign(p, v);
3637527Sjkh	}
3647527Sjkh	return (0);
3657527Sjkh}
366