Annotation of src/usr.bin/tip/value.c, Revision 1.11
1.11 ! deraadt 1: /* $OpenBSD: value.c,v 1.10 2003/06/03 02:56:18 millert 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.11 ! deraadt 37: static const char rcsid[] = "$OpenBSD: value.c,v 1.10 2003/06/03 02:56:18 millert 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 *);
! 45: static int vaccess(unsigned int mode, unsigned int rw);
1.1 deraadt 46: static int col = 0;
47:
48: /*
49: * Variable manipulation
50: */
1.5 deraadt 51: void
1.11 ! deraadt 52: vinit(void)
1.1 deraadt 53: {
1.11 ! deraadt 54: char file[FILENAME_MAX], *cp;
1.7 millert 55: value_t *p;
1.11 ! deraadt 56: FILE *fp;
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.11 ! deraadt 71: value(HOME));
1.3 millert 72: } else {
1.6 deraadt 73: snprintf(file, sizeof file, "%s/.tiprc", value(HOME));
1.11 ! deraadt 74: if ((fp = fopen(file, "r")) != NULL) {
1.7 millert 75: char *tp;
1.3 millert 76:
1.11 ! deraadt 77: while (fgets(file, sizeof(file)-1, fp) != NULL) {
1.3 millert 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: }
1.11 ! deraadt 84: fclose(fp);
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: /*VARARGS1*/
1.5 deraadt 94: void
1.11 ! deraadt 95: vassign(value_t *p, char *v)
1.1 deraadt 96: {
97:
98: if (!vaccess(p->v_access, WRITE)) {
99: printf("access denied\r\n");
100: return;
101: }
1.11 ! deraadt 102:
1.1 deraadt 103: switch (p->v_type&TMASK) {
104: case STRING:
105: if (p->v_value && equal(p->v_value, v))
106: return;
107: if (!(p->v_type&(ENVIRON|INIT)))
108: free(p->v_value);
1.4 millert 109: if ((p->v_value = strdup(v)) == NOSTR) {
1.1 deraadt 110: printf("out of core\r\n");
111: return;
112: }
113: p->v_type &= ~(ENVIRON|INIT);
114: break;
115: case NUMBER:
116: if (number(p->v_value) == number(v))
117: return;
1.4 millert 118: setnumber(p->v_value, number(v));
1.1 deraadt 119: break;
120: case BOOL:
121: if (boolean(p->v_value) == (*v != '!'))
122: return;
1.4 millert 123: setboolean(p->v_value, (*v != '!'));
1.1 deraadt 124: break;
125: case CHAR:
126: if (character(p->v_value) == *v)
127: return;
1.4 millert 128: setcharacter(p->v_value, *v);
1.1 deraadt 129: }
130: p->v_access |= CHANGED;
131: }
132:
133: static void vprint();
1.4 millert 134: static void vtoken();
1.1 deraadt 135:
1.5 deraadt 136: void
1.11 ! deraadt 137: vlex(char *s)
1.1 deraadt 138: {
1.7 millert 139: value_t *p;
1.11 ! deraadt 140: char *cp;
1.1 deraadt 141:
142: if (equal(s, "all")) {
143: for (p = vtable; p->v_name; p++)
144: if (vaccess(p->v_access, READ))
145: vprint(p);
146: } else {
147: do {
1.5 deraadt 148: if ((cp = vinterp(s, ' ')))
1.1 deraadt 149: cp++;
150: vtoken(s);
151: s = cp;
152: } while (s);
153: }
154: if (col > 0) {
155: printf("\r\n");
156: col = 0;
157: }
158: }
159:
160: static void
1.11 ! deraadt 161: vtoken(char *s)
1.1 deraadt 162: {
1.7 millert 163: value_t *p;
164: char *cp;
1.11 ! deraadt 165: char *expand(char *);
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.11 ! deraadt 202: extern char *interp();
1.7 millert 203: char *cp;
1.1 deraadt 204:
205: if (col > 0 && col < MIDDLE)
206: while (col++ < MIDDLE)
207: putchar(' ');
208: col += size(p->v_name);
209: switch (p->v_type&TMASK) {
210:
211: case BOOL:
212: if (boolean(p->v_value) == FALSE) {
213: col++;
214: putchar('!');
215: }
216: printf("%s", p->v_name);
217: break;
218:
219: case STRING:
220: printf("%s=", p->v_name);
221: col++;
222: if (p->v_value) {
223: cp = interp(p->v_value, NULL);
224: col += size(cp);
225: printf("%s", cp);
226: }
227: break;
228:
229: case NUMBER:
230: col += 6;
1.5 deraadt 231: printf("%s=%-5ld", p->v_name, number(p->v_value));
1.1 deraadt 232: break;
233:
234: case CHAR:
235: printf("%s=", p->v_name);
236: col++;
237: if (p->v_value) {
238: cp = ctrl(character(p->v_value));
239: col += size(cp);
240: printf("%s", cp);
241: }
242: break;
243: }
244: if (col >= MIDDLE) {
245: col = 0;
246: printf("\r\n");
247: return;
248: }
249: }
250:
251:
252: static int
1.11 ! deraadt 253: vaccess(unsigned int mode, unsigned int rw)
1.1 deraadt 254: {
255: if (mode & (rw<<PUBLIC))
256: return (1);
257: if (mode & (rw<<PRIVATE))
258: return (1);
259: return ((mode & (rw<<ROOT)) && getuid() == 0);
260: }
261:
262: static value_t *
1.11 ! deraadt 263: vlookup(char *s)
1.1 deraadt 264: {
1.7 millert 265: value_t *p;
1.1 deraadt 266:
267: for (p = vtable; p->v_name; p++)
268: if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
269: return (p);
270: return (NULL);
271: }
272:
273: char *
1.11 ! deraadt 274: vinterp(char *s, int stop)
1.1 deraadt 275: {
1.7 millert 276: char *p = s, c;
1.1 deraadt 277: int num;
278:
1.11 ! deraadt 279: while ((c = *s++) && c != stop) {
1.1 deraadt 280: switch (c) {
281:
282: case '^':
283: if (*s)
284: *p++ = *s++ - 0100;
285: else
286: *p++ = c;
287: break;
288:
289: case '\\':
290: num = 0;
291: c = *s++;
292: if (c >= '0' && c <= '7')
293: num = (num<<3)+(c-'0');
294: else {
1.7 millert 295: char *q = "n\nr\rt\tb\bf\f";
1.1 deraadt 296:
297: for (; *q; q++)
298: if (c == *q++) {
299: *p++ = *q;
300: goto cont;
301: }
302: *p++ = c;
303: cont:
304: break;
305: }
306: if ((c = *s++) >= '0' && c <= '7') {
307: num = (num<<3)+(c-'0');
308: if ((c = *s++) >= '0' && c <= '7')
309: num = (num<<3)+(c-'0');
310: else
311: s--;
312: } else
313: s--;
314: *p++ = num;
315: break;
316:
317: default:
318: *p++ = c;
319: }
1.11 ! deraadt 320: }
1.1 deraadt 321: *p = '\0';
322: return (c == stop ? s-1 : NULL);
323: }
324:
325: /*
326: * assign variable s with value v (for NUMBER or STRING or CHAR types)
327: */
1.5 deraadt 328: int
1.11 ! deraadt 329: vstring(char *s, char *v)
1.1 deraadt 330: {
1.7 millert 331: value_t *p;
1.11 ! deraadt 332: char *expand(char *);
1.1 deraadt 333:
1.11 ! deraadt 334: p = vlookup(s);
1.1 deraadt 335: if (p == 0)
336: return (1);
337: if (p->v_type&NUMBER)
1.11 ! deraadt 338: vassign(p, (char *)atoi(v));
1.1 deraadt 339: else {
340: if (strcmp(s, "record") == 0)
341: v = expand(v);
342: vassign(p, v);
343: }
344: return (0);
345: }