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