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