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