]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - warp/intrp.c
1 /* Header: /usr/src/games/warp/RCS/intrp.c,v 1.2 87/07/03 00:56:37 games Exp
3 * Revision 7.0.1.2 86/12/12 16:59:04 lwall
4 * Baseline for net release.
6 * Revision 7.0.1.1 86/10/16 10:51:43 lwall
7 * Added Damage. Fixed random bugs.
9 * Revision 7.0 86/10/08 15:12:19 lwall
10 * Split into separate files. Added amoebas and pirates.
22 /* name of this host */
26 static char *tildename
= NULL
;
27 static char *tildedir
= NULL
;
30 static char *getrealname(uid_t
);
32 static char *skipinterp(const char *, const char *);
35 static void abort_interp(void);
38 intrp_init(char *tcbuf
)
40 /* get environmental stuff */
42 /* get home directory */
44 homedir
= getenv("HOME");
46 homedir
= getenv("LOGDIR");
48 dotdir
= getval("DOTDIR",homedir
);
52 logname
= getenv("USER");
54 logname
= getenv("LOGNAME");
57 logname
= savestr(getlogin());
60 /* get the real name of the person (%N) */
61 /* Must be done after logname is read in because BERKNAMES uses that */
63 strcpy(tcbuf
,getrealname(getuid()));
64 realname
= savestr(tcbuf
);
66 /* name of this host (%H) */
68 gethostname(buf
,sizeof buf
);
69 hostname
= savestr(buf
);
70 if (index(hostname
,'.'))
71 hostname
= savestr(hostname
);
75 strcpy(hname
,hostname
);
76 strcat(hname
,MYDOMAIN
);
77 hostname
=savestr(hname
);
79 warplib
= savestr(filexp(WARPLIB
));
81 if (scorespec
) /* that getwd below takes ~1/3 sec. */
82 return; /* and we do not need it for -s */
83 (void) getcwd(tcbuf
, sizeof(tcbuf
));/* find working directory name */
84 origdir
= savestr(tcbuf
); /* and remember it */
87 /* expand filename via %, ~, and $ interpretation */
88 /* returns pointer to static area */
89 /* Note that there is a 1-deep cache of ~name interpretation */
94 static char filename
[CBUFLEN
];
99 if (debug
& DEB_FILEXP
)
100 printf("< %s\r\n",s
);
102 interp(filename
, (sizeof filename
), s
); /* interpret any % escapes */
104 if (debug
& DEB_FILEXP
)
105 printf("%% %s\r\n",filename
);
108 if (*s
== '~') { /* does destination start with ~? */
109 if (!*(++s
) || *s
== '/') {
110 snprintf(scrbuf
, sizeof(scrbuf
), "%s%s",homedir
,s
);
111 /* swap $HOME for it */
113 if (debug
& DEB_FILEXP
)
114 printf("~ %s\r\n",scrbuf
);
116 strcpy(filename
,scrbuf
);
120 for (d
=scrbuf
; isalnum((unsigned char)*s
); s
++,d
++)
123 if (tildedir
&& strEQ(tildename
,scrbuf
)) {
124 strcpy(scrbuf
,tildedir
);
126 strcpy(filename
, scrbuf
);
128 if (debug
& DEB_FILEXP
)
129 printf("r %s %s\r\n",tildename
,tildedir
);
138 tildename
= savestr(scrbuf
);
140 struct passwd
*pwd
= getpwnam(tildename
);
142 snprintf(scrbuf
, sizeof(scrbuf
), "%s%s",pwd
->pw_dir
,s
);
143 tildedir
= savestr(pwd
->pw_dir
);
144 strcpy(filename
,scrbuf
);
148 #else /* !TILDENAME */
151 fputs("~loginname not implemented.\r\n",stdout
);
155 fputs("~login not impl.\r\n",stdout
);
160 else if (*s
== '$') { /* starts with some env variable? */
167 for (s
++; isalnum((unsigned char)*s
); s
++) *d
++ = *s
;
168 /* skip over token */
173 if (debug
& DEB_FILEXP
)
174 printf("$ %s\r\n",scrbuf
);
176 interp(filename
, (sizeof filename
), scrbuf
);
177 /* this might do some extra '%'s but */
178 /* that is how the Mercedes Benz */
181 if (debug
& DEB_FILEXP
)
182 printf("> %s\r\n",filename
);
188 /* skip interpolations */
191 skipinterp(const char *pattern
, const char *stoppers
)
194 while (*pattern
&& (!stoppers
|| !index(stoppers
,*pattern
))) {
197 printf("skipinterp till %s at %s\r\n",stoppers
?stoppers
:"",pattern
);
199 if (*pattern
== '%' && pattern
[1]) {
200 switch (*++pattern
) {
202 for (pattern
++; *pattern
&& *pattern
!= '}'; pattern
++)
203 if (*pattern
== '\\')
208 pattern
= skipinterp(pattern
+1,"!=");
211 for (pattern
++; *pattern
&& *pattern
!= '?'; pattern
++)
212 if (*pattern
== '\\')
216 pattern
= skipinterp(pattern
+1,":)");
218 pattern
= skipinterp(pattern
+1,")");
224 pattern
= skipinterp(pattern
+1,"`");
230 pattern
= skipinterp(pattern
+1,"\"");
239 if (*pattern
== '^' && pattern
[1])
241 else if (*pattern
== '\\' && pattern
[1])
248 return __UNCONST(pattern
); /* where we left off */
252 static char *mygets(char *str
, size_t n
)
257 if ((ret
= fgets(str
, n
, stdin
)) != NULL
) {
258 last
= strlen(str
) - 1;
260 if (str
[last
] == '\n')
267 /* interpret interpolations */
270 dointerp(char *dest
, size_t destsize
, const char *pattern
, const char *stoppers
)
276 bool lastcomp
= false;
279 while (*pattern
&& (!stoppers
|| !index(stoppers
,*pattern
))) {
282 printf("dointerp till %s at %s\r\n",stoppers
?stoppers
:"",pattern
);
284 if (*pattern
== '%' && pattern
[1]) {
288 switch (*++pattern
) {
296 pattern
= cpytill(scrbuf
,pattern
+1,'}');
297 if ((s
= index(scrbuf
,'-')) != NULL
)
301 s
= getval(scrbuf
,s
);
308 pattern
= dointerp(dest
,destsize
,pattern
+1,"!=");
314 pattern
= cpytill(scrbuf
,pattern
+1,'?');
317 if (*scrbuf
== '^' && scrbuf
[strlen(scrbuf
)-1] == '$') {
318 scrbuf
[strlen(scrbuf
)-1] = '\0';
319 matched
= strEQ(scrbuf
+1,dest
);
322 matched
= instr(dest
,scrbuf
) != NULL
;
323 if (matched
==(rch
== '=')) {
324 pattern
= dointerp(dest
,destsize
,pattern
+1,":)");
326 pattern
= skipinterp(pattern
+1,")");
329 pattern
= skipinterp(pattern
+1,":)");
332 pattern
= dointerp(dest
,destsize
,pattern
,")");
342 pattern
= dointerp(scrbuf
,(sizeof scrbuf
),pattern
+1,"`");
343 pipefp
= popen(scrbuf
,"r");
344 if (pipefp
!= NULL
) {
347 len
= fread(scrbuf
,sizeof(char),(sizeof scrbuf
)-1,
353 printf("\r\nCan't run %s\r\n",scrbuf
);
356 for (s
=scrbuf
; *s
; s
++) {
370 pattern
= dointerp(scrbuf
,(sizeof scrbuf
),pattern
+1,"\"");
371 fputs(scrbuf
,stdout
);
373 mygets(scrbuf
, sizeof(scrbuf
));
389 snprintf(scrbuf
, sizeof(scrbuf
), "%d",getpid());
391 case 'H': /* host name */
394 case 'L': /* login id */
397 case 'N': /* full name */
398 s
= getval("NAME",realname
);
406 case 'X': /* warp library */
412 *dest
++ = *pattern
| metabit
;
420 if (upper
|| lastcomp
) {
424 safecpy(scrbuf
,s
,(sizeof scrbuf
));
427 if (upper
|| !(t
=rindex(s
,'/')))
429 while (*t
&& !isalpha((unsigned char)*t
)) {
431 *t
= toupper((unsigned char)*t
);
434 i
= metabit
; /* maybe get into register */
453 if (*pattern
== '^' && pattern
[1]) {
454 ++pattern
; /* skip uparrow */
455 i
= *pattern
; /* get char into a register */
457 *dest
++ = '\177' | metabit
;
467 *dest
++ = (i
& 037) | metabit
;
470 else if (*pattern
== '\\' && pattern
[1]) {
471 ++pattern
; /* skip backslash */
472 i
= *pattern
; /* get char into a register */
474 /* this used to be a switch but the if may save space */
476 if (i
>= '0' && i
<= '7') {
478 while (i
< 01000 && *pattern
>= '0' && *pattern
<= '7') {
480 i
+= *pattern
++ - '0';
482 *dest
++ = (i
& 0377) | metabit
;
486 *dest
++ = '\b' | metabit
;
488 *dest
++ = '\f' | metabit
;
490 *dest
++ = '\n' | metabit
;
492 *dest
++ = '\r' | metabit
;
494 *dest
++ = '\t' | metabit
;
496 *dest
++ = i
| metabit
;
500 *dest
++ = *pattern
++ | metabit
;
505 return __UNCONST(pattern
); /* where we left off */
509 interp(char *dest
, size_t destsize
, const char *pattern
)
511 (void) dointerp(dest
,destsize
,pattern
,NULL
);
513 if (debug
& DEB_FILEXP
)
518 /* get the person's real name from /etc/passwd */
519 /* (string is overwritten, so it must be copied) */
522 getrealname(uid_t uid
)
527 struct passwd
*pwd
= getpwuid(uid
);
532 while (*s
&& !isalnum(*s
) && *s
!= '&') s
++;
534 if ((c
= index(s
, ',')) != NULL
)
536 if ((c
= index(s
, ';')) != NULL
)
538 s
= cpytill(buf
,s
,'&');
539 if (*s
== '&') { /* whoever thought this one up was */
540 c
= buf
+ strlen(buf
); /* in the middle of the night */
541 strcat(c
,logname
); /* before the morning after */
543 if (islower((unsigned char)*c
))
544 *c
= toupper((unsigned char)*c
); /* gack and double gack */
547 if ((c
= index(s
, '(')) != NULL
)
549 if ((c
= index(s
, '-')) != NULL
)
554 return buf
; /* return something static */
556 if ((tmpfp
=fopen(filexp(FULLNAMEFILE
),"r")) != NULL
) {
557 fgets(buf
,sizeof buf
,tmpfp
);
562 printf("What is your name? ");
563 fgets(buf
,(sizeof buf
),stdin
);
572 if ((tmpfp
= fopen(filexp(FULLNAMEFILE
),"w")) == NULL
)
574 fprintf(tmpfp
, "%s\n", buf
);
579 buf
[strlen(buf
)-1] = '\0';
587 fputs("\r\n% interp buffer overflow!\r\n",stdout
);