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