Home | History | Annotate | Line # | Download | only in warp
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