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