Annotation of src/usr.bin/tip/value.c, Revision 1.3
1.3 ! millert 1: /* $OpenBSD: value.c,v 1.2 1996/06/26 05:40:49 deraadt Exp $ */
1.1 deraadt 2: /* $NetBSD: value.c,v 1.3 1994/12/08 09:31:17 jtc Exp $ */
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.3 ! millert 41: static char rcsid[] = "$OpenBSD: value.c,v 1.2 1996/06/26 05:40:49 deraadt 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)
66: number(p->v_value) = *address(p->v_value);
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)) {
! 73: fprintf(stderr, "Home directory path too long: %s\n",
! 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);
116: if ((p->v_value = malloc(size(v)+1)) == NOSTR) {
117: printf("out of core\r\n");
118: return;
119: }
120: p->v_type &= ~(ENVIRON|INIT);
121: strcpy(p->v_value, v);
122: break;
123:
124: case NUMBER:
125: if (number(p->v_value) == number(v))
126: return;
127: number(p->v_value) = number(v);
128: break;
129:
130: case BOOL:
131: if (boolean(p->v_value) == (*v != '!'))
132: return;
133: boolean(p->v_value) = (*v != '!');
134: break;
135:
136: case CHAR:
137: if (character(p->v_value) == *v)
138: return;
139: character(p->v_value) = *v;
140: }
141: p->v_access |= CHANGED;
142: }
143:
144: static void vprint();
145:
146: vlex(s)
147: register char *s;
148: {
149: register value_t *p;
150: static void vtoken();
151:
152: if (equal(s, "all")) {
153: for (p = vtable; p->v_name; p++)
154: if (vaccess(p->v_access, READ))
155: vprint(p);
156: } else {
157: register char *cp;
158:
159: do {
160: if (cp = vinterp(s, ' '))
161: cp++;
162: vtoken(s);
163: s = cp;
164: } while (s);
165: }
166: if (col > 0) {
167: printf("\r\n");
168: col = 0;
169: }
170: }
171:
172: static void
173: vtoken(s)
174: register char *s;
175: {
176: register value_t *p;
177: register char *cp;
178: char *expand();
179:
1.3 ! millert 180: if (cp = strchr(s, '=')) {
1.1 deraadt 181: *cp = '\0';
182: if (p = vlookup(s)) {
183: cp++;
184: if (p->v_type&NUMBER)
185: vassign(p, atoi(cp));
186: else {
187: if (strcmp(s, "record") == 0)
188: cp = expand(cp);
189: vassign(p, cp);
190: }
191: return;
192: }
1.3 ! millert 193: } else if (cp = strchr(s, '?')) {
1.1 deraadt 194: *cp = '\0';
195: if ((p = vlookup(s)) && vaccess(p->v_access, READ)) {
196: vprint(p);
197: return;
198: }
199: } else {
200: if (*s != '!')
201: p = vlookup(s);
202: else
203: p = vlookup(s+1);
204: if (p != NOVAL) {
205: vassign(p, s);
206: return;
207: }
208: }
209: printf("%s: unknown variable\r\n", s);
210: }
211:
212: static void
213: vprint(p)
214: register value_t *p;
215: {
216: register char *cp;
217: extern char *interp(), *ctrl();
218:
219: if (col > 0 && col < MIDDLE)
220: while (col++ < MIDDLE)
221: putchar(' ');
222: col += size(p->v_name);
223: switch (p->v_type&TMASK) {
224:
225: case BOOL:
226: if (boolean(p->v_value) == FALSE) {
227: col++;
228: putchar('!');
229: }
230: printf("%s", p->v_name);
231: break;
232:
233: case STRING:
234: printf("%s=", p->v_name);
235: col++;
236: if (p->v_value) {
237: cp = interp(p->v_value, NULL);
238: col += size(cp);
239: printf("%s", cp);
240: }
241: break;
242:
243: case NUMBER:
244: col += 6;
245: printf("%s=%-5d", p->v_name, number(p->v_value));
246: break;
247:
248: case CHAR:
249: printf("%s=", p->v_name);
250: col++;
251: if (p->v_value) {
252: cp = ctrl(character(p->v_value));
253: col += size(cp);
254: printf("%s", cp);
255: }
256: break;
257: }
258: if (col >= MIDDLE) {
259: col = 0;
260: printf("\r\n");
261: return;
262: }
263: }
264:
265:
266: static int
267: vaccess(mode, rw)
268: register unsigned mode, rw;
269: {
270: if (mode & (rw<<PUBLIC))
271: return (1);
272: if (mode & (rw<<PRIVATE))
273: return (1);
274: return ((mode & (rw<<ROOT)) && getuid() == 0);
275: }
276:
277: static value_t *
278: vlookup(s)
279: register char *s;
280: {
281: register value_t *p;
282:
283: for (p = vtable; p->v_name; p++)
284: if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
285: return (p);
286: return (NULL);
287: }
288:
289: char *
290: vinterp(s, stop)
291: register char *s;
292: char stop;
293: {
294: register char *p = s, c;
295: int num;
296:
297: while ((c = *s++) && c != stop)
298: switch (c) {
299:
300: case '^':
301: if (*s)
302: *p++ = *s++ - 0100;
303: else
304: *p++ = c;
305: break;
306:
307: case '\\':
308: num = 0;
309: c = *s++;
310: if (c >= '0' && c <= '7')
311: num = (num<<3)+(c-'0');
312: else {
313: register char *q = "n\nr\rt\tb\bf\f";
314:
315: for (; *q; q++)
316: if (c == *q++) {
317: *p++ = *q;
318: goto cont;
319: }
320: *p++ = c;
321: cont:
322: break;
323: }
324: if ((c = *s++) >= '0' && c <= '7') {
325: num = (num<<3)+(c-'0');
326: if ((c = *s++) >= '0' && c <= '7')
327: num = (num<<3)+(c-'0');
328: else
329: s--;
330: } else
331: s--;
332: *p++ = num;
333: break;
334:
335: default:
336: *p++ = c;
337: }
338: *p = '\0';
339: return (c == stop ? s-1 : NULL);
340: }
341:
342: /*
343: * assign variable s with value v (for NUMBER or STRING or CHAR types)
344: */
345:
346: vstring(s,v)
347: register char *s;
348: register char *v;
349: {
350: register value_t *p;
351: char *expand();
352:
353: p = vlookup(s);
354: if (p == 0)
355: return (1);
356: if (p->v_type&NUMBER)
357: vassign(p, atoi(v));
358: else {
359: if (strcmp(s, "record") == 0)
360: v = expand(v);
361: vassign(p, v);
362: }
363: return (0);
364: }