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