9804 hal-set-property should support --direct option
[unleashed.git] / usr / src / cmd / tip / value.c
blobaabe0f49ab6647df0960c3996b39d203d3d3b6ac
1 /*
2 * Copyright 2000 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
6 /*
7 * Copyright (c) 1983 Regents of the University of California.
8 * All rights reserved. The Berkeley software License Agreement
9 * specifies the terms and conditions for redistribution.
12 #pragma ident "%Z%%M% %I% %E% SMI"
14 #include "tip.h"
16 #define MIDDLE 35
18 static value_t *vlookup(char *);
19 static int col = 0;
21 extern char *interp(char *);
23 static void vtoken(char *);
24 static void vprint(value_t *);
25 static int vaccess(unsigned, unsigned);
28 * Variable manipulation
30 void
31 vinit(void)
33 value_t *p;
34 char *cp;
35 FILE *f;
36 char file[1024];
38 for (p = vtable; p->v_name != NULL; p++) {
39 if (p->v_type&ENVIRON)
40 if (cp = getenv(p->v_name))
41 p->v_value = cp;
42 if (p->v_type&IREMOTE)
43 number(p->v_value) = *address(p->v_value);
46 * Read the .tiprc file in the HOME directory
47 * for sets
49 if ((cp = value(HOME)) == NULL)
50 cp = "";
51 (void) strlcpy(file, cp, sizeof (file));
52 (void) strlcat(file, "/.tiprc", sizeof (file));
53 if ((f = fopen(file, "r")) != NULL) {
54 char *tp;
56 while (fgets(file, sizeof (file)-1, f) != NULL) {
57 if (file[0] == '#')
58 continue;
59 if (vflag)
60 (void) printf("set %s", file);
61 if (tp = strrchr(file, '\n'))
62 *tp = '\0';
63 vlex(file);
65 (void) fclose(f);
68 * To allow definition of exception prior to fork
70 vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC);
73 /*VARARGS1*/
74 void
75 vassign(value_t *p, char *v)
78 if (!vaccess(p->v_access, WRITE)) {
79 (void) printf("access denied\r\n");
80 return;
82 switch (p->v_type&TMASK) {
84 case STRING:
85 if (p->v_value != (char *)NULL) {
86 if (equal(p->v_value, v))
87 return;
88 if (!(p->v_type&(ENVIRON|INIT)))
89 free(p->v_value);
91 if ((p->v_value = malloc(strlen(v)+1)) == NOSTR) {
92 (void) printf("out of core\r\n");
93 return;
95 p->v_type &= ~(ENVIRON|INIT);
96 (void) strcpy(p->v_value, v);
97 break;
99 case NUMBER:
100 if (number(p->v_value) == number(v))
101 return;
102 number(p->v_value) = number(v);
103 break;
105 case BOOL:
106 if (boolean(p->v_value) == (*v != '!'))
107 return;
108 boolean(p->v_value) = (*v != '!');
109 break;
111 case CHAR:
112 if (character(p->v_value) == *v)
113 return;
114 character(p->v_value) = *v;
116 p->v_access |= CHANGED;
119 void
120 vlex(char *s)
122 value_t *p;
124 if (equal(s, "all")) {
125 for (p = vtable; p->v_name; p++)
126 if (vaccess(p->v_access, READ))
127 vprint(p);
128 } else {
129 char *cp;
131 do {
132 if (cp = vinterp(s, ' '))
133 cp++;
134 vtoken(s);
135 s = cp;
136 } while (s);
138 if (col > 0) {
139 (void) printf("\r\n");
140 col = 0;
144 static void
145 vtoken(char *s)
147 value_t *p;
148 char *cp, *cp2;
150 if (cp = strchr(s, '=')) {
151 *cp = '\0';
152 if (p = vlookup(s)) {
153 cp++;
154 if (p->v_type&NUMBER)
155 vassign(p, (char *)atoi(cp));
156 else {
157 if (strcmp(s, "record") == 0)
158 if ((cp2 = expand(cp)) != NOSTR)
159 cp = cp2;
160 vassign(p, cp);
162 return;
164 } else if (cp = strchr(s, '?')) {
165 *cp = '\0';
166 if ((p = vlookup(s)) != NULL && vaccess(p->v_access, READ)) {
167 vprint(p);
168 return;
170 } else {
171 if (*s != '!')
172 p = vlookup(s);
173 else
174 p = vlookup(s+1);
175 if (p != NOVAL) {
176 if (p->v_type&BOOL)
177 vassign(p, s);
178 else
179 (void) printf("%s: no value specified\r\n", s);
180 return;
183 (void) printf("%s: unknown variable\r\n", s);
186 static void
187 vprint(value_t *p)
189 char *cp;
191 if (col > 0 && col < MIDDLE)
192 while (col++ < MIDDLE)
193 (void) putchar(' ');
194 col += strlen(p->v_name);
195 switch (p->v_type&TMASK) {
197 case BOOL:
198 if (boolean(p->v_value) == FALSE) {
199 col++;
200 (void) putchar('!');
202 (void) printf("%s", p->v_name);
203 break;
205 case STRING:
206 (void) printf("%s=", p->v_name);
207 col++;
208 if (p->v_value) {
209 cp = interp(p->v_value);
210 col += strlen(cp);
211 (void) printf("%s", cp);
213 break;
215 case NUMBER:
216 col += 6;
217 (void) printf("%s=%-5d", p->v_name, number(p->v_value));
218 break;
220 case CHAR:
221 (void) printf("%s=", p->v_name);
222 col++;
223 if (p->v_value) {
224 cp = ctrl(character(p->v_value));
225 col += strlen(cp);
226 (void) printf("%s", cp);
228 break;
230 if (col >= MIDDLE) {
231 col = 0;
232 (void) printf("\r\n");
233 return;
238 static int
239 vaccess(unsigned mode, unsigned rw)
241 if (mode & (rw<<PUBLIC))
242 return (1);
243 if (mode & (rw<<PRIVATE))
244 return (1);
245 return ((mode & (rw<<ROOT)) && uid == 0);
248 static value_t *
249 vlookup(char *s)
251 value_t *p;
253 for (p = vtable; p->v_name; p++)
254 if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s)))
255 return (p);
256 return (NULL);
259 char *
260 vinterp(char *s, char stop)
262 char *p = s, c;
263 int num;
265 while ((c = *s++) != 0 && c != stop)
266 switch (c) {
268 case '^':
269 if (*s)
270 *p++ = *s++ - 0100;
271 else
272 *p++ = c;
273 break;
275 case '\\':
276 num = 0;
277 c = *s++;
278 if (c >= '0' && c <= '7')
279 num = (num<<3)+(c-'0');
280 else {
281 char *q = "n\nr\rt\tb\bf\f";
283 for (; *q; q++)
284 if (c == *q++) {
285 *p++ = *q;
286 goto cont;
288 *p++ = c;
289 cont:
290 break;
292 if ((c = *s++) >= '0' && c <= '7') {
293 num = (num<<3)+(c-'0');
294 if ((c = *s++) >= '0' && c <= '7')
295 num = (num<<3)+(c-'0');
296 else
297 s--;
298 } else
299 s--;
300 *p++ = num;
301 break;
303 default:
304 *p++ = c;
306 *p = '\0';
307 return (c == stop ? s-1 : NULL);
311 * assign variable s with value v (for NUMBER or STRING or CHAR types)
314 vstring(char *s, char *v)
316 value_t *p;
317 char *v2;
319 p = vlookup(s);
320 if (p == 0)
321 return (1);
322 if (p->v_type&NUMBER)
323 vassign(p, (char *)atoi(v));
324 else {
325 if (strcmp(s, "record") == 0)
326 if ((v2 = expand(v)) != NOSTR)
327 v = v2;
328 vassign(p, v);
330 return (0);