Annotation of src/usr.bin/tip/value.c, Revision 1.15
1.15 ! ray 1: /* $OpenBSD: value.c,v 1.14 2006/03/17 22:02:58 moritz 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.15 ! ray 37: static const char rcsid[] = "$OpenBSD: value.c,v 1.14 2006/03/17 22:02:58 moritz Exp $";
1.1 deraadt 38: #endif /* not lint */
39:
40: #include "tip.h"
41:
42: #define MIDDLE 35
43:
1.11 deraadt 44: static value_t *vlookup(char *);
1.13 moritz 45: static void vassign(value_t *, char *);
46: static void vtoken(char *);
47: static void vprint(value_t *);
48: static int vaccess(unsigned int, unsigned int);
49: static char *vinterp(char *, int);
50:
1.14 moritz 51: static size_t col = 0;
1.1 deraadt 52:
53: /*
54: * Variable manipulation
55: */
1.5 deraadt 56: void
1.11 deraadt 57: vinit(void)
1.1 deraadt 58: {
1.11 deraadt 59: char file[FILENAME_MAX], *cp;
1.7 millert 60: value_t *p;
1.11 deraadt 61: FILE *fp;
1.1 deraadt 62:
63: for (p = vtable; p->v_name != NULL; p++) {
64: if (p->v_type&ENVIRON)
1.5 deraadt 65: if ((cp = getenv(p->v_name)))
1.1 deraadt 66: p->v_value = cp;
67: if (p->v_type&IREMOTE)
1.4 millert 68: setnumber(p->v_value, *address(p->v_value));
1.1 deraadt 69: }
70: /*
71: * Read the .tiprc file in the HOME directory
72: * for sets
73: */
1.3 millert 74: if (strlen(value(HOME)) + sizeof("/.tiprc") > sizeof(file)) {
1.4 millert 75: (void)fprintf(stderr, "Home directory path too long: %s\n",
1.11 deraadt 76: value(HOME));
1.3 millert 77: } else {
1.6 deraadt 78: snprintf(file, sizeof file, "%s/.tiprc", value(HOME));
1.11 deraadt 79: if ((fp = fopen(file, "r")) != NULL) {
1.7 millert 80: char *tp;
1.3 millert 81:
1.15 ! ray 82: while (fgets(file, sizeof(file), fp) != NULL) {
1.3 millert 83: if (vflag)
84: printf("set %s", file);
1.5 deraadt 85: if ((tp = strrchr(file, '\n')))
1.3 millert 86: *tp = '\0';
87: vlex(file);
88: }
1.11 deraadt 89: fclose(fp);
1.1 deraadt 90: }
91: }
92: /*
93: * To allow definition of exception prior to fork
94: */
95: vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC);
96: }
97:
98: /*VARARGS1*/
1.13 moritz 99: static void
1.11 deraadt 100: vassign(value_t *p, char *v)
1.1 deraadt 101: {
102: if (!vaccess(p->v_access, WRITE)) {
103: printf("access denied\r\n");
104: return;
105: }
1.11 deraadt 106:
1.1 deraadt 107: switch (p->v_type&TMASK) {
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: case NUMBER:
120: if (number(p->v_value) == number(v))
121: return;
1.4 millert 122: setnumber(p->v_value, number(v));
1.1 deraadt 123: break;
124: case BOOL:
125: if (boolean(p->v_value) == (*v != '!'))
126: return;
1.4 millert 127: setboolean(p->v_value, (*v != '!'));
1.1 deraadt 128: break;
129: case CHAR:
130: if (character(p->v_value) == *v)
131: return;
1.4 millert 132: setcharacter(p->v_value, *v);
1.1 deraadt 133: }
134: p->v_access |= CHANGED;
135: }
136:
1.5 deraadt 137: void
1.11 deraadt 138: vlex(char *s)
1.1 deraadt 139: {
1.7 millert 140: value_t *p;
1.11 deraadt 141: char *cp;
1.1 deraadt 142:
143: if (equal(s, "all")) {
144: for (p = vtable; p->v_name; p++)
145: if (vaccess(p->v_access, READ))
146: vprint(p);
147: } else {
148: do {
1.5 deraadt 149: if ((cp = vinterp(s, ' ')))
1.1 deraadt 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:
161: static void
1.11 deraadt 162: vtoken(char *s)
1.1 deraadt 163: {
1.7 millert 164: value_t *p;
165: char *cp;
1.1 deraadt 166:
1.5 deraadt 167: if ((cp = strchr(s, '='))) {
1.1 deraadt 168: *cp = '\0';
1.5 deraadt 169: if ((p = vlookup(s))) {
1.1 deraadt 170: cp++;
171: if (p->v_type&NUMBER)
1.11 deraadt 172: vassign(p, (char *)atoi(cp));
1.1 deraadt 173: else {
174: if (strcmp(s, "record") == 0)
175: cp = expand(cp);
176: vassign(p, cp);
177: }
178: return;
179: }
1.5 deraadt 180: } else if ((cp = strchr(s, '?'))) {
1.1 deraadt 181: *cp = '\0';
182: if ((p = vlookup(s)) && vaccess(p->v_access, READ)) {
183: vprint(p);
184: return;
185: }
186: } else {
187: if (*s != '!')
188: p = vlookup(s);
189: else
190: p = vlookup(s+1);
191: if (p != NOVAL) {
192: vassign(p, s);
193: return;
194: }
195: }
196: printf("%s: unknown variable\r\n", s);
197: }
198:
199: static void
1.11 deraadt 200: vprint(value_t *p)
1.1 deraadt 201: {
1.7 millert 202: char *cp;
1.1 deraadt 203:
204: if (col > 0 && col < MIDDLE)
205: while (col++ < MIDDLE)
206: putchar(' ');
207: col += size(p->v_name);
208: switch (p->v_type&TMASK) {
209:
210: case BOOL:
211: if (boolean(p->v_value) == FALSE) {
212: col++;
213: putchar('!');
214: }
215: printf("%s", p->v_name);
216: break;
217:
218: case STRING:
219: printf("%s=", p->v_name);
220: col++;
221: if (p->v_value) {
1.12 moritz 222: cp = interp(p->v_value);
1.1 deraadt 223: col += size(cp);
224: printf("%s", cp);
225: }
226: break;
227:
228: case NUMBER:
229: col += 6;
1.5 deraadt 230: printf("%s=%-5ld", p->v_name, number(p->v_value));
1.1 deraadt 231: break;
232:
233: case CHAR:
234: printf("%s=", p->v_name);
235: col++;
236: if (p->v_value) {
237: cp = ctrl(character(p->v_value));
238: col += size(cp);
239: printf("%s", cp);
240: }
241: break;
242: }
243: if (col >= MIDDLE) {
244: col = 0;
245: printf("\r\n");
246: return;
247: }
248: }
249:
250: static int
1.11 deraadt 251: vaccess(unsigned int mode, unsigned int rw)
1.1 deraadt 252: {
253: if (mode & (rw<<PUBLIC))
254: return (1);
255: if (mode & (rw<<PRIVATE))
256: return (1);
257: return ((mode & (rw<<ROOT)) && getuid() == 0);
258: }
259:
260: static value_t *
1.11 deraadt 261: vlookup(char *s)
1.1 deraadt 262: {
1.7 millert 263: value_t *p;
1.1 deraadt 264:
265: for (p = vtable; p->v_name; p++)
266: if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
267: return (p);
268: return (NULL);
269: }
270:
1.13 moritz 271: static char *
1.11 deraadt 272: vinterp(char *s, int stop)
1.1 deraadt 273: {
1.7 millert 274: char *p = s, c;
1.1 deraadt 275: int num;
276:
1.11 deraadt 277: while ((c = *s++) && c != stop) {
1.1 deraadt 278: switch (c) {
279:
280: case '^':
281: if (*s)
282: *p++ = *s++ - 0100;
283: else
284: *p++ = c;
285: break;
286:
287: case '\\':
288: num = 0;
289: c = *s++;
290: if (c >= '0' && c <= '7')
291: num = (num<<3)+(c-'0');
292: else {
1.7 millert 293: char *q = "n\nr\rt\tb\bf\f";
1.1 deraadt 294:
295: for (; *q; q++)
296: if (c == *q++) {
297: *p++ = *q;
298: goto cont;
299: }
300: *p++ = c;
301: cont:
302: break;
303: }
304: if ((c = *s++) >= '0' && c <= '7') {
305: num = (num<<3)+(c-'0');
306: if ((c = *s++) >= '0' && c <= '7')
307: num = (num<<3)+(c-'0');
308: else
309: s--;
310: } else
311: s--;
312: *p++ = num;
313: break;
314:
315: default:
316: *p++ = c;
317: }
1.11 deraadt 318: }
1.1 deraadt 319: *p = '\0';
320: return (c == stop ? s-1 : NULL);
321: }
322:
323: /*
324: * assign variable s with value v (for NUMBER or STRING or CHAR types)
325: */
1.5 deraadt 326: int
1.11 deraadt 327: vstring(char *s, char *v)
1.1 deraadt 328: {
1.7 millert 329: value_t *p;
1.1 deraadt 330:
1.11 deraadt 331: p = vlookup(s);
1.1 deraadt 332: if (p == 0)
333: return (1);
334: if (p->v_type&NUMBER)
1.11 deraadt 335: vassign(p, (char *)atoi(v));
1.1 deraadt 336: else {
337: if (strcmp(s, "record") == 0)
338: v = expand(v);
339: vassign(p, v);
340: }
341: return (0);
342: }