1 /* $OpenBSD: value.c,v 1.14 2006/03/17 22:02:58 moritz Exp $ */
2 /* $NetBSD: value.c,v 1.6 1997/02/11 09:24:09 mrg Exp $ */
5 * SPDX-License-Identifier: BSD-3-Clause
7 * Copyright (c) 1983, 1993
8 * The Regents of the University of California. All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
40 static char sccsid[] = "@(#)value.c 8.1 (Berkeley) 6/6/93";
41 static const char rcsid[] = "$OpenBSD: value.c,v 1.14 2006/03/17 22:02:58 moritz Exp $";
49 static value_t *vlookup(char *);
50 static void vassign(value_t *, char *);
51 static void vtoken(char *);
52 static void vprint(value_t *);
53 static int vaccess(unsigned int, unsigned int);
54 static char *vinterp(char *, int);
56 static size_t col = 0;
59 * Variable manipulation
64 char file[FILENAME_MAX], *cp;
68 for (p = vtable; p->v_name != NULL; p++) {
69 if (p->v_type&ENVIRON)
70 if ((cp = getenv(p->v_name)))
72 if (p->v_type&IREMOTE)
73 setnumber(p->v_value, *address(p->v_value));
76 * Read the .tiprc file in the HOME directory
82 "$HOME not set. Skipping check for ~/.tiprc\n");
83 } else if (strlen(cp) + sizeof("/.tiprc") > sizeof(file)) {
84 (void)fprintf(stderr, "Home directory path too long: %s\n",
87 snprintf(file, sizeof file, "%s/.tiprc", value(HOME));
88 if ((fp = fopen(file, "r")) != NULL) {
91 while (fgets(file, sizeof(file)-1, fp) != NULL) {
93 printf("set %s", file);
94 if ((tp = strrchr(file, '\n')))
102 * To allow definition of exception prior to fork
104 vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC);
109 vassign(value_t *p, char *v)
111 if (!vaccess(p->v_access, WRITE)) {
112 printf("access denied\r\n");
116 switch (p->v_type&TMASK) {
118 if (p->v_value && equal(p->v_value, v))
120 if (!(p->v_type&(ENVIRON|INIT)))
122 if ((p->v_value = strdup(v)) == NOSTR) {
123 printf("out of core\r\n");
126 p->v_type &= ~(ENVIRON|INIT);
129 if (number(p->v_value) == number(v))
131 setnumber(p->v_value, number(v));
134 if (boolean(p->v_value) == (*v != '!'))
136 setboolean(p->v_value, (*v != '!'));
139 if (character(p->v_value) == *v)
141 setcharacter(p->v_value, *v);
143 p->v_access |= CHANGED;
152 if (equal(s, "all")) {
153 for (p = vtable; p->v_name; p++)
154 if (vaccess(p->v_access, READ))
158 if ((cp = vinterp(s, ' ')))
176 if ((cp = strchr(s, '='))) {
178 if ((p = vlookup(s))) {
180 if (p->v_type&NUMBER)
181 vassign(p, (char *)(intptr_t)atoi(cp));
183 if (strcmp(s, "record") == 0)
189 } else if ((cp = strchr(s, '?'))) {
191 if ((p = vlookup(s)) && vaccess(p->v_access, READ)) {
205 printf("%s: unknown variable\r\n", s);
213 if (col > 0 && col < MIDDLE)
214 while (col++ < MIDDLE)
216 col += size(p->v_name);
217 switch (p->v_type&TMASK) {
220 if (boolean(p->v_value) == FALSE) {
224 printf("%s", p->v_name);
228 printf("%s=", p->v_name);
231 cp = interp(p->v_value);
239 printf("%s=%-5ld", p->v_name, number(p->v_value));
243 printf("%s=", p->v_name);
246 cp = ctrl(character(p->v_value));
260 vaccess(unsigned int mode, unsigned int rw)
262 if (mode & (rw<<PUBLIC))
264 if (mode & (rw<<PRIVATE))
266 return ((mode & (rw<<ROOT)) && getuid() == 0);
274 for (p = vtable; p->v_name; p++)
275 if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
281 vinterp(char *s, int stop)
286 while ((c = *s++) && c != stop) {
299 if (c >= '0' && c <= '7')
300 num = (num<<3)+(c-'0');
302 char *q = "n\nr\rt\tb\bf\f";
313 if ((c = *s++) >= '0' && c <= '7') {
314 num = (num<<3)+(c-'0');
315 if ((c = *s++) >= '0' && c <= '7')
316 num = (num<<3)+(c-'0');
329 return (c == stop ? s-1 : NULL);
333 * assign variable s with value v (for NUMBER or STRING or CHAR types)
336 vstring(char *s, char *v)
343 if (p->v_type&NUMBER)
344 vassign(p, (char *)(intptr_t)atoi(v));
346 if (strcmp(s, "record") == 0)