xref: /titanic_52/usr/src/cmd/tip/value.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * Copyright (c) 2000 by Sun Microsystems, Inc.
3*7c478bd9Sstevel@tonic-gate  * All rights reserved.
4*7c478bd9Sstevel@tonic-gate  */
5*7c478bd9Sstevel@tonic-gate 
6*7c478bd9Sstevel@tonic-gate /* from UCB 4.5 6/25/83 */
7*7c478bd9Sstevel@tonic-gate /*
8*7c478bd9Sstevel@tonic-gate  * Copyright (c) 1983 Regents of the University of California.
9*7c478bd9Sstevel@tonic-gate  * All rights reserved. The Berkeley software License Agreement
10*7c478bd9Sstevel@tonic-gate  * specifies the terms and conditions for redistribution.
11*7c478bd9Sstevel@tonic-gate  */
12*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
13*7c478bd9Sstevel@tonic-gate 
14*7c478bd9Sstevel@tonic-gate #include "tip.h"
15*7c478bd9Sstevel@tonic-gate 
16*7c478bd9Sstevel@tonic-gate #define	MIDDLE	35
17*7c478bd9Sstevel@tonic-gate 
18*7c478bd9Sstevel@tonic-gate static value_t *vlookup();
19*7c478bd9Sstevel@tonic-gate static int col = 0;
20*7c478bd9Sstevel@tonic-gate 
21*7c478bd9Sstevel@tonic-gate /*
22*7c478bd9Sstevel@tonic-gate  * Variable manipulation
23*7c478bd9Sstevel@tonic-gate  */
24*7c478bd9Sstevel@tonic-gate vinit()
25*7c478bd9Sstevel@tonic-gate {
26*7c478bd9Sstevel@tonic-gate 	register value_t *p;
27*7c478bd9Sstevel@tonic-gate 	register char *cp;
28*7c478bd9Sstevel@tonic-gate 	FILE *f;
29*7c478bd9Sstevel@tonic-gate 	char file[1024];
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate 	for (p = vtable; p->v_name != NULL; p++) {
32*7c478bd9Sstevel@tonic-gate 		if (p->v_type&ENVIRON)
33*7c478bd9Sstevel@tonic-gate 			if (cp = getenv(p->v_name))
34*7c478bd9Sstevel@tonic-gate 				p->v_value = cp;
35*7c478bd9Sstevel@tonic-gate 		if (p->v_type&IREMOTE)
36*7c478bd9Sstevel@tonic-gate 			number(p->v_value) = *address(p->v_value);
37*7c478bd9Sstevel@tonic-gate 	}
38*7c478bd9Sstevel@tonic-gate 	/*
39*7c478bd9Sstevel@tonic-gate 	 * Read the .tiprc file in the HOME directory
40*7c478bd9Sstevel@tonic-gate 	 *  for sets
41*7c478bd9Sstevel@tonic-gate 	 */
42*7c478bd9Sstevel@tonic-gate 	if ((cp = value(HOME)) == NULL)
43*7c478bd9Sstevel@tonic-gate 		cp = "";
44*7c478bd9Sstevel@tonic-gate 	strlcpy(file, cp, sizeof (file));
45*7c478bd9Sstevel@tonic-gate 	strlcat(file, "/.tiprc", sizeof (file));
46*7c478bd9Sstevel@tonic-gate 	if ((f = fopen(file, "r")) != NULL) {
47*7c478bd9Sstevel@tonic-gate 		register char *tp;
48*7c478bd9Sstevel@tonic-gate 
49*7c478bd9Sstevel@tonic-gate 		while (fgets(file, sizeof (file)-1, f) != NULL) {
50*7c478bd9Sstevel@tonic-gate 			if (file[0] == '#')
51*7c478bd9Sstevel@tonic-gate 				continue;
52*7c478bd9Sstevel@tonic-gate 			if (vflag)
53*7c478bd9Sstevel@tonic-gate 				printf("set %s", file);
54*7c478bd9Sstevel@tonic-gate 			if (tp = strrchr(file, '\n'))
55*7c478bd9Sstevel@tonic-gate 				*tp = '\0';
56*7c478bd9Sstevel@tonic-gate 			vlex(file);
57*7c478bd9Sstevel@tonic-gate 		}
58*7c478bd9Sstevel@tonic-gate 		fclose(f);
59*7c478bd9Sstevel@tonic-gate 	}
60*7c478bd9Sstevel@tonic-gate 	/*
61*7c478bd9Sstevel@tonic-gate 	 * To allow definition of exception prior to fork
62*7c478bd9Sstevel@tonic-gate 	 */
63*7c478bd9Sstevel@tonic-gate 	vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC);
64*7c478bd9Sstevel@tonic-gate }
65*7c478bd9Sstevel@tonic-gate 
66*7c478bd9Sstevel@tonic-gate /*VARARGS1*/
67*7c478bd9Sstevel@tonic-gate vassign(p, v)
68*7c478bd9Sstevel@tonic-gate 	register value_t *p;
69*7c478bd9Sstevel@tonic-gate 	char *v;
70*7c478bd9Sstevel@tonic-gate {
71*7c478bd9Sstevel@tonic-gate 
72*7c478bd9Sstevel@tonic-gate 	if (!vaccess(p->v_access, WRITE)) {
73*7c478bd9Sstevel@tonic-gate 		printf("access denied\r\n");
74*7c478bd9Sstevel@tonic-gate 		return;
75*7c478bd9Sstevel@tonic-gate 	}
76*7c478bd9Sstevel@tonic-gate 	switch (p->v_type&TMASK) {
77*7c478bd9Sstevel@tonic-gate 
78*7c478bd9Sstevel@tonic-gate 	case STRING:
79*7c478bd9Sstevel@tonic-gate 		if (p->v_value != (char *)NULL) {
80*7c478bd9Sstevel@tonic-gate 			if (equal(p->v_value, v))
81*7c478bd9Sstevel@tonic-gate 				return;
82*7c478bd9Sstevel@tonic-gate 			if (!(p->v_type&(ENVIRON|INIT)))
83*7c478bd9Sstevel@tonic-gate 				free(p->v_value);
84*7c478bd9Sstevel@tonic-gate 		}
85*7c478bd9Sstevel@tonic-gate 		if ((p->v_value = malloc(strlen(v)+1)) == NOSTR) {
86*7c478bd9Sstevel@tonic-gate 			printf("out of core\r\n");
87*7c478bd9Sstevel@tonic-gate 			return;
88*7c478bd9Sstevel@tonic-gate 		}
89*7c478bd9Sstevel@tonic-gate 		p->v_type &= ~(ENVIRON|INIT);
90*7c478bd9Sstevel@tonic-gate 		strcpy(p->v_value, v);
91*7c478bd9Sstevel@tonic-gate 		break;
92*7c478bd9Sstevel@tonic-gate 
93*7c478bd9Sstevel@tonic-gate 	case NUMBER:
94*7c478bd9Sstevel@tonic-gate 		if (number(p->v_value) == number(v))
95*7c478bd9Sstevel@tonic-gate 			return;
96*7c478bd9Sstevel@tonic-gate 		number(p->v_value) = number(v);
97*7c478bd9Sstevel@tonic-gate 		break;
98*7c478bd9Sstevel@tonic-gate 
99*7c478bd9Sstevel@tonic-gate 	case BOOL:
100*7c478bd9Sstevel@tonic-gate 		if (boolean(p->v_value) == (*v != '!'))
101*7c478bd9Sstevel@tonic-gate 			return;
102*7c478bd9Sstevel@tonic-gate 		boolean(p->v_value) = (*v != '!');
103*7c478bd9Sstevel@tonic-gate 		break;
104*7c478bd9Sstevel@tonic-gate 
105*7c478bd9Sstevel@tonic-gate 	case CHAR:
106*7c478bd9Sstevel@tonic-gate 		if (character(p->v_value) == *v)
107*7c478bd9Sstevel@tonic-gate 			return;
108*7c478bd9Sstevel@tonic-gate 		character(p->v_value) = *v;
109*7c478bd9Sstevel@tonic-gate 	}
110*7c478bd9Sstevel@tonic-gate 	p->v_access |= CHANGED;
111*7c478bd9Sstevel@tonic-gate }
112*7c478bd9Sstevel@tonic-gate 
113*7c478bd9Sstevel@tonic-gate vlex(s)
114*7c478bd9Sstevel@tonic-gate 	register char *s;
115*7c478bd9Sstevel@tonic-gate {
116*7c478bd9Sstevel@tonic-gate 	register value_t *p;
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate 	if (equal(s, "all")) {
119*7c478bd9Sstevel@tonic-gate 		for (p = vtable; p->v_name; p++)
120*7c478bd9Sstevel@tonic-gate 			if (vaccess(p->v_access, READ))
121*7c478bd9Sstevel@tonic-gate 				vprint(p);
122*7c478bd9Sstevel@tonic-gate 	} else {
123*7c478bd9Sstevel@tonic-gate 		register char *cp;
124*7c478bd9Sstevel@tonic-gate 
125*7c478bd9Sstevel@tonic-gate 		do {
126*7c478bd9Sstevel@tonic-gate 			if (cp = vinterp(s, ' '))
127*7c478bd9Sstevel@tonic-gate 				cp++;
128*7c478bd9Sstevel@tonic-gate 			vtoken(s);
129*7c478bd9Sstevel@tonic-gate 			s = cp;
130*7c478bd9Sstevel@tonic-gate 		} while (s);
131*7c478bd9Sstevel@tonic-gate 	}
132*7c478bd9Sstevel@tonic-gate 	if (col > 0) {
133*7c478bd9Sstevel@tonic-gate 		printf("\r\n");
134*7c478bd9Sstevel@tonic-gate 		col = 0;
135*7c478bd9Sstevel@tonic-gate 	}
136*7c478bd9Sstevel@tonic-gate }
137*7c478bd9Sstevel@tonic-gate 
138*7c478bd9Sstevel@tonic-gate static int
139*7c478bd9Sstevel@tonic-gate vtoken(s)
140*7c478bd9Sstevel@tonic-gate 	register char *s;
141*7c478bd9Sstevel@tonic-gate {
142*7c478bd9Sstevel@tonic-gate 	register value_t *p;
143*7c478bd9Sstevel@tonic-gate 	register char *cp, *cp2;
144*7c478bd9Sstevel@tonic-gate 	char *expand();
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate 	if (cp = strchr(s, '=')) {
147*7c478bd9Sstevel@tonic-gate 		*cp = '\0';
148*7c478bd9Sstevel@tonic-gate 		if (p = vlookup(s)) {
149*7c478bd9Sstevel@tonic-gate 			cp++;
150*7c478bd9Sstevel@tonic-gate 			if (p->v_type&NUMBER)
151*7c478bd9Sstevel@tonic-gate 				vassign(p, atoi(cp));
152*7c478bd9Sstevel@tonic-gate 			else {
153*7c478bd9Sstevel@tonic-gate 				if (strcmp(s, "record") == 0)
154*7c478bd9Sstevel@tonic-gate 					if ((cp2 = expand(cp)) != NOSTR)
155*7c478bd9Sstevel@tonic-gate 						cp = cp2;
156*7c478bd9Sstevel@tonic-gate 				vassign(p, cp);
157*7c478bd9Sstevel@tonic-gate 			}
158*7c478bd9Sstevel@tonic-gate 			return;
159*7c478bd9Sstevel@tonic-gate 		}
160*7c478bd9Sstevel@tonic-gate 	} else if (cp = strchr(s, '?')) {
161*7c478bd9Sstevel@tonic-gate 		*cp = '\0';
162*7c478bd9Sstevel@tonic-gate 		if ((p = vlookup(s)) && vaccess(p->v_access, READ)) {
163*7c478bd9Sstevel@tonic-gate 			vprint(p);
164*7c478bd9Sstevel@tonic-gate 			return;
165*7c478bd9Sstevel@tonic-gate 		}
166*7c478bd9Sstevel@tonic-gate 	} else {
167*7c478bd9Sstevel@tonic-gate 		if (*s != '!')
168*7c478bd9Sstevel@tonic-gate 			p = vlookup(s);
169*7c478bd9Sstevel@tonic-gate 		else
170*7c478bd9Sstevel@tonic-gate 			p = vlookup(s+1);
171*7c478bd9Sstevel@tonic-gate 		if (p != NOVAL) {
172*7c478bd9Sstevel@tonic-gate 			if (p->v_type&BOOL)
173*7c478bd9Sstevel@tonic-gate 				vassign(p, s);
174*7c478bd9Sstevel@tonic-gate 			else
175*7c478bd9Sstevel@tonic-gate 				printf("%s: no value specified\r\n", s);
176*7c478bd9Sstevel@tonic-gate 			return;
177*7c478bd9Sstevel@tonic-gate 		}
178*7c478bd9Sstevel@tonic-gate 	}
179*7c478bd9Sstevel@tonic-gate 	printf("%s: unknown variable\r\n", s);
180*7c478bd9Sstevel@tonic-gate }
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate static int
183*7c478bd9Sstevel@tonic-gate vprint(p)
184*7c478bd9Sstevel@tonic-gate 	register value_t *p;
185*7c478bd9Sstevel@tonic-gate {
186*7c478bd9Sstevel@tonic-gate 	register char *cp;
187*7c478bd9Sstevel@tonic-gate 	extern char *interp(), *ctrl();
188*7c478bd9Sstevel@tonic-gate 
189*7c478bd9Sstevel@tonic-gate 	if (col > 0 && col < MIDDLE)
190*7c478bd9Sstevel@tonic-gate 		while (col++ < MIDDLE)
191*7c478bd9Sstevel@tonic-gate 			putchar(' ');
192*7c478bd9Sstevel@tonic-gate 	col += strlen(p->v_name);
193*7c478bd9Sstevel@tonic-gate 	switch (p->v_type&TMASK) {
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate 	case BOOL:
196*7c478bd9Sstevel@tonic-gate 		if (boolean(p->v_value) == FALSE) {
197*7c478bd9Sstevel@tonic-gate 			col++;
198*7c478bd9Sstevel@tonic-gate 			putchar('!');
199*7c478bd9Sstevel@tonic-gate 		}
200*7c478bd9Sstevel@tonic-gate 		printf("%s", p->v_name);
201*7c478bd9Sstevel@tonic-gate 		break;
202*7c478bd9Sstevel@tonic-gate 
203*7c478bd9Sstevel@tonic-gate 	case STRING:
204*7c478bd9Sstevel@tonic-gate 		printf("%s=", p->v_name);
205*7c478bd9Sstevel@tonic-gate 		col++;
206*7c478bd9Sstevel@tonic-gate 		if (p->v_value) {
207*7c478bd9Sstevel@tonic-gate 			cp = interp(p->v_value, NULL);
208*7c478bd9Sstevel@tonic-gate 			col += strlen(cp);
209*7c478bd9Sstevel@tonic-gate 			printf("%s", cp);
210*7c478bd9Sstevel@tonic-gate 		}
211*7c478bd9Sstevel@tonic-gate 		break;
212*7c478bd9Sstevel@tonic-gate 
213*7c478bd9Sstevel@tonic-gate 	case NUMBER:
214*7c478bd9Sstevel@tonic-gate 		col += 6;
215*7c478bd9Sstevel@tonic-gate 		printf("%s=%-5d", p->v_name, number(p->v_value));
216*7c478bd9Sstevel@tonic-gate 		break;
217*7c478bd9Sstevel@tonic-gate 
218*7c478bd9Sstevel@tonic-gate 	case CHAR:
219*7c478bd9Sstevel@tonic-gate 		printf("%s=", p->v_name);
220*7c478bd9Sstevel@tonic-gate 		col++;
221*7c478bd9Sstevel@tonic-gate 		if (p->v_value) {
222*7c478bd9Sstevel@tonic-gate 			cp = ctrl(character(p->v_value));
223*7c478bd9Sstevel@tonic-gate 			col += strlen(cp);
224*7c478bd9Sstevel@tonic-gate 			printf("%s", cp);
225*7c478bd9Sstevel@tonic-gate 		}
226*7c478bd9Sstevel@tonic-gate 		break;
227*7c478bd9Sstevel@tonic-gate 	}
228*7c478bd9Sstevel@tonic-gate 	if (col >= MIDDLE) {
229*7c478bd9Sstevel@tonic-gate 		col = 0;
230*7c478bd9Sstevel@tonic-gate 		printf("\r\n");
231*7c478bd9Sstevel@tonic-gate 		return;
232*7c478bd9Sstevel@tonic-gate 	}
233*7c478bd9Sstevel@tonic-gate }
234*7c478bd9Sstevel@tonic-gate 
235*7c478bd9Sstevel@tonic-gate 
236*7c478bd9Sstevel@tonic-gate static int
237*7c478bd9Sstevel@tonic-gate vaccess(mode, rw)
238*7c478bd9Sstevel@tonic-gate 	register unsigned mode, rw;
239*7c478bd9Sstevel@tonic-gate {
240*7c478bd9Sstevel@tonic-gate 	if (mode & (rw<<PUBLIC))
241*7c478bd9Sstevel@tonic-gate 		return (1);
242*7c478bd9Sstevel@tonic-gate 	if (mode & (rw<<PRIVATE))
243*7c478bd9Sstevel@tonic-gate 		return (1);
244*7c478bd9Sstevel@tonic-gate 	return ((mode & (rw<<ROOT)) && uid == 0);
245*7c478bd9Sstevel@tonic-gate }
246*7c478bd9Sstevel@tonic-gate 
247*7c478bd9Sstevel@tonic-gate static value_t *
248*7c478bd9Sstevel@tonic-gate vlookup(s)
249*7c478bd9Sstevel@tonic-gate 	register char *s;
250*7c478bd9Sstevel@tonic-gate {
251*7c478bd9Sstevel@tonic-gate 	register value_t *p;
252*7c478bd9Sstevel@tonic-gate 
253*7c478bd9Sstevel@tonic-gate 	for (p = vtable; p->v_name; p++)
254*7c478bd9Sstevel@tonic-gate 		if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
255*7c478bd9Sstevel@tonic-gate 			return (p);
256*7c478bd9Sstevel@tonic-gate 	return (NULL);
257*7c478bd9Sstevel@tonic-gate }
258*7c478bd9Sstevel@tonic-gate 
259*7c478bd9Sstevel@tonic-gate char *
260*7c478bd9Sstevel@tonic-gate vinterp(s, stop)
261*7c478bd9Sstevel@tonic-gate 	register char *s;
262*7c478bd9Sstevel@tonic-gate 	char stop;
263*7c478bd9Sstevel@tonic-gate {
264*7c478bd9Sstevel@tonic-gate 	register char *p = s, c;
265*7c478bd9Sstevel@tonic-gate 	int num;
266*7c478bd9Sstevel@tonic-gate 
267*7c478bd9Sstevel@tonic-gate 	while ((c = *s++) && c != stop)
268*7c478bd9Sstevel@tonic-gate 		switch (c) {
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate 		case '^':
271*7c478bd9Sstevel@tonic-gate 			if (*s)
272*7c478bd9Sstevel@tonic-gate 				*p++ = *s++ - 0100;
273*7c478bd9Sstevel@tonic-gate 			else
274*7c478bd9Sstevel@tonic-gate 				*p++ = c;
275*7c478bd9Sstevel@tonic-gate 			break;
276*7c478bd9Sstevel@tonic-gate 
277*7c478bd9Sstevel@tonic-gate 		case '\\':
278*7c478bd9Sstevel@tonic-gate 			num = 0;
279*7c478bd9Sstevel@tonic-gate 			c = *s++;
280*7c478bd9Sstevel@tonic-gate 			if (c >= '0' && c <= '7')
281*7c478bd9Sstevel@tonic-gate 				num = (num<<3)+(c-'0');
282*7c478bd9Sstevel@tonic-gate 			else {
283*7c478bd9Sstevel@tonic-gate 				register char *q = "n\nr\rt\tb\bf\f";
284*7c478bd9Sstevel@tonic-gate 
285*7c478bd9Sstevel@tonic-gate 				for (; *q; q++)
286*7c478bd9Sstevel@tonic-gate 					if (c == *q++) {
287*7c478bd9Sstevel@tonic-gate 						*p++ = *q;
288*7c478bd9Sstevel@tonic-gate 						goto cont;
289*7c478bd9Sstevel@tonic-gate 					}
290*7c478bd9Sstevel@tonic-gate 				*p++ = c;
291*7c478bd9Sstevel@tonic-gate 			cont:
292*7c478bd9Sstevel@tonic-gate 				break;
293*7c478bd9Sstevel@tonic-gate 			}
294*7c478bd9Sstevel@tonic-gate 			if ((c = *s++) >= '0' && c <= '7') {
295*7c478bd9Sstevel@tonic-gate 				num = (num<<3)+(c-'0');
296*7c478bd9Sstevel@tonic-gate 				if ((c = *s++) >= '0' && c <= '7')
297*7c478bd9Sstevel@tonic-gate 					num = (num<<3)+(c-'0');
298*7c478bd9Sstevel@tonic-gate 				else
299*7c478bd9Sstevel@tonic-gate 					s--;
300*7c478bd9Sstevel@tonic-gate 			} else
301*7c478bd9Sstevel@tonic-gate 				s--;
302*7c478bd9Sstevel@tonic-gate 			*p++ = num;
303*7c478bd9Sstevel@tonic-gate 			break;
304*7c478bd9Sstevel@tonic-gate 
305*7c478bd9Sstevel@tonic-gate 		default:
306*7c478bd9Sstevel@tonic-gate 			*p++ = c;
307*7c478bd9Sstevel@tonic-gate 		}
308*7c478bd9Sstevel@tonic-gate 	*p = '\0';
309*7c478bd9Sstevel@tonic-gate 	return (c == stop ? s-1 : NULL);
310*7c478bd9Sstevel@tonic-gate }
311*7c478bd9Sstevel@tonic-gate 
312*7c478bd9Sstevel@tonic-gate /*
313*7c478bd9Sstevel@tonic-gate  * assign variable s with value v (for NUMBER or STRING or CHAR types)
314*7c478bd9Sstevel@tonic-gate  */
315*7c478bd9Sstevel@tonic-gate 
316*7c478bd9Sstevel@tonic-gate vstring(s, v)
317*7c478bd9Sstevel@tonic-gate 	register char *s;
318*7c478bd9Sstevel@tonic-gate 	register char *v;
319*7c478bd9Sstevel@tonic-gate {
320*7c478bd9Sstevel@tonic-gate 	register value_t *p;
321*7c478bd9Sstevel@tonic-gate 	char *v2;
322*7c478bd9Sstevel@tonic-gate 	char *expand();
323*7c478bd9Sstevel@tonic-gate 
324*7c478bd9Sstevel@tonic-gate 	p = vlookup(s);
325*7c478bd9Sstevel@tonic-gate 	if (p == 0)
326*7c478bd9Sstevel@tonic-gate 		return (1);
327*7c478bd9Sstevel@tonic-gate 	if (p->v_type&NUMBER)
328*7c478bd9Sstevel@tonic-gate 		vassign(p, atoi(v));
329*7c478bd9Sstevel@tonic-gate 	else {
330*7c478bd9Sstevel@tonic-gate 		if (strcmp(s, "record") == 0)
331*7c478bd9Sstevel@tonic-gate 			if ((v2 = expand(v)) != NOSTR)
332*7c478bd9Sstevel@tonic-gate 				v = v2;
333*7c478bd9Sstevel@tonic-gate 		vassign(p, v);
334*7c478bd9Sstevel@tonic-gate 	}
335*7c478bd9Sstevel@tonic-gate 	return (0);
336*7c478bd9Sstevel@tonic-gate }
337