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