]>
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 #define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
24 /* name of this host */
28 static char *tildename
= NULL
;
29 static char *tildedir
= NULL
;
32 static char *getrealname(uid_t
);
34 static char *skipinterp(const char *, const char *);
37 __dead
static void abort_interp(void);
40 intrp_init(char *tcbuf
)
42 /* get environmental stuff */
44 /* get home directory */
46 homedir
= getenv("HOME");
48 homedir
= getenv("LOGDIR");
50 dotdir
= getval("DOTDIR",homedir
);
54 logname
= getenv("USER");
56 logname
= getenv("LOGNAME");
59 logname
= savestr(getlogin());
62 /* get the real name of the person (%N) */
63 /* Must be done after logname is read in because BERKNAMES uses that */
65 strcpy(tcbuf
,getrealname(getuid()));
66 realname
= savestr(tcbuf
);
68 /* name of this host (%H) */
70 gethostname(buf
,sizeof buf
);
71 hostname
= savestr(buf
);
72 if (strchr(hostname
,'.'))
73 hostname
= savestr(hostname
);
77 strcpy(hname
,hostname
);
78 strcat(hname
,MYDOMAIN
);
79 hostname
=savestr(hname
);
81 warplib
= savestr(filexp(WARPLIB
));
83 if (scorespec
) /* that getwd below takes ~1/3 sec. */
84 return; /* and we do not need it for -s */
85 (void) getcwd(tcbuf
, sizeof(tcbuf
));/* find working directory name */
86 origdir
= savestr(tcbuf
); /* and remember it */
89 /* expand filename via %, ~, and $ interpretation */
90 /* returns pointer to static area */
91 /* Note that there is a 1-deep cache of ~name interpretation */
96 static char filename
[CBUFLEN
];
101 if (debug
& DEB_FILEXP
)
102 printf("< %s\r\n",s
);
104 interp(filename
, (sizeof filename
), s
); /* interpret any % escapes */
106 if (debug
& DEB_FILEXP
)
107 printf("%% %s\r\n",filename
);
110 if (*s
== '~') { /* does destination start with ~? */
111 if (!*(++s
) || *s
== '/') {
112 snprintf(scrbuf
, sizeof(scrbuf
), "%s%s",homedir
,s
);
113 /* swap $HOME for it */
115 if (debug
& DEB_FILEXP
)
116 printf("~ %s\r\n",scrbuf
);
118 strcpy(filename
,scrbuf
);
122 for (d
=scrbuf
; isalnum((unsigned char)*s
); s
++,d
++)
125 if (tildedir
&& strEQ(tildename
,scrbuf
)) {
126 strcpy(scrbuf
,tildedir
);
128 strcpy(filename
, scrbuf
);
130 if (debug
& DEB_FILEXP
)
131 printf("r %s %s\r\n",tildename
,tildedir
);
140 tildename
= savestr(scrbuf
);
142 struct passwd
*pwd
= getpwnam(tildename
);
144 snprintf(scrbuf
, sizeof(scrbuf
), "%s%s",pwd
->pw_dir
,s
);
145 tildedir
= savestr(pwd
->pw_dir
);
146 strcpy(filename
,scrbuf
);
150 #else /* !TILDENAME */
153 fputs("~loginname not implemented.\r\n",stdout
);
157 fputs("~login not impl.\r\n",stdout
);
162 else if (*s
== '$') { /* starts with some env variable? */
169 for (s
++; isalnum((unsigned char)*s
); s
++) *d
++ = *s
;
170 /* skip over token */
175 if (debug
& DEB_FILEXP
)
176 printf("$ %s\r\n",scrbuf
);
178 interp(filename
, (sizeof filename
), scrbuf
);
179 /* this might do some extra '%'s but */
180 /* that is how the Mercedes Benz */
183 if (debug
& DEB_FILEXP
)
184 printf("> %s\r\n",filename
);
190 /* skip interpolations */
193 skipinterp(const char *pattern
, const char *stoppers
)
196 while (*pattern
&& (!stoppers
|| !strchr(stoppers
,*pattern
))) {
199 printf("skipinterp till %s at %s\r\n",stoppers
?stoppers
:"",pattern
);
201 if (*pattern
== '%' && pattern
[1]) {
202 switch (*++pattern
) {
204 for (pattern
++; *pattern
&& *pattern
!= '}'; pattern
++)
205 if (*pattern
== '\\')
210 pattern
= skipinterp(pattern
+1,"!=");
213 for (pattern
++; *pattern
&& *pattern
!= '?'; pattern
++)
214 if (*pattern
== '\\')
218 pattern
= skipinterp(pattern
+1,":)");
220 pattern
= skipinterp(pattern
+1,")");
226 pattern
= skipinterp(pattern
+1,"`");
232 pattern
= skipinterp(pattern
+1,"\"");
241 if (*pattern
== '^' && pattern
[1])
243 else if (*pattern
== '\\' && pattern
[1])
250 return __UNCONST(pattern
); /* where we left off */
254 static char *mygets(char *str
, size_t n
)
259 if ((ret
= fgets(str
, n
, stdin
)) != NULL
) {
260 last
= strlen(str
) - 1;
262 if (str
[last
] == '\n')
269 /* interpret interpolations */
272 dointerp(char *dest
, size_t destsize
, const char *pattern
, const char *stoppers
)
278 bool lastcomp
= false;
281 while (*pattern
&& (!stoppers
|| !strchr(stoppers
,*pattern
))) {
284 printf("dointerp till %s at %s\r\n",stoppers
?stoppers
:"",pattern
);
286 if (*pattern
== '%' && pattern
[1]) {
290 switch (*++pattern
) {
298 pattern
= cpytill(scrbuf
,pattern
+1,'}');
299 if ((s
= strchr(scrbuf
,'-')) != NULL
)
303 s
= getval(scrbuf
,s
);
310 pattern
= dointerp(dest
,destsize
,pattern
+1,"!=");
316 pattern
= cpytill(scrbuf
,pattern
+1,'?');
319 if (*scrbuf
== '^' && scrbuf
[strlen(scrbuf
)-1] == '$') {
320 scrbuf
[strlen(scrbuf
)-1] = '\0';
321 matched
= strEQ(scrbuf
+1,dest
);
324 matched
= instr(dest
,scrbuf
) != NULL
;
325 if (matched
==(rch
== '=')) {
326 pattern
= dointerp(dest
,destsize
,pattern
+1,":)");
328 pattern
= skipinterp(pattern
+1,")");
331 pattern
= skipinterp(pattern
+1,":)");
334 pattern
= dointerp(dest
,destsize
,pattern
,")");
344 pattern
= dointerp(scrbuf
,(sizeof scrbuf
),pattern
+1,"`");
345 pipefp
= popen(scrbuf
,"r");
346 if (pipefp
!= NULL
) {
349 len
= fread(scrbuf
,sizeof(char),(sizeof scrbuf
)-1,
355 printf("\r\nCan't run %s\r\n",scrbuf
);
358 for (s
=scrbuf
; *s
; s
++) {
372 pattern
= dointerp(scrbuf
,(sizeof scrbuf
),pattern
+1,"\"");
373 fputs(scrbuf
,stdout
);
375 mygets(scrbuf
, sizeof(scrbuf
));
391 snprintf(scrbuf
, sizeof(scrbuf
), "%d",getpid());
393 case 'H': /* host name */
396 case 'L': /* login id */
399 case 'N': /* full name */
400 s
= getval("NAME",realname
);
408 case 'X': /* warp library */
414 *dest
++ = *pattern
| metabit
;
422 if (upper
|| lastcomp
) {
426 safecpy(scrbuf
,s
,(sizeof scrbuf
));
429 if (upper
|| !(t
=strrchr(s
,'/')))
431 while (*t
&& !isalpha((unsigned char)*t
)) {
433 *t
= toupper((unsigned char)*t
);
436 i
= metabit
; /* maybe get into register */
455 if (*pattern
== '^' && pattern
[1]) {
456 ++pattern
; /* skip uparrow */
457 i
= *pattern
; /* get char into a register */
459 *dest
++ = '\177' | metabit
;
469 *dest
++ = (i
& 037) | metabit
;
472 else if (*pattern
== '\\' && pattern
[1]) {
473 ++pattern
; /* skip backslash */
474 i
= *pattern
; /* get char into a register */
476 /* this used to be a switch but the if may save space */
478 if (i
>= '0' && i
<= '7') {
480 while (i
< 01000 && *pattern
>= '0' && *pattern
<= '7') {
482 i
+= *pattern
++ - '0';
484 *dest
++ = (i
& 0377) | metabit
;
488 *dest
++ = '\b' | metabit
;
490 *dest
++ = '\f' | metabit
;
492 *dest
++ = '\n' | metabit
;
494 *dest
++ = '\r' | metabit
;
496 *dest
++ = '\t' | metabit
;
498 *dest
++ = i
| metabit
;
502 *dest
++ = *pattern
++ | metabit
;
507 return __UNCONST(pattern
); /* where we left off */
511 interp(char *dest
, size_t destsize
, const char *pattern
)
513 (void) dointerp(dest
,destsize
,pattern
,NULL
);
515 if (debug
& DEB_FILEXP
)
520 /* get the person's real name from /etc/passwd */
521 /* (string is overwritten, so it must be copied) */
524 getrealname(uid_t uid
)
529 struct passwd
*pwd
= getpwuid(uid
);
534 while (*s
&& !isalnum(*s
) && *s
!= '&') s
++;
536 if ((c
= strchr(s
, ',')) != NULL
)
538 if ((c
= strchr(s
, ';')) != NULL
)
540 s
= cpytill(buf
,s
,'&');
541 if (*s
== '&') { /* whoever thought this one up was */
542 c
= buf
+ strlen(buf
); /* in the middle of the night */
543 strcat(c
,logname
); /* before the morning after */
545 if (islower((unsigned char)*c
))
546 *c
= toupper((unsigned char)*c
); /* gack and double gack */
549 if ((c
= strchr(s
, '(')) != NULL
)
551 if ((c
= strchr(s
, '-')) != NULL
)
556 return buf
; /* return something static */
558 if ((tmpfp
=fopen(filexp(FULLNAMEFILE
),"r")) != NULL
) {
559 fgets(buf
,sizeof buf
,tmpfp
);
564 printf("What is your name? ");
565 fgets(buf
,(sizeof buf
),stdin
);
574 if ((tmpfp
= fopen(filexp(FULLNAMEFILE
),"w")) == NULL
)
576 fprintf(tmpfp
, "%s\n", buf
);
581 buf
[strlen(buf
)-1] = '\0';
589 fputs("\r\n% interp buffer overflow!\r\n",stdout
);