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