xref: /csrg-svn/usr.bin/tip/value.c (revision 3700)
1*3700Sroot /*	value.c	4.1	81/05/09	*/
2*3700Sroot #include "tip.h"
3*3700Sroot 
4*3700Sroot #define MIDDLE	35
5*3700Sroot 
6*3700Sroot static value_t *vlookup();
7*3700Sroot static int col = 0;
8*3700Sroot 
9*3700Sroot /*
10*3700Sroot  * Variable manipulation
11*3700Sroot  */
12*3700Sroot vinit()
13*3700Sroot {
14*3700Sroot 	register value_t *p;
15*3700Sroot 	register char *cp;
16*3700Sroot 	FILE *f;
17*3700Sroot 	char file[256];
18*3700Sroot 
19*3700Sroot 	for (p = vtable; p->v_name != NULL; p++) {
20*3700Sroot 		if (p->v_type&ENVIRON)
21*3700Sroot 			if (cp = getenv(p->v_name))
22*3700Sroot 				p->v_value = cp;
23*3700Sroot 		if (p->v_type&IREMOTE)
24*3700Sroot 			number(p->v_value) = *address(p->v_value);
25*3700Sroot 	}
26*3700Sroot 	/*
27*3700Sroot 	 * Read the .tiprc file in the HOME directory
28*3700Sroot 	 *  for sets
29*3700Sroot 	 */
30*3700Sroot 	strcpy(file, value(HOME));
31*3700Sroot 	strcat(file, "/.tiprc");
32*3700Sroot 	if ((f = fopen(file, "r")) != NULL) {
33*3700Sroot 		register char *tp;
34*3700Sroot 
35*3700Sroot 		while (fgets(file, sizeof(file)-1, f) != NULL) {
36*3700Sroot 			if (vflag)
37*3700Sroot 				printf("set %s", file);
38*3700Sroot 			if (tp = rindex(file, '\n'))
39*3700Sroot 				*tp = '\0';
40*3700Sroot 			vlex(file);
41*3700Sroot 		}
42*3700Sroot 		fclose(f);
43*3700Sroot 	}
44*3700Sroot 	/*
45*3700Sroot 	 * To allow definition of exception prior to fork
46*3700Sroot 	 */
47*3700Sroot 	vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC);
48*3700Sroot }
49*3700Sroot 
50*3700Sroot /*VARARGS1*/
51*3700Sroot vassign(p, v)
52*3700Sroot register value_t *p;
53*3700Sroot char *v;
54*3700Sroot {
55*3700Sroot 
56*3700Sroot 	if (!vaccess(p->v_access, WRITE)) {
57*3700Sroot 		printf("access denied\r\n");
58*3700Sroot 		return;
59*3700Sroot 	}
60*3700Sroot 	switch(p->v_type&TMASK) {
61*3700Sroot 
62*3700Sroot 		case STRING:
63*3700Sroot 			if (equal(p->v_value, v))
64*3700Sroot 				return;
65*3700Sroot 			if (!(p->v_type&(ENVIRON|INIT)))
66*3700Sroot 				free(p->v_value);
67*3700Sroot 			if ((p->v_value = malloc(size(v)+1)) == NOSTR) {
68*3700Sroot 				printf("out of core\r\n");
69*3700Sroot 				return;
70*3700Sroot 			}
71*3700Sroot 			p->v_type &= ~(ENVIRON|INIT);
72*3700Sroot 			strcpy(p->v_value, v);
73*3700Sroot 			break;
74*3700Sroot 
75*3700Sroot 		case NUMBER:
76*3700Sroot 			if (number(p->v_value) == number(v))
77*3700Sroot 				return;
78*3700Sroot 			number(p->v_value) = number(v);
79*3700Sroot 			break;
80*3700Sroot 
81*3700Sroot 		case BOOL:
82*3700Sroot 			if (boolean(p->v_value) == (*v != '!'))
83*3700Sroot 				return;
84*3700Sroot 			boolean(p->v_value) = (*v != '!');
85*3700Sroot 			break;
86*3700Sroot 
87*3700Sroot 		case CHAR:
88*3700Sroot 			if (character(p->v_value) == *v)
89*3700Sroot 				return;
90*3700Sroot 			character(p->v_value) = *v;
91*3700Sroot 	}
92*3700Sroot 	p->v_access |= CHANGED;
93*3700Sroot }
94*3700Sroot 
95*3700Sroot vlex(s)
96*3700Sroot register char *s;
97*3700Sroot {
98*3700Sroot 	register value_t *p;
99*3700Sroot 
100*3700Sroot 	if (equal(s, "all")) {
101*3700Sroot 		for (p = vtable; p->v_name; p++)
102*3700Sroot 			if (vaccess(p->v_access, READ))
103*3700Sroot 				vprint(p);
104*3700Sroot 	} else {
105*3700Sroot 		register char *cp;
106*3700Sroot 
107*3700Sroot 		do {
108*3700Sroot 			if (cp = vinterp(s, ' '))
109*3700Sroot 				cp++;
110*3700Sroot 			vtoken(s);
111*3700Sroot 			s = cp;
112*3700Sroot 		} while (s);
113*3700Sroot 	}
114*3700Sroot 	if (col > 0) {
115*3700Sroot 		printf("\r\n");
116*3700Sroot 		col = 0;
117*3700Sroot 	}
118*3700Sroot }
119*3700Sroot 
120*3700Sroot static int
121*3700Sroot vtoken(s)
122*3700Sroot register char *s;
123*3700Sroot {
124*3700Sroot 	register value_t *p;
125*3700Sroot 	register char *cp;
126*3700Sroot 
127*3700Sroot 	if (cp = index(s, '=')) {
128*3700Sroot 		*cp = '\0';
129*3700Sroot 		if (p = vlookup(s)) {
130*3700Sroot 			cp++;
131*3700Sroot 			if (p->v_type&NUMBER)
132*3700Sroot 				vassign(p, atoi(cp));
133*3700Sroot 			else
134*3700Sroot 				vassign(p, cp);
135*3700Sroot 			return;
136*3700Sroot 		}
137*3700Sroot 	} else if (cp = index(s, '?')) {
138*3700Sroot 		*cp = '\0';
139*3700Sroot 		if ((p = vlookup(s)) && vaccess(p->v_access, READ)) {
140*3700Sroot 			vprint(p);
141*3700Sroot 			return;
142*3700Sroot 		}
143*3700Sroot 	} else {
144*3700Sroot 		if (*s != '!')
145*3700Sroot 			p = vlookup(s);
146*3700Sroot 		else
147*3700Sroot 			p = vlookup(s+1);
148*3700Sroot 		if (p != NOVAL) {
149*3700Sroot 			vassign(p, s);
150*3700Sroot 			return;
151*3700Sroot 		}
152*3700Sroot 	}
153*3700Sroot 	printf("%s: unknown variable\r\n", s);
154*3700Sroot }
155*3700Sroot 
156*3700Sroot static int
157*3700Sroot vprint(p)
158*3700Sroot register value_t *p;
159*3700Sroot {
160*3700Sroot 	register char *cp;
161*3700Sroot 	extern char *interp(), *ctrl();
162*3700Sroot 
163*3700Sroot 	if (col > 0 && col < MIDDLE)
164*3700Sroot 		while (col++ < MIDDLE)
165*3700Sroot 			putchar(' ');
166*3700Sroot 	col += size(p->v_name);
167*3700Sroot 	switch(p->v_type&TMASK)
168*3700Sroot 	{
169*3700Sroot 		case BOOL:
170*3700Sroot 			if (boolean(p->v_value) == FALSE) {
171*3700Sroot 				col++;
172*3700Sroot 				putchar('!');
173*3700Sroot 			}
174*3700Sroot 			printf("%s", p->v_name);
175*3700Sroot 			break;
176*3700Sroot 		case STRING:
177*3700Sroot 			printf("%s=", p->v_name);
178*3700Sroot 			col++;
179*3700Sroot 			if (p->v_value) {
180*3700Sroot 				cp = interp(p->v_value);
181*3700Sroot 				col += size(cp);
182*3700Sroot 				printf("%s", cp);
183*3700Sroot 			}
184*3700Sroot 			break;
185*3700Sroot 		case NUMBER:
186*3700Sroot 			col += 6;
187*3700Sroot 			printf("%s=%-5d", p->v_name, number(p->v_value));
188*3700Sroot 			break;
189*3700Sroot 		case CHAR:
190*3700Sroot 			printf("%s=", p->v_name);
191*3700Sroot 			col++;
192*3700Sroot 			if (p->v_value) {
193*3700Sroot 				cp = ctrl(character(p->v_value));
194*3700Sroot 				col += size(cp);
195*3700Sroot 				printf("%s", cp);
196*3700Sroot 			}
197*3700Sroot 			break;
198*3700Sroot 	}
199*3700Sroot 	if (col >= MIDDLE) {
200*3700Sroot 		col = 0;
201*3700Sroot 		printf("\r\n");
202*3700Sroot 		return;
203*3700Sroot 	}
204*3700Sroot }
205*3700Sroot 
206*3700Sroot 
207*3700Sroot static int
208*3700Sroot vaccess(mode, rw)
209*3700Sroot register unsigned mode, rw;
210*3700Sroot {
211*3700Sroot 	if (mode & (rw<<PUBLIC))
212*3700Sroot 		return(1);
213*3700Sroot 	if (mode & (rw<<PRIVATE))
214*3700Sroot 		return(1);
215*3700Sroot 	return((mode & (rw<<ROOT)) && getuid() == 0);
216*3700Sroot }
217*3700Sroot 
218*3700Sroot static value_t *
219*3700Sroot vlookup(s)
220*3700Sroot register char *s;
221*3700Sroot {
222*3700Sroot 	register value_t *p;
223*3700Sroot 
224*3700Sroot 	for (p = vtable; p->v_name; p++)
225*3700Sroot 		if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
226*3700Sroot 			return(p);
227*3700Sroot 	return(NULL);
228*3700Sroot }
229*3700Sroot 
230*3700Sroot char *
231*3700Sroot vinterp(s, stop)
232*3700Sroot register char *s;
233*3700Sroot char stop;
234*3700Sroot {
235*3700Sroot 	register char *p = s, c;
236*3700Sroot 	int num;
237*3700Sroot 
238*3700Sroot 	while ((c = *s++) && c != stop) switch(c)
239*3700Sroot 	{
240*3700Sroot 		case '^':
241*3700Sroot 			if (*s)
242*3700Sroot 				*p++ = *s++ - 0100;
243*3700Sroot 			else
244*3700Sroot 				*p++ = c;
245*3700Sroot 			break;
246*3700Sroot 
247*3700Sroot 		case '\\':
248*3700Sroot 			num = 0;
249*3700Sroot 			c = *s++;
250*3700Sroot 			if (c >= '0' && c <= '7')
251*3700Sroot 				num = (num<<3)+(c-'0');
252*3700Sroot 			else {
253*3700Sroot 				register char *q = "n\nr\rt\tb\bf\f";
254*3700Sroot 
255*3700Sroot 				for (; *q; q++)
256*3700Sroot 					if (c == *q++) {
257*3700Sroot 						*p++ = *q;
258*3700Sroot 						goto cont;
259*3700Sroot 					}
260*3700Sroot 				*p++ = c;
261*3700Sroot 			cont:
262*3700Sroot 				break;
263*3700Sroot 			}
264*3700Sroot 			if ((c = *s++) >= '0' && c <= '7') {
265*3700Sroot 				num = (num<<3)+(c-'0');
266*3700Sroot 				if ((c = *s++) >= '0' && c <= '7')
267*3700Sroot 					num = (num<<3)+(c-'0');
268*3700Sroot 				else
269*3700Sroot 					s--;
270*3700Sroot 			} else
271*3700Sroot 				s--;
272*3700Sroot 			*p++ = num;
273*3700Sroot 			break;
274*3700Sroot 
275*3700Sroot 		default:
276*3700Sroot 			*p++ = c;
277*3700Sroot 	}
278*3700Sroot 	*p = '\0';
279*3700Sroot 	return(c == stop ? s-1 : NULL);
280*3700Sroot }
281