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