value.c revision 113163
11553Srgrimes/* $OpenBSD: value.c,v 1.7 2001/10/24 18:38:58 millert Exp $ */ 21553Srgrimes/* $NetBSD: value.c,v 1.6 1997/02/11 09:24:09 mrg Exp $ */ 31553Srgrimes 41553Srgrimes/* 51553Srgrimes * Copyright (c) 1983, 1993 61553Srgrimes * The Regents of the University of California. All rights reserved. 71553Srgrimes * 81553Srgrimes * Redistribution and use in source and binary forms, with or without 91553Srgrimes * modification, are permitted provided that the following conditions 101553Srgrimes * are met: 111553Srgrimes * 1. Redistributions of source code must retain the above copyright 121553Srgrimes * notice, this list of conditions and the following disclaimer. 131553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 141553Srgrimes * notice, this list of conditions and the following disclaimer in the 151553Srgrimes * documentation and/or other materials provided with the distribution. 161553Srgrimes * 3. All advertising materials mentioning features or use of this software 171553Srgrimes * must display the following acknowledgement: 181553Srgrimes * This product includes software developed by the University of 191553Srgrimes * California, Berkeley and its contributors. 201553Srgrimes * 4. Neither the name of the University nor the names of its contributors 211553Srgrimes * may be used to endorse or promote products derived from this software 221553Srgrimes * without specific prior written permission. 231553Srgrimes * 241553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 251553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 281553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341553Srgrimes * SUCH DAMAGE. 351553Srgrimes */ 361553Srgrimes 371553Srgrimes#include <sys/cdefs.h> 381553Srgrimes__FBSDID("$FreeBSD: head/usr.bin/tip/tip/value.c 113163 2003-04-06 08:30:25Z imp $"); 391553Srgrimes 401553Srgrimes#ifndef lint 411553Srgrimes#if 0 421553Srgrimesstatic char sccsid[] = "@(#)value.c 8.1 (Berkeley) 6/6/93"; 431553Srgrimesstatic char rcsid[] = "$OpenBSD: value.c,v 1.7 2001/10/24 18:38:58 millert Exp $"; 441553Srgrimes#endif 451553Srgrimes#endif /* not lint */ 461553Srgrimes 471553Srgrimes#include "tip.h" 481553Srgrimes 491553Srgrimes#define MIDDLE 35 501553Srgrimes 511553Srgrimesstatic value_t *vlookup(); 521553Srgrimesstatic int col = 0; 531553Srgrimes 541553Srgrimes/* 551553Srgrimes * Variable manipulation 561553Srgrimes */ 571553Srgrimesvoid 581553Srgrimesvinit() 591553Srgrimes{ 601553Srgrimes value_t *p; 611553Srgrimes char *cp; 621553Srgrimes FILE *f; 631553Srgrimes char file[FILENAME_MAX]; 641553Srgrimes 651553Srgrimes for (p = vtable; p->v_name != NULL; p++) { 661553Srgrimes if (p->v_type&ENVIRON) 671553Srgrimes if ((cp = getenv(p->v_name))) 681553Srgrimes p->v_value = cp; 691553Srgrimes if (p->v_type&IREMOTE) 701553Srgrimes setnumber(p->v_value, *address(p->v_value)); 711553Srgrimes } 721553Srgrimes /* 731553Srgrimes * Read the .tiprc file in the HOME directory 741553Srgrimes * for sets 751553Srgrimes */ 761553Srgrimes if (strlen(value(HOME)) + sizeof("/.tiprc") > sizeof(file)) { 771553Srgrimes (void)fprintf(stderr, "Home directory path too long: %s\n", 781553Srgrimes value(HOME)); 791553Srgrimes } else { 801553Srgrimes snprintf(file, sizeof file, "%s/.tiprc", value(HOME)); 811553Srgrimes if ((f = fopen(file, "r")) != NULL) { 821553Srgrimes char *tp; 831553Srgrimes 841553Srgrimes while (fgets(file, sizeof(file)-1, f) != NULL) { 851553Srgrimes if (vflag) 861553Srgrimes printf("set %s", file); 871553Srgrimes if ((tp = strrchr(file, '\n'))) 8814961Smpp *tp = '\0'; 8914961Smpp vlex(file); 901553Srgrimes } 9114961Smpp fclose(f); 921553Srgrimes } 931553Srgrimes } 941553Srgrimes /* 951553Srgrimes * To allow definition of exception prior to fork 961553Srgrimes */ 971553Srgrimes vtable[EXCEPTIONS].v_access &= ~(WRITE<<PUBLIC); 981553Srgrimes} 991553Srgrimes 1001553Srgrimesstatic int vaccess(); 1011553Srgrimes 1021553Srgrimes/*VARARGS1*/ 1031553Srgrimesvoid 1041553Srgrimesvassign(p, v) 1051553Srgrimes value_t *p; 1061553Srgrimes char *v; 1071553Srgrimes{ 1081553Srgrimes 1091553Srgrimes if (!vaccess(p->v_access, WRITE)) { 1101553Srgrimes printf("access denied\r\n"); 1111553Srgrimes return; 1121553Srgrimes } 1131553Srgrimes switch (p->v_type&TMASK) { 1141553Srgrimes 1151553Srgrimes case STRING: 1161553Srgrimes if (p->v_value && equal(p->v_value, v)) 1171553Srgrimes return; 1181553Srgrimes if (!(p->v_type&(ENVIRON|INIT))) 1191553Srgrimes free(p->v_value); 1201553Srgrimes if ((p->v_value = strdup(v)) == NOSTR) { 1211553Srgrimes printf("out of core\r\n"); 1221553Srgrimes return; 1231553Srgrimes } 1241553Srgrimes p->v_type &= ~(ENVIRON|INIT); 1251553Srgrimes break; 1261553Srgrimes 1271553Srgrimes case NUMBER: 1281553Srgrimes if (number(p->v_value) == number(v)) 1291553Srgrimes return; 13014961Smpp setnumber(p->v_value, number(v)); 13114961Smpp break; 13214961Smpp 13314961Smpp case BOOL: 13414961Smpp if (boolean(p->v_value) == (*v != '!')) 13514961Smpp return; 13614961Smpp setboolean(p->v_value, (*v != '!')); 13714961Smpp break; 13814961Smpp 13914961Smpp case CHAR: 14014961Smpp if (character(p->v_value) == *v) 14114961Smpp return; 14214961Smpp setcharacter(p->v_value, *v); 14314961Smpp } 14414961Smpp p->v_access |= CHANGED; 14514961Smpp} 14614961Smpp 14714961Smppstatic void vprint(); 14814961Smppstatic void vtoken(); 1491553Srgrimes 1501553Srgrimesvoid 1511553Srgrimesvlex(s) 1521553Srgrimes char *s; 1531553Srgrimes{ 1541553Srgrimes value_t *p; 1551553Srgrimes 1561553Srgrimes if (equal(s, "all")) { 1571553Srgrimes for (p = vtable; p->v_name; p++) 1581553Srgrimes if (vaccess(p->v_access, READ)) 1591553Srgrimes vprint(p); 1601553Srgrimes } else { 1614782Sache char *cp; 1621553Srgrimes 1631553Srgrimes do { 1641553Srgrimes if ((cp = vinterp(s, ' '))) 1651553Srgrimes cp++; 1661553Srgrimes vtoken(s); 1671553Srgrimes s = cp; 1681553Srgrimes } while (s); 1691553Srgrimes } 1701553Srgrimes if (col > 0) { 1711553Srgrimes printf("\r\n"); 1724782Sache col = 0; 1731553Srgrimes } 1741553Srgrimes} 1751553Srgrimes 1761553Srgrimesstatic void 1771553Srgrimesvtoken(s) 1781553Srgrimes char *s; 1791553Srgrimes{ 1801553Srgrimes value_t *p; 1811553Srgrimes char *cp; 1821553Srgrimes char *expand(); 1831553Srgrimes 1841553Srgrimes if ((cp = strchr(s, '='))) { 1851553Srgrimes *cp = '\0'; 1861553Srgrimes if ((p = vlookup(s))) { 1871553Srgrimes cp++; 1881553Srgrimes if (p->v_type&NUMBER) 1891553Srgrimes vassign(p, atoi(cp)); 1901553Srgrimes else { 1911553Srgrimes if (strcmp(s, "record") == 0) 1921553Srgrimes cp = expand(cp); 1931553Srgrimes vassign(p, cp); 1941553Srgrimes } 1951553Srgrimes return; 1961553Srgrimes } 1971553Srgrimes } else if ((cp = strchr(s, '?'))) { 1981553Srgrimes *cp = '\0'; 1991553Srgrimes if ((p = vlookup(s)) && vaccess(p->v_access, READ)) { 2001553Srgrimes vprint(p); 2011553Srgrimes return; 2021553Srgrimes } 2031553Srgrimes } else { 2041553Srgrimes if (*s != '!') 2051553Srgrimes p = vlookup(s); 2061553Srgrimes else 2071553Srgrimes p = vlookup(s+1); 2081553Srgrimes if (p != NOVAL) { 2091553Srgrimes vassign(p, s); 2101553Srgrimes return; 2111553Srgrimes } 2121553Srgrimes } 2131553Srgrimes printf("%s: unknown variable\r\n", s); 2141553Srgrimes} 2151553Srgrimes 2161553Srgrimesstatic void 2171553Srgrimesvprint(p) 2181553Srgrimes value_t *p; 2191553Srgrimes{ 2201553Srgrimes char *cp; 2211553Srgrimes extern char *interp(); 2221553Srgrimes 2231553Srgrimes if (col > 0 && col < MIDDLE) 2241553Srgrimes while (col++ < MIDDLE) 2251553Srgrimes putchar(' '); 2261553Srgrimes col += size(p->v_name); 2271553Srgrimes switch (p->v_type&TMASK) { 2281553Srgrimes 2291553Srgrimes case BOOL: 2301553Srgrimes if (boolean(p->v_value) == FALSE) { 2311553Srgrimes col++; 2321553Srgrimes putchar('!'); 2331553Srgrimes } 2341553Srgrimes printf("%s", p->v_name); 2351553Srgrimes break; 2361553Srgrimes 2371553Srgrimes case STRING: 2381553Srgrimes printf("%s=", p->v_name); 2391553Srgrimes col++; 2401553Srgrimes if (p->v_value) { 2411553Srgrimes cp = interp(p->v_value, NULL); 2421553Srgrimes col += size(cp); 2431553Srgrimes printf("%s", cp); 2441553Srgrimes } 2451553Srgrimes break; 2461553Srgrimes 2471553Srgrimes case NUMBER: 2481553Srgrimes col += 6; 2491553Srgrimes printf("%s=%-5ld", p->v_name, number(p->v_value)); 2501553Srgrimes break; 2511553Srgrimes 2521553Srgrimes case CHAR: 2531553Srgrimes printf("%s=", p->v_name); 2541553Srgrimes col++; 2551553Srgrimes if (p->v_value) { 2561553Srgrimes cp = ctrl(character(p->v_value)); 2571553Srgrimes col += size(cp); 2581553Srgrimes printf("%s", cp); 2591553Srgrimes } 2601553Srgrimes break; 2611553Srgrimes } 2621553Srgrimes if (col >= MIDDLE) { 2631553Srgrimes col = 0; 2641553Srgrimes printf("\r\n"); 2651553Srgrimes return; 2661553Srgrimes } 2671553Srgrimes} 2681553Srgrimes 2691553Srgrimes 2701553Srgrimesstatic int 2711553Srgrimesvaccess(mode, rw) 2721553Srgrimes unsigned mode, rw; 2731553Srgrimes{ 2741553Srgrimes if (mode & (rw<<PUBLIC)) 2751553Srgrimes return (1); 2761553Srgrimes if (mode & (rw<<PRIVATE)) 2771553Srgrimes return (1); 2781553Srgrimes return ((mode & (rw<<ROOT)) && getuid() == 0); 2791553Srgrimes} 2801553Srgrimes 2811553Srgrimesstatic value_t * 2821553Srgrimesvlookup(s) 2831553Srgrimes char *s; 2841553Srgrimes{ 2851553Srgrimes value_t *p; 2861553Srgrimes 2871553Srgrimes for (p = vtable; p->v_name; p++) 2881553Srgrimes if (equal(p->v_name, s) || (p->v_abrev && equal(p->v_abrev, s))) 2891553Srgrimes return (p); 2901553Srgrimes return (NULL); 2911553Srgrimes} 2921553Srgrimes 2931553Srgrimeschar * 2941553Srgrimesvinterp(s, stop) 2951553Srgrimes char *s; 2961553Srgrimes char stop; 2971553Srgrimes{ 2981553Srgrimes char *p = s, c; 2991553Srgrimes int num; 3001553Srgrimes 3011553Srgrimes while ((c = *s++) && c != stop) 3021553Srgrimes switch (c) { 3031553Srgrimes 3041553Srgrimes case '^': 3051553Srgrimes if (*s) 3061553Srgrimes *p++ = *s++ - 0100; 3071553Srgrimes else 3081553Srgrimes *p++ = c; 3091553Srgrimes break; 3101553Srgrimes 3111553Srgrimes case '\\': 3121553Srgrimes num = 0; 3131553Srgrimes c = *s++; 3141553Srgrimes if (c >= '0' && c <= '7') 3151553Srgrimes num = (num<<3)+(c-'0'); 3161553Srgrimes else { 3171553Srgrimes char *q = "n\nr\rt\tb\bf\f"; 3181553Srgrimes 3191553Srgrimes for (; *q; q++) 3201553Srgrimes if (c == *q++) { 3211553Srgrimes *p++ = *q; 3221553Srgrimes goto cont; 3231553Srgrimes } 3241553Srgrimes *p++ = c; 3251553Srgrimes cont: 3261553Srgrimes break; 3271553Srgrimes } 3281553Srgrimes if ((c = *s++) >= '0' && c <= '7') { 3291553Srgrimes num = (num<<3)+(c-'0'); 3301553Srgrimes if ((c = *s++) >= '0' && c <= '7') 3311553Srgrimes num = (num<<3)+(c-'0'); 3321553Srgrimes else 3331553Srgrimes s--; 3341553Srgrimes } else 3351553Srgrimes s--; 3361553Srgrimes *p++ = num; 3371553Srgrimes break; 3381553Srgrimes 3391553Srgrimes default: 3401553Srgrimes *p++ = c; 3411553Srgrimes } 3421553Srgrimes *p = '\0'; 3431553Srgrimes return (c == stop ? s-1 : NULL); 3441553Srgrimes} 3451553Srgrimes 3461553Srgrimes/* 3471553Srgrimes * assign variable s with value v (for NUMBER or STRING or CHAR types) 3481553Srgrimes */ 3491553Srgrimesint 3501553Srgrimesvstring(s,v) 3511553Srgrimes char *s; 3521553Srgrimes char *v; 3531553Srgrimes{ 3541553Srgrimes value_t *p; 3551553Srgrimes char *expand(); 3561553Srgrimes 3571553Srgrimes p = vlookup(s); 3581553Srgrimes if (p == 0) 3591553Srgrimes return (1); 3601553Srgrimes if (p->v_type&NUMBER) 3611553Srgrimes vassign(p, atoi(v)); 3621553Srgrimes else { 3631553Srgrimes if (strcmp(s, "record") == 0) 3641553Srgrimes v = expand(v); 3651553Srgrimes vassign(p, v); 3661553Srgrimes } 3671553Srgrimes return (0); 3681553Srgrimes} 3691553Srgrimes