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