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