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