Annotation of src/usr.bin/tip/value.c, Revision 1.7
1.7 ! millert 1: /* $OpenBSD: value.c,v 1.6 1999/02/04 17:59:38 deraadt Exp $ */
1.4 millert 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.7 ! millert 41: static char rcsid[] = "$OpenBSD: value.c,v 1.6 1999/02/04 17:59:38 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: */
1.5 deraadt 54: void
1.1 deraadt 55: vinit()
56: {
1.7 ! millert 57: value_t *p;
! 58: char *cp;
1.1 deraadt 59: FILE *f;
1.3 millert 60: char file[FILENAME_MAX];
1.1 deraadt 61:
62: for (p = vtable; p->v_name != NULL; p++) {
63: if (p->v_type&ENVIRON)
1.5 deraadt 64: if ((cp = getenv(p->v_name)))
1.1 deraadt 65: p->v_value = cp;
66: if (p->v_type&IREMOTE)
1.4 millert 67: setnumber(p->v_value, *address(p->v_value));
1.1 deraadt 68: }
69: /*
70: * Read the .tiprc file in the HOME directory
71: * for sets
72: */
1.3 millert 73: if (strlen(value(HOME)) + sizeof("/.tiprc") > sizeof(file)) {
1.4 millert 74: (void)fprintf(stderr, "Home directory path too long: %s\n",
1.3 millert 75: value(HOME));
76: } else {
1.6 deraadt 77: snprintf(file, sizeof file, "%s/.tiprc", value(HOME));
1.3 millert 78: if ((f = fopen(file, "r")) != NULL) {
1.7 ! millert 79: char *tp;
1.3 millert 80:
81: while (fgets(file, sizeof(file)-1, f) != NULL) {
82: if (vflag)
83: printf("set %s", file);
1.5 deraadt 84: if ((tp = strrchr(file, '\n')))
1.3 millert 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*/
1.5 deraadt 100: void
1.1 deraadt 101: vassign(p, v)
1.7 ! millert 102: value_t *p;
1.1 deraadt 103: char *v;
104: {
105:
106: if (!vaccess(p->v_access, WRITE)) {
107: printf("access denied\r\n");
108: return;
109: }
110: switch (p->v_type&TMASK) {
111:
112: case STRING:
113: if (p->v_value && equal(p->v_value, v))
114: return;
115: if (!(p->v_type&(ENVIRON|INIT)))
116: free(p->v_value);
1.4 millert 117: if ((p->v_value = strdup(v)) == NOSTR) {
1.1 deraadt 118: printf("out of core\r\n");
119: return;
120: }
121: p->v_type &= ~(ENVIRON|INIT);
122: break;
123:
124: case NUMBER:
125: if (number(p->v_value) == number(v))
126: return;
1.4 millert 127: setnumber(p->v_value, number(v));
1.1 deraadt 128: break;
129:
130: case BOOL:
131: if (boolean(p->v_value) == (*v != '!'))
132: return;
1.4 millert 133: setboolean(p->v_value, (*v != '!'));
1.1 deraadt 134: break;
135:
136: case CHAR:
137: if (character(p->v_value) == *v)
138: return;
1.4 millert 139: setcharacter(p->v_value, *v);
1.1 deraadt 140: }
141: p->v_access |= CHANGED;
142: }
143:
144: static void vprint();
1.4 millert 145: static void vtoken();
1.1 deraadt 146:
1.5 deraadt 147: void
1.1 deraadt 148: vlex(s)
1.7 ! millert 149: char *s;
1.1 deraadt 150: {
1.7 ! millert 151: value_t *p;
1.1 deraadt 152:
153: if (equal(s, "all")) {
154: for (p = vtable; p->v_name; p++)
155: if (vaccess(p->v_access, READ))
156: vprint(p);
157: } else {
1.7 ! millert 158: char *cp;
1.1 deraadt 159:
160: do {
1.5 deraadt 161: if ((cp = vinterp(s, ' ')))
1.1 deraadt 162: cp++;
163: vtoken(s);
164: s = cp;
165: } while (s);
166: }
167: if (col > 0) {
168: printf("\r\n");
169: col = 0;
170: }
171: }
172:
173: static void
174: vtoken(s)
1.7 ! millert 175: char *s;
1.1 deraadt 176: {
1.7 ! millert 177: value_t *p;
! 178: char *cp;
1.1 deraadt 179: char *expand();
180:
1.5 deraadt 181: if ((cp = strchr(s, '='))) {
1.1 deraadt 182: *cp = '\0';
1.5 deraadt 183: if ((p = vlookup(s))) {
1.1 deraadt 184: cp++;
185: if (p->v_type&NUMBER)
186: vassign(p, atoi(cp));
187: else {
188: if (strcmp(s, "record") == 0)
189: cp = expand(cp);
190: vassign(p, cp);
191: }
192: return;
193: }
1.5 deraadt 194: } else if ((cp = strchr(s, '?'))) {
1.1 deraadt 195: *cp = '\0';
196: if ((p = vlookup(s)) && vaccess(p->v_access, READ)) {
197: vprint(p);
198: return;
199: }
200: } else {
201: if (*s != '!')
202: p = vlookup(s);
203: else
204: p = vlookup(s+1);
205: if (p != NOVAL) {
206: vassign(p, s);
207: return;
208: }
209: }
210: printf("%s: unknown variable\r\n", s);
211: }
212:
213: static void
214: vprint(p)
1.7 ! millert 215: value_t *p;
1.1 deraadt 216: {
1.7 ! millert 217: char *cp;
1.1 deraadt 218: extern char *interp(), *ctrl();
219:
220: if (col > 0 && col < MIDDLE)
221: while (col++ < MIDDLE)
222: putchar(' ');
223: col += size(p->v_name);
224: switch (p->v_type&TMASK) {
225:
226: case BOOL:
227: if (boolean(p->v_value) == FALSE) {
228: col++;
229: putchar('!');
230: }
231: printf("%s", p->v_name);
232: break;
233:
234: case STRING:
235: printf("%s=", p->v_name);
236: col++;
237: if (p->v_value) {
238: cp = interp(p->v_value, NULL);
239: col += size(cp);
240: printf("%s", cp);
241: }
242: break;
243:
244: case NUMBER:
245: col += 6;
1.5 deraadt 246: printf("%s=%-5ld", p->v_name, number(p->v_value));
1.1 deraadt 247: break;
248:
249: case CHAR:
250: printf("%s=", p->v_name);
251: col++;
252: if (p->v_value) {
253: cp = ctrl(character(p->v_value));
254: col += size(cp);
255: printf("%s", cp);
256: }
257: break;
258: }
259: if (col >= MIDDLE) {
260: col = 0;
261: printf("\r\n");
262: return;
263: }
264: }
265:
266:
267: static int
268: vaccess(mode, rw)
1.7 ! millert 269: unsigned mode, rw;
1.1 deraadt 270: {
271: if (mode & (rw<<PUBLIC))
272: return (1);
273: if (mode & (rw<<PRIVATE))
274: return (1);
275: return ((mode & (rw<<ROOT)) && getuid() == 0);
276: }
277:
278: static value_t *
279: vlookup(s)
1.7 ! millert 280: char *s;
1.1 deraadt 281: {
1.7 ! millert 282: value_t *p;
1.1 deraadt 283:
284: for (p = vtable; p->v_name; p++)
285: if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
286: return (p);
287: return (NULL);
288: }
289:
290: char *
291: vinterp(s, stop)
1.7 ! millert 292: char *s;
1.1 deraadt 293: char stop;
294: {
1.7 ! millert 295: char *p = s, c;
1.1 deraadt 296: int num;
297:
298: while ((c = *s++) && c != stop)
299: switch (c) {
300:
301: case '^':
302: if (*s)
303: *p++ = *s++ - 0100;
304: else
305: *p++ = c;
306: break;
307:
308: case '\\':
309: num = 0;
310: c = *s++;
311: if (c >= '0' && c <= '7')
312: num = (num<<3)+(c-'0');
313: else {
1.7 ! millert 314: char *q = "n\nr\rt\tb\bf\f";
1.1 deraadt 315:
316: for (; *q; q++)
317: if (c == *q++) {
318: *p++ = *q;
319: goto cont;
320: }
321: *p++ = c;
322: cont:
323: break;
324: }
325: if ((c = *s++) >= '0' && c <= '7') {
326: num = (num<<3)+(c-'0');
327: if ((c = *s++) >= '0' && c <= '7')
328: num = (num<<3)+(c-'0');
329: else
330: s--;
331: } else
332: s--;
333: *p++ = num;
334: break;
335:
336: default:
337: *p++ = c;
338: }
339: *p = '\0';
340: return (c == stop ? s-1 : NULL);
341: }
342:
343: /*
344: * assign variable s with value v (for NUMBER or STRING or CHAR types)
345: */
1.5 deraadt 346: int
1.1 deraadt 347: vstring(s,v)
1.7 ! millert 348: char *s;
! 349: char *v;
1.1 deraadt 350: {
1.7 ! millert 351: value_t *p;
1.1 deraadt 352: char *expand();
353:
354: p = vlookup(s);
355: if (p == 0)
356: return (1);
357: if (p->v_type&NUMBER)
358: vassign(p, atoi(v));
359: else {
360: if (strcmp(s, "record") == 0)
361: v = expand(v);
362: vassign(p, v);
363: }
364: return (0);
365: }