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