value.c revision 50477
1/* 2 * Copyright (c) 1983, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. All advertising materials mentioning features or use of this software 14 * must display the following acknowledgement: 15 * This product includes software developed by the University of 16 * California, Berkeley and its contributors. 17 * 4. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34#ifndef lint 35#if 0 36static char sccsid[] = "@(#)value.c 8.1 (Berkeley) 6/6/93"; 37#endif 38static const char rcsid[] = 39 "$FreeBSD: head/usr.bin/tip/tip/value.c 50477 1999-08-28 01:08:13Z peter $"; 40#endif /* not lint */ 41 42#include "tip.h" 43 44#define MIDDLE 35 45 46static value_t *vlookup(); 47int vstring __P((char *, char *)); 48void vlex __P((char *)); 49void vassign __P((value_t *, char *)); 50 51static int col = 0; 52 53/* 54 * Variable manipulation 55 */ 56void 57vinit() 58{ 59 register value_t *p; 60 register char *cp; 61 FILE *f; 62 char file[256]; 63 64 for (p = vtable; p->v_name != NULL; p++) { 65 if (p->v_type&ENVIRON) 66 if ((cp = getenv(p->v_name))) 67 p->v_value = cp; 68 if (p->v_type&IREMOTE) 69 if (p->v_type&STRING) 70 p->v_value = *(char **) address(p->v_value); 71 else 72 number(p->v_value) = *address(p->v_value); 73 } 74 /* 75 * Read the .tiprc file in the HOME directory 76 * for sets 77 */ 78 strcpy(file, value(HOME)); 79 strcat(file, "/.tiprc"); 80 if ((f = fopen(file, "r")) != NULL) { 81 register char *tp; 82 83 while (fgets(file, sizeof(file)-1, f) != NULL) { 84 if (vflag) 85 printf("set %s", file); 86 if ((tp = rindex(file, '\n'))) 87 *tp = '\0'; 88 vlex(file); 89 } 90 fclose(f); 91 } 92 /* 93 * To allow definition of exception prior to fork 94 */ 95 vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC); 96} 97 98static int vaccess(); 99 100/*VARARGS1*/ 101void 102vassign(p, v) 103 register value_t *p; 104 char *v; 105{ 106 107 if (!vaccess(p->v_access, WRITE)) { 108 printf("access denied\r\n"); 109 return; 110 } 111 switch (p->v_type&TMASK) { 112 113 case STRING: 114 if (p->v_value && equal(p->v_value, v)) 115 return; 116 if (!(p->v_type&(ENVIRON|INIT))) 117 free(p->v_value); 118 if ((p->v_value = malloc(size(v)+1)) == NOSTR) { 119 printf("out of core\r\n"); 120 return; 121 } 122 p->v_type &= ~(ENVIRON|INIT); 123 strcpy(p->v_value, v); 124 break; 125 126 case NUMBER: 127 if (number(p->v_value) == number(v)) 128 return; 129 number(p->v_value) = number(v); 130 break; 131 132 case BOOL: 133 if (boolean(p->v_value) == (*v != '!')) 134 return; 135 boolean(p->v_value) = (*v != '!'); 136 break; 137 138 case CHAR: 139 if (character(p->v_value) == *v) 140 return; 141 character(p->v_value) = *v; 142 } 143 p->v_access |= CHANGED; 144} 145 146static void vprint(); 147 148void 149vlex(s) 150 register char *s; 151{ 152 register value_t *p; 153 static void vtoken(); 154 155 if (equal(s, "all")) { 156 for (p = vtable; p->v_name; p++) 157 if (vaccess(p->v_access, READ)) 158 vprint(p); 159 } else { 160 register char *cp; 161 162 do { 163 if ((cp = vinterp(s, ' '))) 164 cp++; 165 vtoken(s); 166 s = cp; 167 } while (s); 168 } 169 if (col > 0) { 170 printf("\r\n"); 171 col = 0; 172 } 173} 174 175static void 176vtoken(s) 177 register char *s; 178{ 179 register value_t *p; 180 register char *cp; 181 char *expand(); 182 183 if ((cp = index(s, '='))) { 184 *cp = '\0'; 185 if ((p = vlookup(s))) { 186 cp++; 187 if (p->v_type&NUMBER) 188 vassign(p, atoi(cp)); 189 else { 190 if (strcmp(s, "record") == 0) 191 cp = expand(cp); 192 vassign(p, cp); 193 } 194 return; 195 } 196 } else if ((cp = index(s, '?'))) { 197 *cp = '\0'; 198 if ((p = vlookup(s)) && vaccess(p->v_access, READ)) { 199 vprint(p); 200 return; 201 } 202 } else { 203 if (*s != '!') 204 p = vlookup(s); 205 else 206 p = vlookup(s+1); 207 if (p != NOVAL) { 208 vassign(p, s); 209 return; 210 } 211 } 212 printf("%s: unknown variable\r\n", s); 213} 214 215static void 216vprint(p) 217 register value_t *p; 218{ 219 register char *cp; 220 extern char *interp(), *ctrl(); 221 222 if (col > 0 && col < MIDDLE) 223 while (col++ < MIDDLE) 224 putchar(' '); 225 col += size(p->v_name); 226 switch (p->v_type&TMASK) { 227 228 case BOOL: 229 if (boolean(p->v_value) == FALSE) { 230 col++; 231 putchar('!'); 232 } 233 printf("%s", p->v_name); 234 break; 235 236 case STRING: 237 printf("%s=", p->v_name); 238 col++; 239 if (p->v_value) { 240 cp = interp(p->v_value, NULL); 241 col += size(cp); 242 printf("%s", cp); 243 } 244 break; 245 246 case NUMBER: 247 col += 6; 248 printf("%s=%-5d", p->v_name, number(p->v_value)); 249 break; 250 251 case CHAR: 252 printf("%s=", p->v_name); 253 col++; 254 if (p->v_value) { 255 cp = ctrl(character(p->v_value)); 256 col += size(cp); 257 printf("%s", cp); 258 } 259 break; 260 } 261 if (col >= MIDDLE) { 262 col = 0; 263 printf("\r\n"); 264 return; 265 } 266} 267 268 269static int 270vaccess(mode, rw) 271 register unsigned mode, rw; 272{ 273 if (mode & (rw<<PUBLIC)) 274 return (1); 275 if (mode & (rw<<PRIVATE)) 276 return (1); 277 return ((mode & (rw<<ROOT)) && getuid() == 0); 278} 279 280static value_t * 281vlookup(s) 282 register char *s; 283{ 284 register value_t *p; 285 286 for (p = vtable; p->v_name; p++) 287 if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s))) 288 return (p); 289 return (NULL); 290} 291 292char * 293vinterp(s, stop) 294 register char *s; 295 char stop; 296{ 297 register char *p = s, c; 298 int num; 299 300 while ((c = *s++) && c != stop) 301 switch (c) { 302 303 case '^': 304 if (*s) 305 *p++ = *s++ - 0100; 306 else 307 *p++ = c; 308 break; 309 310 case '\\': 311 num = 0; 312 c = *s++; 313 if (c >= '0' && c <= '7') 314 num = (num<<3)+(c-'0'); 315 else { 316 register char *q = "n\nr\rt\tb\bf\f"; 317 318 for (; *q; q++) 319 if (c == *q++) { 320 *p++ = *q; 321 goto cont; 322 } 323 *p++ = c; 324 cont: 325 break; 326 } 327 if ((c = *s++) >= '0' && c <= '7') { 328 num = (num<<3)+(c-'0'); 329 if ((c = *s++) >= '0' && c <= '7') 330 num = (num<<3)+(c-'0'); 331 else 332 s--; 333 } else 334 s--; 335 *p++ = num; 336 break; 337 338 default: 339 *p++ = c; 340 } 341 *p = '\0'; 342 return (c == stop ? s-1 : NULL); 343} 344 345/* 346 * assign variable s with value v (for NUMBER or STRING or CHAR types) 347 */ 348 349int 350vstring(s,v) 351 register char *s; 352 register char *v; 353{ 354 register value_t *p; 355 char *expand(); 356 357 p = vlookup(s); 358 if (p == 0) 359 return (1); 360 if (p->v_type&NUMBER) 361 vassign(p, atoi(v)); 362 else { 363 if (strcmp(s, "record") == 0) 364 v = expand(v); 365 vassign(p, v); 366 } 367 return (0); 368} 369