|
|
1.1 root 1: /*
2: * Copyright (c) 1983 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted
6: * provided that: (1) source distributions retain this entire copyright
7: * notice and comment, and (2) distributions including binaries display
8: * the following acknowledgement: ``This product includes software
9: * developed by the University of California, Berkeley and its contributors''
10: * in the documentation or other materials provided with the distribution
11: * and in all advertising materials mentioning features or use of this
12: * software. Neither the name of the University nor the names of its
13: * contributors may be used to endorse or promote products derived
14: * from this software without specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
16: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
17: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: static char sccsid[] = "@(#)value.c 5.3 (Berkeley) 6/1/90";
22: #endif /* not lint */
23:
24: #include "tip.h"
25:
26: #define MIDDLE 35
27:
28: static value_t *vlookup();
29: static int col = 0;
30:
31: /*
32: * Variable manipulation
33: */
34: vinit()
35: {
36: register value_t *p;
37: register char *cp;
38: FILE *f;
39: char file[256];
40:
41: for (p = vtable; p->v_name != NULL; p++) {
42: if (p->v_type&ENVIRON)
43: if (cp = getenv(p->v_name))
44: p->v_value = cp;
45: if (p->v_type&IREMOTE)
46: number(p->v_value) = *address(p->v_value);
47: }
48: /*
49: * Read the .tiprc file in the HOME directory
50: * for sets
51: */
52: strcpy(file, value(HOME));
53: strcat(file, "/.tiprc");
54: if ((f = fopen(file, "r")) != NULL) {
55: register char *tp;
56:
57: while (fgets(file, sizeof(file)-1, f) != NULL) {
58: if (vflag)
59: printf("set %s", file);
60: if (tp = rindex(file, '\n'))
61: *tp = '\0';
62: vlex(file);
63: }
64: fclose(f);
65: }
66: /*
67: * To allow definition of exception prior to fork
68: */
69: vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC);
70: }
71:
72: /*VARARGS1*/
73: vassign(p, v)
74: register value_t *p;
75: char *v;
76: {
77:
78: if (!vaccess(p->v_access, WRITE)) {
79: printf("access denied\r\n");
80: return;
81: }
82: switch (p->v_type&TMASK) {
83:
84: case STRING:
85: if (equal(p->v_value, v))
86: return;
87: if (!(p->v_type&(ENVIRON|INIT)))
88: free(p->v_value);
89: if ((p->v_value = malloc(size(v)+1)) == NOSTR) {
90: printf("out of core\r\n");
91: return;
92: }
93: p->v_type &= ~(ENVIRON|INIT);
94: strcpy(p->v_value, v);
95: break;
96:
97: case NUMBER:
98: if (number(p->v_value) == number(v))
99: return;
100: number(p->v_value) = number(v);
101: break;
102:
103: case BOOL:
104: if (boolean(p->v_value) == (*v != '!'))
105: return;
106: boolean(p->v_value) = (*v != '!');
107: break;
108:
109: case CHAR:
110: if (character(p->v_value) == *v)
111: return;
112: character(p->v_value) = *v;
113: }
114: p->v_access |= CHANGED;
115: }
116:
117: vlex(s)
118: register char *s;
119: {
120: register value_t *p;
121:
122: if (equal(s, "all")) {
123: for (p = vtable; p->v_name; p++)
124: if (vaccess(p->v_access, READ))
125: vprint(p);
126: } else {
127: register char *cp;
128:
129: do {
130: if (cp = vinterp(s, ' '))
131: cp++;
132: vtoken(s);
133: s = cp;
134: } while (s);
135: }
136: if (col > 0) {
137: printf("\r\n");
138: col = 0;
139: }
140: }
141:
142: static int
143: vtoken(s)
144: register char *s;
145: {
146: register value_t *p;
147: register char *cp;
148: char *expand();
149:
150: if (cp = index(s, '=')) {
151: *cp = '\0';
152: if (p = vlookup(s)) {
153: cp++;
154: if (p->v_type&NUMBER)
155: vassign(p, atoi(cp));
156: else {
157: if (strcmp(s, "record") == 0)
158: cp = expand(cp);
159: vassign(p, cp);
160: }
161: return;
162: }
163: } else if (cp = index(s, '?')) {
164: *cp = '\0';
165: if ((p = vlookup(s)) && vaccess(p->v_access, READ)) {
166: vprint(p);
167: return;
168: }
169: } else {
170: if (*s != '!')
171: p = vlookup(s);
172: else
173: p = vlookup(s+1);
174: if (p != NOVAL) {
175: vassign(p, s);
176: return;
177: }
178: }
179: printf("%s: unknown variable\r\n", s);
180: }
181:
182: static int
183: vprint(p)
184: register value_t *p;
185: {
186: register char *cp;
187: extern char *interp(), *ctrl();
188:
189: if (col > 0 && col < MIDDLE)
190: while (col++ < MIDDLE)
191: putchar(' ');
192: col += size(p->v_name);
193: switch (p->v_type&TMASK) {
194:
195: case BOOL:
196: if (boolean(p->v_value) == FALSE) {
197: col++;
198: putchar('!');
199: }
200: printf("%s", p->v_name);
201: break;
202:
203: case STRING:
204: printf("%s=", p->v_name);
205: col++;
206: if (p->v_value) {
207: cp = interp(p->v_value, NULL);
208: col += size(cp);
209: printf("%s", cp);
210: }
211: break;
212:
213: case NUMBER:
214: col += 6;
215: printf("%s=%-5d", p->v_name, number(p->v_value));
216: break;
217:
218: case CHAR:
219: printf("%s=", p->v_name);
220: col++;
221: if (p->v_value) {
222: cp = ctrl(character(p->v_value));
223: col += size(cp);
224: printf("%s", cp);
225: }
226: break;
227: }
228: if (col >= MIDDLE) {
229: col = 0;
230: printf("\r\n");
231: return;
232: }
233: }
234:
235:
236: static int
237: vaccess(mode, rw)
238: register unsigned mode, rw;
239: {
240: if (mode & (rw<<PUBLIC))
241: return (1);
242: if (mode & (rw<<PRIVATE))
243: return (1);
244: return ((mode & (rw<<ROOT)) && getuid() == 0);
245: }
246:
247: static value_t *
248: vlookup(s)
249: register char *s;
250: {
251: register value_t *p;
252:
253: for (p = vtable; p->v_name; p++)
254: if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
255: return (p);
256: return (NULL);
257: }
258:
259: char *
260: vinterp(s, stop)
261: register char *s;
262: char stop;
263: {
264: register char *p = s, c;
265: int num;
266:
267: while ((c = *s++) && c != stop)
268: switch (c) {
269:
270: case '^':
271: if (*s)
272: *p++ = *s++ - 0100;
273: else
274: *p++ = c;
275: break;
276:
277: case '\\':
278: num = 0;
279: c = *s++;
280: if (c >= '0' && c <= '7')
281: num = (num<<3)+(c-'0');
282: else {
283: register char *q = "n\nr\rt\tb\bf\f";
284:
285: for (; *q; q++)
286: if (c == *q++) {
287: *p++ = *q;
288: goto cont;
289: }
290: *p++ = c;
291: cont:
292: break;
293: }
294: if ((c = *s++) >= '0' && c <= '7') {
295: num = (num<<3)+(c-'0');
296: if ((c = *s++) >= '0' && c <= '7')
297: num = (num<<3)+(c-'0');
298: else
299: s--;
300: } else
301: s--;
302: *p++ = num;
303: break;
304:
305: default:
306: *p++ = c;
307: }
308: *p = '\0';
309: return (c == stop ? s-1 : NULL);
310: }
311:
312: /*
313: * assign variable s with value v (for NUMBER or STRING or CHAR types)
314: */
315:
316: vstring(s,v)
317: register char *s;
318: register char *v;
319: {
320: register value_t *p;
321: char *expand();
322:
323: p = vlookup(s);
324: if (p == 0)
325: return (1);
326: if (p->v_type&NUMBER)
327: vassign(p, atoi(v));
328: else {
329: if (strcmp(s, "record") == 0)
330: v = expand(v);
331: vassign(p, v);
332: }
333: return (0);
334: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.