intrp.c revision 1.8 1 1.2 kamil /* Header: /usr/src/games/warp/RCS/intrp.c,v 1.2 87/07/03 00:56:37 games Exp
2 1.1 kamil *
3 1.1 kamil * Revision 7.0.1.2 86/12/12 16:59:04 lwall
4 1.1 kamil * Baseline for net release.
5 1.8 rillig *
6 1.1 kamil * Revision 7.0.1.1 86/10/16 10:51:43 lwall
7 1.1 kamil * Added Damage. Fixed random bugs.
8 1.8 rillig *
9 1.1 kamil * Revision 7.0 86/10/08 15:12:19 lwall
10 1.1 kamil * Split into separate files. Added amoebas and pirates.
11 1.8 rillig *
12 1.1 kamil */
13 1.1 kamil
14 1.1 kamil #include "EXTERN.h"
15 1.1 kamil #include "warp.h"
16 1.1 kamil #include "sig.h"
17 1.1 kamil #include "util.h"
18 1.1 kamil #include "term.h"
19 1.1 kamil #include "INTERN.h"
20 1.1 kamil #include "intrp.h"
21 1.1 kamil
22 1.1 kamil /* name of this host */
23 1.1 kamil char *hostname;
24 1.1 kamil
25 1.1 kamil #ifdef TILDENAME
26 1.4 christos static char *tildename = NULL;
27 1.4 christos static char *tildedir = NULL;
28 1.1 kamil #endif
29 1.1 kamil
30 1.4 christos static char *getrealname(uid_t);
31 1.1 kamil #ifdef CONDSUB
32 1.4 christos static char *skipinterp(const char *, const char *);
33 1.1 kamil #endif
34 1.1 kamil
35 1.7 joerg __dead static void abort_interp(void);
36 1.1 kamil
37 1.1 kamil void
38 1.4 christos intrp_init(char *tcbuf)
39 1.1 kamil {
40 1.1 kamil /* get environmental stuff */
41 1.1 kamil
42 1.1 kamil /* get home directory */
43 1.1 kamil
44 1.1 kamil homedir = getenv("HOME");
45 1.4 christos if (homedir == NULL)
46 1.1 kamil homedir = getenv("LOGDIR");
47 1.1 kamil
48 1.1 kamil dotdir = getval("DOTDIR",homedir);
49 1.1 kamil
50 1.1 kamil /* get login name */
51 1.1 kamil
52 1.1 kamil logname = getenv("USER");
53 1.4 christos if (logname == NULL)
54 1.1 kamil logname = getenv("LOGNAME");
55 1.1 kamil #ifdef GETLOGIN
56 1.4 christos if (logname == NULL)
57 1.1 kamil logname = savestr(getlogin());
58 1.1 kamil #endif
59 1.8 rillig
60 1.1 kamil /* get the real name of the person (%N) */
61 1.1 kamil /* Must be done after logname is read in because BERKNAMES uses that */
62 1.1 kamil
63 1.1 kamil strcpy(tcbuf,getrealname(getuid()));
64 1.1 kamil realname = savestr(tcbuf);
65 1.1 kamil
66 1.1 kamil /* name of this host (%H) */
67 1.1 kamil
68 1.1 kamil gethostname(buf,sizeof buf);
69 1.1 kamil hostname = savestr(buf);
70 1.6 christos if (strchr(hostname,'.'))
71 1.1 kamil hostname = savestr(hostname);
72 1.1 kamil else {
73 1.1 kamil char hname[128];
74 1.1 kamil
75 1.1 kamil strcpy(hname,hostname);
76 1.1 kamil strcat(hname,MYDOMAIN);
77 1.1 kamil hostname=savestr(hname);
78 1.1 kamil }
79 1.1 kamil warplib = savestr(filexp(WARPLIB));
80 1.1 kamil
81 1.1 kamil if (scorespec) /* that getwd below takes ~1/3 sec. */
82 1.1 kamil return; /* and we do not need it for -s */
83 1.4 christos (void) getcwd(tcbuf, sizeof(tcbuf));/* find working directory name */
84 1.1 kamil origdir = savestr(tcbuf); /* and remember it */
85 1.1 kamil }
86 1.1 kamil
87 1.1 kamil /* expand filename via %, ~, and $ interpretation */
88 1.1 kamil /* returns pointer to static area */
89 1.1 kamil /* Note that there is a 1-deep cache of ~name interpretation */
90 1.1 kamil
91 1.1 kamil char *
92 1.4 christos filexp(const char *s)
93 1.1 kamil {
94 1.1 kamil static char filename[CBUFLEN];
95 1.1 kamil char scrbuf[CBUFLEN];
96 1.4 christos char *d;
97 1.1 kamil
98 1.1 kamil #ifdef DEBUGGING
99 1.1 kamil if (debug & DEB_FILEXP)
100 1.1 kamil printf("< %s\r\n",s);
101 1.1 kamil #endif
102 1.1 kamil interp(filename, (sizeof filename), s); /* interpret any % escapes */
103 1.1 kamil #ifdef DEBUGGING
104 1.1 kamil if (debug & DEB_FILEXP)
105 1.1 kamil printf("%% %s\r\n",filename);
106 1.1 kamil #endif
107 1.1 kamil s = filename;
108 1.1 kamil if (*s == '~') { /* does destination start with ~? */
109 1.1 kamil if (!*(++s) || *s == '/') {
110 1.4 christos snprintf(scrbuf, sizeof(scrbuf), "%s%s",homedir,s);
111 1.1 kamil /* swap $HOME for it */
112 1.1 kamil #ifdef DEBUGGING
113 1.1 kamil if (debug & DEB_FILEXP)
114 1.1 kamil printf("~ %s\r\n",scrbuf);
115 1.1 kamil #endif
116 1.1 kamil strcpy(filename,scrbuf);
117 1.1 kamil }
118 1.1 kamil else {
119 1.1 kamil #ifdef TILDENAME
120 1.4 christos for (d=scrbuf; isalnum((unsigned char)*s); s++,d++)
121 1.1 kamil *d = *s;
122 1.1 kamil *d = '\0';
123 1.1 kamil if (tildedir && strEQ(tildename,scrbuf)) {
124 1.1 kamil strcpy(scrbuf,tildedir);
125 1.1 kamil strcat(scrbuf, s);
126 1.1 kamil strcpy(filename, scrbuf);
127 1.1 kamil #ifdef DEBUGGING
128 1.1 kamil if (debug & DEB_FILEXP)
129 1.1 kamil printf("r %s %s\r\n",tildename,tildedir);
130 1.1 kamil #endif
131 1.1 kamil }
132 1.1 kamil else {
133 1.1 kamil if (tildename) {
134 1.1 kamil free(tildename);
135 1.1 kamil free(tildedir);
136 1.1 kamil }
137 1.4 christos tildedir = NULL;
138 1.1 kamil tildename = savestr(scrbuf);
139 1.1 kamil {
140 1.1 kamil struct passwd *pwd = getpwnam(tildename);
141 1.1 kamil
142 1.4 christos snprintf(scrbuf, sizeof(scrbuf), "%s%s",pwd->pw_dir,s);
143 1.1 kamil tildedir = savestr(pwd->pw_dir);
144 1.1 kamil strcpy(filename,scrbuf);
145 1.1 kamil endpwent();
146 1.1 kamil }
147 1.1 kamil }
148 1.1 kamil #else /* !TILDENAME */
149 1.1 kamil #ifdef VERBOSE
150 1.1 kamil IF(verbose)
151 1.1 kamil fputs("~loginname not implemented.\r\n",stdout);
152 1.1 kamil ELSE
153 1.1 kamil #endif
154 1.1 kamil #ifdef TERSE
155 1.1 kamil fputs("~login not impl.\r\n",stdout);
156 1.1 kamil #endif
157 1.1 kamil #endif
158 1.1 kamil }
159 1.1 kamil }
160 1.1 kamil else if (*s == '$') { /* starts with some env variable? */
161 1.1 kamil d = scrbuf;
162 1.1 kamil *d++ = '%';
163 1.1 kamil if (s[1] == '{')
164 1.1 kamil strcpy(d,s+2);
165 1.1 kamil else {
166 1.1 kamil *d++ = '{';
167 1.4 christos for (s++; isalnum((unsigned char)*s); s++) *d++ = *s;
168 1.1 kamil /* skip over token */
169 1.1 kamil *d++ = '}';
170 1.1 kamil strcpy(d,s);
171 1.1 kamil }
172 1.1 kamil #ifdef DEBUGGING
173 1.1 kamil if (debug & DEB_FILEXP)
174 1.1 kamil printf("$ %s\r\n",scrbuf);
175 1.1 kamil #endif
176 1.1 kamil interp(filename, (sizeof filename), scrbuf);
177 1.1 kamil /* this might do some extra '%'s but */
178 1.1 kamil /* that is how the Mercedes Benz */
179 1.1 kamil }
180 1.1 kamil #ifdef DEBUGGING
181 1.1 kamil if (debug & DEB_FILEXP)
182 1.1 kamil printf("> %s\r\n",filename);
183 1.1 kamil #endif
184 1.1 kamil return filename;
185 1.1 kamil }
186 1.1 kamil
187 1.1 kamil #ifdef CONDSUB
188 1.1 kamil /* skip interpolations */
189 1.1 kamil
190 1.4 christos static char *
191 1.4 christos skipinterp(const char *pattern, const char *stoppers)
192 1.1 kamil {
193 1.1 kamil
194 1.6 christos while (*pattern && (!stoppers || !strchr(stoppers,*pattern))) {
195 1.1 kamil #ifdef DEBUGGING
196 1.1 kamil if (debug & 8)
197 1.1 kamil printf("skipinterp till %s at %s\r\n",stoppers?stoppers:"",pattern);
198 1.1 kamil #endif
199 1.1 kamil if (*pattern == '%' && pattern[1]) {
200 1.1 kamil switch (*++pattern) {
201 1.1 kamil case '{':
202 1.1 kamil for (pattern++; *pattern && *pattern != '}'; pattern++)
203 1.1 kamil if (*pattern == '\\')
204 1.1 kamil pattern++;
205 1.1 kamil break;
206 1.1 kamil #ifdef CONDSUB
207 1.1 kamil case '(': {
208 1.1 kamil pattern = skipinterp(pattern+1,"!=");
209 1.1 kamil if (!*pattern)
210 1.1 kamil goto getout;
211 1.1 kamil for (pattern++; *pattern && *pattern != '?'; pattern++)
212 1.1 kamil if (*pattern == '\\')
213 1.1 kamil pattern++;
214 1.1 kamil if (!*pattern)
215 1.1 kamil goto getout;
216 1.1 kamil pattern = skipinterp(pattern+1,":)");
217 1.1 kamil if (*pattern == ':')
218 1.1 kamil pattern = skipinterp(pattern+1,")");
219 1.1 kamil break;
220 1.1 kamil }
221 1.1 kamil #endif
222 1.1 kamil #ifdef BACKTICK
223 1.1 kamil case '`': {
224 1.1 kamil pattern = skipinterp(pattern+1,"`");
225 1.1 kamil break;
226 1.1 kamil }
227 1.1 kamil #endif
228 1.1 kamil #ifdef PROMPTTTY
229 1.1 kamil case '"':
230 1.1 kamil pattern = skipinterp(pattern+1,"\"");
231 1.1 kamil break;
232 1.1 kamil #endif
233 1.1 kamil default:
234 1.1 kamil break;
235 1.1 kamil }
236 1.1 kamil pattern++;
237 1.1 kamil }
238 1.1 kamil else {
239 1.1 kamil if (*pattern == '^' && pattern[1])
240 1.1 kamil pattern += 2;
241 1.1 kamil else if (*pattern == '\\' && pattern[1])
242 1.1 kamil pattern += 2;
243 1.1 kamil else
244 1.1 kamil pattern++;
245 1.1 kamil }
246 1.1 kamil }
247 1.1 kamil getout:
248 1.4 christos return __UNCONST(pattern); /* where we left off */
249 1.1 kamil }
250 1.1 kamil #endif
251 1.1 kamil
252 1.3 kamil static char *mygets(char *str, size_t n)
253 1.3 kamil {
254 1.3 kamil char *ret;
255 1.3 kamil size_t last;
256 1.3 kamil
257 1.3 kamil if ((ret = fgets(str, n, stdin)) != NULL) {
258 1.3 kamil last = strlen(str) - 1;
259 1.3 kamil
260 1.3 kamil if (str[last] == '\n')
261 1.3 kamil str[last] = '\0';
262 1.3 kamil }
263 1.3 kamil
264 1.3 kamil return ret;
265 1.3 kamil }
266 1.3 kamil
267 1.1 kamil /* interpret interpolations */
268 1.1 kamil
269 1.1 kamil char *
270 1.4 christos dointerp(char *dest, size_t destsize, const char *pattern, const char *stoppers)
271 1.1 kamil {
272 1.4 christos char *s;
273 1.4 christos int i;
274 1.1 kamil char scrbuf[512];
275 1.4 christos bool upper = false;
276 1.4 christos bool lastcomp = false;
277 1.1 kamil int metabit = 0;
278 1.1 kamil
279 1.6 christos while (*pattern && (!stoppers || !strchr(stoppers,*pattern))) {
280 1.1 kamil #ifdef DEBUGGING
281 1.1 kamil if (debug & 8)
282 1.1 kamil printf("dointerp till %s at %s\r\n",stoppers?stoppers:"",pattern);
283 1.1 kamil #endif
284 1.1 kamil if (*pattern == '%' && pattern[1]) {
285 1.4 christos upper = false;
286 1.4 christos lastcomp = false;
287 1.4 christos for (s=NULL; !s; ) {
288 1.1 kamil switch (*++pattern) {
289 1.1 kamil case '^':
290 1.4 christos upper = true;
291 1.1 kamil break;
292 1.1 kamil case '_':
293 1.4 christos lastcomp = true;
294 1.1 kamil break;
295 1.1 kamil case '{':
296 1.1 kamil pattern = cpytill(scrbuf,pattern+1,'}');
297 1.6 christos if ((s = strchr(scrbuf,'-')) != NULL)
298 1.1 kamil *s++ = '\0';
299 1.1 kamil else
300 1.1 kamil s = nullstr;
301 1.1 kamil s = getval(scrbuf,s);
302 1.1 kamil break;
303 1.1 kamil #ifdef CONDSUB
304 1.1 kamil case '(': {
305 1.1 kamil char rch;
306 1.1 kamil bool matched;
307 1.8 rillig
308 1.1 kamil pattern = dointerp(dest,destsize,pattern+1,"!=");
309 1.1 kamil rch = *pattern;
310 1.1 kamil if (rch == '!')
311 1.1 kamil pattern++;
312 1.1 kamil if (*pattern != '=')
313 1.1 kamil goto getout;
314 1.1 kamil pattern = cpytill(scrbuf,pattern+1,'?');
315 1.1 kamil if (!*pattern)
316 1.1 kamil goto getout;
317 1.1 kamil if (*scrbuf == '^' && scrbuf[strlen(scrbuf)-1] == '$') {
318 1.1 kamil scrbuf[strlen(scrbuf)-1] = '\0';
319 1.1 kamil matched = strEQ(scrbuf+1,dest);
320 1.1 kamil }
321 1.1 kamil else
322 1.4 christos matched = instr(dest,scrbuf) != NULL;
323 1.1 kamil if (matched==(rch == '=')) {
324 1.1 kamil pattern = dointerp(dest,destsize,pattern+1,":)");
325 1.1 kamil if (*pattern == ':')
326 1.1 kamil pattern = skipinterp(pattern+1,")");
327 1.1 kamil }
328 1.1 kamil else {
329 1.1 kamil pattern = skipinterp(pattern+1,":)");
330 1.1 kamil if (*pattern == ':')
331 1.1 kamil pattern++;
332 1.1 kamil pattern = dointerp(dest,destsize,pattern,")");
333 1.1 kamil }
334 1.1 kamil s = dest;
335 1.1 kamil break;
336 1.1 kamil }
337 1.1 kamil #endif
338 1.1 kamil #ifdef BACKTICK
339 1.1 kamil case '`': {
340 1.4 christos FILE *pipefp;
341 1.1 kamil
342 1.1 kamil pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"`");
343 1.1 kamil pipefp = popen(scrbuf,"r");
344 1.4 christos if (pipefp != NULL) {
345 1.1 kamil int len;
346 1.1 kamil
347 1.1 kamil len = fread(scrbuf,sizeof(char),(sizeof scrbuf)-1,
348 1.1 kamil pipefp);
349 1.1 kamil scrbuf[len] = '\0';
350 1.1 kamil pclose(pipefp);
351 1.1 kamil }
352 1.1 kamil else {
353 1.1 kamil printf("\r\nCan't run %s\r\n",scrbuf);
354 1.1 kamil *scrbuf = '\0';
355 1.1 kamil }
356 1.1 kamil for (s=scrbuf; *s; s++) {
357 1.1 kamil if (*s == '\n') {
358 1.1 kamil if (s[1])
359 1.1 kamil *s = ' ';
360 1.1 kamil else
361 1.1 kamil *s = '\0';
362 1.1 kamil }
363 1.1 kamil }
364 1.1 kamil s = scrbuf;
365 1.1 kamil break;
366 1.1 kamil }
367 1.1 kamil #endif
368 1.1 kamil #ifdef PROMPTTTY
369 1.1 kamil case '"':
370 1.1 kamil pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"\"");
371 1.1 kamil fputs(scrbuf,stdout);
372 1.1 kamil resetty();
373 1.3 kamil mygets(scrbuf, sizeof(scrbuf));
374 1.1 kamil crmode();
375 1.1 kamil raw();
376 1.1 kamil noecho();
377 1.1 kamil nonl();
378 1.1 kamil s = scrbuf;
379 1.1 kamil break;
380 1.1 kamil #endif
381 1.1 kamil case '~':
382 1.1 kamil s = homedir;
383 1.1 kamil break;
384 1.1 kamil case '.':
385 1.1 kamil s = dotdir;
386 1.1 kamil break;
387 1.1 kamil case '$':
388 1.1 kamil s = scrbuf;
389 1.4 christos snprintf(scrbuf, sizeof(scrbuf), "%d",getpid());
390 1.1 kamil break;
391 1.1 kamil case 'H': /* host name */
392 1.1 kamil s = hostname;
393 1.1 kamil break;
394 1.1 kamil case 'L': /* login id */
395 1.1 kamil s = logname;
396 1.1 kamil break;
397 1.1 kamil case 'N': /* full name */
398 1.1 kamil s = getval("NAME",realname);
399 1.1 kamil break;
400 1.1 kamil case 'O':
401 1.1 kamil s = origdir;
402 1.1 kamil break;
403 1.1 kamil case 'p':
404 1.1 kamil s = cwd;
405 1.1 kamil break;
406 1.1 kamil case 'X': /* warp library */
407 1.1 kamil s = warplib;
408 1.1 kamil break;
409 1.1 kamil default:
410 1.1 kamil if (--destsize <= 0)
411 1.1 kamil abort_interp();
412 1.1 kamil *dest++ = *pattern | metabit;
413 1.1 kamil s = nullstr;
414 1.1 kamil break;
415 1.1 kamil }
416 1.1 kamil }
417 1.1 kamil if (!s)
418 1.1 kamil s = nullstr;
419 1.1 kamil pattern++;
420 1.1 kamil if (upper || lastcomp) {
421 1.1 kamil char *t;
422 1.1 kamil
423 1.1 kamil if (s != scrbuf) {
424 1.4 christos safecpy(scrbuf,s,(sizeof scrbuf));
425 1.1 kamil s = scrbuf;
426 1.1 kamil }
427 1.6 christos if (upper || !(t=strrchr(s,'/')))
428 1.1 kamil t = s;
429 1.4 christos while (*t && !isalpha((unsigned char)*t)) {
430 1.1 kamil t++;
431 1.4 christos *t = toupper((unsigned char)*t);
432 1.4 christos }
433 1.1 kamil }
434 1.1 kamil i = metabit; /* maybe get into register */
435 1.1 kamil if (s == dest) {
436 1.1 kamil while (*dest) {
437 1.1 kamil if (--destsize <= 0)
438 1.1 kamil abort_interp();
439 1.1 kamil *dest++ |= i;
440 1.1 kamil }
441 1.1 kamil }
442 1.1 kamil else {
443 1.1 kamil while (*s) {
444 1.1 kamil if (--destsize <= 0)
445 1.1 kamil abort_interp();
446 1.1 kamil *dest++ = *s++ | i;
447 1.1 kamil }
448 1.1 kamil }
449 1.1 kamil }
450 1.1 kamil else {
451 1.1 kamil if (--destsize <= 0)
452 1.1 kamil abort_interp();
453 1.1 kamil if (*pattern == '^' && pattern[1]) {
454 1.1 kamil ++pattern; /* skip uparrow */
455 1.1 kamil i = *pattern; /* get char into a register */
456 1.1 kamil if (i == '?')
457 1.1 kamil *dest++ = '\177' | metabit;
458 1.1 kamil else if (i == '(') {
459 1.1 kamil metabit = 0200;
460 1.1 kamil destsize++;
461 1.1 kamil }
462 1.1 kamil else if (i == ')') {
463 1.1 kamil metabit = 0;
464 1.1 kamil destsize++;
465 1.1 kamil }
466 1.1 kamil else
467 1.4 christos *dest++ = (i & 037) | metabit;
468 1.1 kamil pattern++;
469 1.1 kamil }
470 1.1 kamil else if (*pattern == '\\' && pattern[1]) {
471 1.1 kamil ++pattern; /* skip backslash */
472 1.1 kamil i = *pattern; /* get char into a register */
473 1.8 rillig
474 1.1 kamil /* this used to be a switch but the if may save space */
475 1.8 rillig
476 1.1 kamil if (i >= '0' && i <= '7') {
477 1.1 kamil i = 1;
478 1.1 kamil while (i < 01000 && *pattern >= '0' && *pattern <= '7') {
479 1.1 kamil i <<= 3;
480 1.1 kamil i += *pattern++ - '0';
481 1.1 kamil }
482 1.4 christos *dest++ = (i & 0377) | metabit;
483 1.1 kamil --pattern;
484 1.1 kamil }
485 1.1 kamil else if (i == 'b')
486 1.1 kamil *dest++ = '\b' | metabit;
487 1.1 kamil else if (i == 'f')
488 1.1 kamil *dest++ = '\f' | metabit;
489 1.1 kamil else if (i == 'n')
490 1.1 kamil *dest++ = '\n' | metabit;
491 1.1 kamil else if (i == 'r')
492 1.1 kamil *dest++ = '\r' | metabit;
493 1.1 kamil else if (i == 't')
494 1.1 kamil *dest++ = '\t' | metabit;
495 1.1 kamil else
496 1.1 kamil *dest++ = i | metabit;
497 1.1 kamil pattern++;
498 1.1 kamil }
499 1.1 kamil else
500 1.1 kamil *dest++ = *pattern++ | metabit;
501 1.1 kamil }
502 1.1 kamil }
503 1.1 kamil *dest = '\0';
504 1.1 kamil getout:
505 1.4 christos return __UNCONST(pattern); /* where we left off */
506 1.1 kamil }
507 1.1 kamil
508 1.1 kamil void
509 1.4 christos interp(char *dest, size_t destsize, const char *pattern)
510 1.1 kamil {
511 1.4 christos (void) dointerp(dest,destsize,pattern,NULL);
512 1.1 kamil #ifdef DEBUGGING
513 1.1 kamil if (debug & DEB_FILEXP)
514 1.1 kamil fputs(dest,stdout);
515 1.1 kamil #endif
516 1.1 kamil }
517 1.1 kamil
518 1.1 kamil /* get the person's real name from /etc/passwd */
519 1.1 kamil /* (string is overwritten, so it must be copied) */
520 1.1 kamil
521 1.4 christos static char *
522 1.4 christos getrealname(uid_t uid)
523 1.1 kamil {
524 1.1 kamil char *s, *c;
525 1.1 kamil
526 1.1 kamil #ifdef PASSNAMES
527 1.1 kamil struct passwd *pwd = getpwuid(uid);
528 1.8 rillig
529 1.1 kamil s = pwd->pw_gecos;
530 1.1 kamil #ifdef BERKNAMES
531 1.1 kamil #ifdef BERKJUNK
532 1.1 kamil while (*s && !isalnum(*s) && *s != '&') s++;
533 1.1 kamil #endif
534 1.6 christos if ((c = strchr(s, ',')) != NULL)
535 1.1 kamil *c = '\0';
536 1.6 christos if ((c = strchr(s, ';')) != NULL)
537 1.1 kamil *c = '\0';
538 1.1 kamil s = cpytill(buf,s,'&');
539 1.1 kamil if (*s == '&') { /* whoever thought this one up was */
540 1.1 kamil c = buf + strlen(buf); /* in the middle of the night */
541 1.1 kamil strcat(c,logname); /* before the morning after */
542 1.1 kamil strcat(c,s+1);
543 1.4 christos if (islower((unsigned char)*c))
544 1.4 christos *c = toupper((unsigned char)*c); /* gack and double gack */
545 1.1 kamil }
546 1.1 kamil #else
547 1.6 christos if ((c = strchr(s, '(')) != NULL)
548 1.1 kamil *c = '\0';
549 1.6 christos if ((c = strchr(s, '-')) != NULL)
550 1.1 kamil s = c;
551 1.1 kamil strcpy(buf,tmpbuf);
552 1.1 kamil #endif
553 1.1 kamil endpwent();
554 1.1 kamil return buf; /* return something static */
555 1.1 kamil #else
556 1.4 christos if ((tmpfp=fopen(filexp(FULLNAMEFILE),"r")) != NULL) {
557 1.4 christos fgets(buf,sizeof buf,tmpfp);
558 1.4 christos fclose(tmpfp);
559 1.1 kamil }
560 1.1 kamil else {
561 1.1 kamil resetty();
562 1.1 kamil printf("What is your name? ");
563 1.4 christos fgets(buf,(sizeof buf),stdin);
564 1.1 kamil crmode();
565 1.1 kamil raw();
566 1.1 kamil noecho();
567 1.1 kamil nonl();
568 1.1 kamil if (fork())
569 1.1 kamil wait(0);
570 1.1 kamil else {
571 1.5 christos setgid(getgid());
572 1.1 kamil if ((tmpfp = fopen(filexp(FULLNAMEFILE),"w")) == NULL)
573 1.1 kamil exit(1);
574 1.1 kamil fprintf(tmpfp, "%s\n", buf);
575 1.4 christos fclose(tmpfp);
576 1.1 kamil exit(0);
577 1.1 kamil }
578 1.1 kamil }
579 1.1 kamil buf[strlen(buf)-1] = '\0';
580 1.1 kamil return buf;
581 1.1 kamil #endif
582 1.1 kamil }
583 1.1 kamil
584 1.1 kamil static void
585 1.4 christos abort_interp(void)
586 1.1 kamil {
587 1.1 kamil fputs("\r\n% interp buffer overflow!\r\n",stdout);
588 1.1 kamil sig_catcher(0);
589 1.1 kamil }
590