⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 intrp.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: intrp.c,v 3.0 1992/02/01 03:09:32 davison Trn $ *//* This software is Copyright 1991 by Stan Barber.  * * Permission is hereby granted to copy, reproduce, redistribute or otherwise * use this software as long as: there is no monetary profit gained * specifically from the use or reproduction of this software, it is not * sold, rented, traded or otherwise marketed, and this copyright notice is * included prominently in any copy made.  * * The author make no claims as to the fitness or correctness of this software * for any use whatsoever, and it is provided as is. Any use of this software * is at the user's own risk.  */#include "EXTERN.h"#include "common.h"#include "util.h"#include "search.h"#include "cache.h"#include "bits.h"#include "head.h"#include "trn.h"#include "artsrch.h"#include "ng.h"#include "ngdata.h"#include "respond.h"#include "rcstuff.h"#include "artio.h"#include "init.h"#include "term.h"#include "final.h"#include "rthread.h"#include "rt-select.h"#include "nntp.h"#include "INTERN.h"#include "intrp.h"static char * regexp_specials = "^$.*[\\/?%";char orgname[] = ORGNAME;#ifdef HAS_UNAME#include <sys/utsname.h>struct utsname utsn;#endif#ifdef TILDENAMEstatic char *tildename = Nullch;static char *tildedir = Nullch;#endif#ifdef CONDSUBchar *skipinterp _((char *,char *));#endifstatic void abort_interp _((void));voidintrp_init(tcbuf)char *tcbuf;{    char *getlogin();        /* get environmental stuff */#ifdef NEWS_ADMIN    {#ifdef HAS_GETPWENT	struct passwd *getpwnam();	struct passwd *pwd = getpwnam(NEWS_ADMIN);	if (pwd != NULL)	    newsuid = pwd->pw_uid;#else#ifdef TILDENAME	char tildenews[2+sizeof NEWS_ADMIN];	strcpy(tildenews, "~");	strcat(tildenews, NEWS_ADMIN);	(void) filexp(tildenews);#else	??? "Define either HAS_GETPWENT or TILDENAME to get NEWS_ADMIN"#endif  /* TILDENAME */#endif	/* HAS_GETPWENT */    }#endif	/* NEWS_ADMIN */    /* get home directory */    homedir = getenv("HOME");    if (homedir == Nullch)	homedir = getenv("LOGDIR");    dotdir = getval("DOTDIR",homedir);    /* get login name */    logname = getenv("USER");    if (logname == Nullch)	logname = getenv("LOGNAME");#ifdef GETLOGIN    if (logname == Nullch)	logname = savestr(getlogin());#endif    spool = savestr(filexp(NEWSSPOOL));	/* usually /usr/spool/news */    threaddir = filexp(THREAD_DIR);    if (strEQ(threaddir,spool))	threaddir = spool;    else	threaddir = savestr(threaddir);    overviewdir = filexp(OVERVIEW_DIR);    if (strEQ(overviewdir,spool))	overviewdir = spool;    else	overviewdir = savestr(overviewdir);#ifdef NEWS_ADMIN    /* if this is the news admin than load his UID into newsuid */    if ( strEQ(logname,NEWS_ADMIN) )	newsuid = getuid();#endif    if (checkflag)			/* that getwd below takes ~1/3 sec. */	return;				/* and we do not need it for -c */    getwd(tcbuf);			/* find working directory name */    origdir = savestr(tcbuf);		/* and remember it */    /* get the real name of the person (%N) */    /* Must be done after logname is read in because BERKNAMES uses that */    strcpy(tcbuf,getrealname((long)getuid()));    realname = savestr(tcbuf);    /* name of header file (%h) */    headname = savestr(filexp(HEADNAME));    /* host name that goes in postings (%H) */    phostname = PHOSTNAME;    if (*phostname == '/') {	if ((tmpfp = fopen(phostname,"r")) == NULL) {	    printf("Warning: Couldn't open %s to determine hostname!\n",		   phostname); 	    sig_catcher(0);	}	fgets(buf, sizeof(buf), tmpfp);	if (buf[strlen(buf)-1] == '\n')	    buf[strlen(buf)-1] = 0;	fclose(tmpfp);    }    else {#ifdef HAS_GETHOSTNAME	gethostname(buf,sizeof buf);#else# ifdef HAS_UNAME	/* get sysname */	uname(&utsn);	strcpy(buf,utsn.nodename);# else#  ifdef PHOSTCMD       {	FILE *popen();	FILE *pipefp = popen(PHOSTCMD,"r");		if (pipefp == Nullfp) {	    printf("Can't find hostname\n");	    sig_catcher(0);	}	fgets(buf,sizeof buf,pipefp);	buf[strlen(buf)-1] = '\0';	/* wipe out newline */	pclose(pipefp);       }#  else	*buf = '\0';#  endif /* PHOSTCMD */# endif /* HAS_UNAME */#endif /* HAS_GETHOSTNAME */	if (*buf) {	    char *cp = index(buf,'.');	    if (cp)		*cp = '\0';	    cp = index(phostname,'.');	    if (cp)		strcat(buf,cp);	    phostname = savestr(buf);	}    }}/* expand filename via %, ~, and $ interpretation *//* returns pointer to static area *//* Note that there is a 1-deep cache of ~name interpretation */char *filexp(s)register char *s;{    static char filename[CBUFLEN];    char scrbuf[CBUFLEN];    register char *d;#ifdef DEBUG    if (debug & DEB_FILEXP)	printf("< %s\n",s) FLUSH;#endif    interp(filename, (sizeof filename), s);						/* interpret any % escapes */#ifdef DEBUG    if (debug & DEB_FILEXP)	printf("%% %s\n",filename) FLUSH;#endif    s = filename;    if (*s == '~') {	/* does destination start with ~? */	if (!*(++s) || *s == '/') {	    sprintf(scrbuf,"%s%s",homedir,s);				/* swap $HOME for it */#ifdef DEBUG    if (debug & DEB_FILEXP)	printf("~ %s\n",scrbuf) FLUSH;#endif	    strcpy(filename,scrbuf);	}	else {#ifdef TILDENAME	    for (d=scrbuf; isalnum(*s); s++,d++)		*d = *s;	    *d = '\0';	    if (tildedir && strEQ(tildename,scrbuf)) {		strcpy(scrbuf,tildedir);		strcat(scrbuf, s);		strcpy(filename, scrbuf);#ifdef DEBUG		if (debug & DEB_FILEXP)		    printf("r %s %s\n",tildename,tildedir) FLUSH;#endif	    }	    else {		if (tildename) {		    free(tildename);		    free(tildedir);		}		tildedir = Nullch;		tildename = savestr(scrbuf);#ifdef HAS_GETPWENT	/* getpwnam() is not the paragon of efficiency */		{#ifdef notdef		    struct passwd *getpwnam _((char*));#endif		    struct passwd *pwd = getpwnam(tildename);		    if ( pwd == NULL){			printf("%s is an unknown user. Using default.\n",tildename) FLUSH;			return(Nullch);		    }		    sprintf(scrbuf,"%s%s",pwd->pw_dir,s);		    tildedir = savestr(pwd->pw_dir);		    strcpy(filename,scrbuf);		    endpwent();		}#else			/* this will run faster, and is less D space */		{	/* just be sure LOGDIRFIELD is correct */		    FILE *pfp = fopen("/etc/passwd","r");		    char tmpbuf[512];		    int i;		    		    if (pfp == Nullfp) {			printf(cantopen,"passwd") FLUSH;			sig_catcher(0);		    }		    while (fgets(tmpbuf,512,pfp) != Nullch) {			d = cpytill(scrbuf,tmpbuf,':');#ifdef DEBUG			if (debug & DEB_FILEXP)			    printf("p %s\n",tmpbuf) FLUSH;#endif			if (strEQ(scrbuf,tildename)) {			    for (i=LOGDIRFIELD-2; i; i--) {				if (d)				    d = index(d+1,':');			    }			    if (d) {				cpytill(scrbuf,d+1,':');				tildedir = savestr(scrbuf);				strcat(scrbuf,s);				strcpy(filename,scrbuf);			    }			    break;			}		    }		    fclose(pfp);		}#endif	    }#else /* !TILDENAME */#ifdef VERBOSE	    IF(verbose)		fputs("~loginname not implemented.\n",stdout) FLUSH;	    ELSE#endif#ifdef TERSE		fputs("~login not impl.\n",stdout) FLUSH;#endif#endif	}    }    else if (*s == '$') {	/* starts with some env variable? */	d = scrbuf;	*d++ = '%';	if (s[1] == '{')	    strcpy(d,s+2);	else {	    *d++ = '{';	    for (s++; isalnum(*s); s++) *d++ = *s;				/* skip over token */	    *d++ = '}';	    strcpy(d,s);	}#ifdef DEBUG	if (debug & DEB_FILEXP)	    printf("$ %s\n",scrbuf) FLUSH;#endif	interp(filename, (sizeof filename), scrbuf);					/* this might do some extra '%'s but */					/* that is how the Mercedes Benz */    }#ifdef DEBUG    if (debug & DEB_FILEXP)	printf("> %s\n",filename) FLUSH;#endif    return filename;}#ifdef CONDSUB/* skip interpolations */char *skipinterp(pattern,stoppers)register char *pattern;char *stoppers;{    while (*pattern && (!stoppers || !index(stoppers,*pattern))) {#ifdef DEBUG	if (debug & DEB_INTRP)	    printf("skipinterp till %s at %s\n",stoppers?stoppers:"",pattern);#endif	if (*pattern == '%' && pattern[1]) {	    switch (*++pattern) {	    case '{':		for (pattern++; *pattern && *pattern != '}'; pattern++)		    if (*pattern == '\\')			pattern++;		break;	    case '[':		for (pattern++; *pattern && *pattern != ']'; pattern++)		    if (*pattern == '\\')			pattern++;		break;#ifdef CONDSUB	    case '(': {		pattern = skipinterp(pattern+1,"!=");		if (!*pattern)		    goto getout;		for (pattern++; *pattern && *pattern != '?'; pattern++)		    if (*pattern == '\\')			pattern++;		if (!*pattern)		    goto getout;		pattern = skipinterp(pattern+1,":)");		if (*pattern == ':')		    pattern = skipinterp(pattern+1,")");		break;	    }#endif#ifdef BACKTICK	    case '`': {		pattern = skipinterp(pattern+1,"`");		break;	    }#endif#ifdef PROMPTTTY	    case '"':		pattern = skipinterp(pattern+1,"\"");		break;#endif	    default:		break;	    }	    pattern++;	}	else {	    if (*pattern == '^' && pattern[1])		pattern += 2;	    else if (*pattern == '\\' && pattern[1])		pattern += 2;	    else		pattern++;	}    }getout:    return pattern;			/* where we left off */}#endif/* interpret interpolations */char *dointerp(dest,destsize,pattern,stoppers)register char *dest;register int destsize;register char *pattern;char *stoppers;{    char *subj_buf = Nullch;    char *ngs_buf = Nullch;    char *refs_buf = Nullch;    char *artid_buf = Nullch;    char *reply_buf = Nullch;    char *from_buf = Nullch;    char *path_buf = Nullch;    char *follow_buf = Nullch;    char *dist_buf = Nullch;    char *line_buf = Nullch;    register char *s, *h;    register int i;    char scrbuf[512];    char spfbuf[512];    bool upper = FALSE;    bool lastcomp = FALSE;    bool re_quote = FALSE;    bool proc_sprintf = FALSE;    int metabit = 0;    while (*pattern && (!stoppers || !index(stoppers,*pattern))) {#ifdef DEBUG	if (debug & DEB_INTRP)	    printf("dointerp till %s at %s\n",stoppers?stoppers:"",pattern);#endif	if (*pattern == '%' && pattern[1]) {	    upper = FALSE;	    lastcomp = FALSE;	    re_quote = FALSE;	    proc_sprintf = FALSE;	    for (s=Nullch; !s; ) {		switch (*++pattern) {		case '^':		    upper = TRUE;		    break;		case '_':		    lastcomp = TRUE;		    break;		case '\\':		    re_quote = TRUE;		    break;		case ':':		    proc_sprintf = TRUE;		    h = spfbuf;		    *h++ = '%';		    pattern++;	/* Skip over ':' */		    while (*pattern		     && (*pattern=='.' || *pattern=='-' || isdigit(*pattern))) {			*h++ = *pattern++;		    }		    *h++ = 's';		    *h++ = '\0';		    pattern--;		    break;		case '/':#ifdef ARTSRCH		    s = scrbuf;		    if (!index("/?g",pattern[-2]))			*s++ = '/';		    strcpy(s,lastpat);		    s += strlen(s);		    if (pattern[-2] != 'g') {			if (index("/?",pattern[-2]))			    *s++ = pattern[-2];			else			    *s++ = '/';			if (art_howmuch == 1)			    *s++ = 'h';			else if (art_howmuch == 2)			    *s++ = 'a';			if (art_doread)			    *s++ = 'r';		    }		    *s = '\0';		    s = scrbuf;#else		    s = nullstr;#endif		    break;		case '{':		    pattern = cpytill(scrbuf,pattern+1,'}');		    if (s = index(scrbuf,'-'))			*s++ = '\0';		    else			s = nullstr;		    s = getval(scrbuf,s);		    break;		case '[':		    pattern = cpytill(scrbuf,pattern+1,']');		    i = set_line_type(scrbuf,scrbuf+strlen(scrbuf));		    if (line_buf)			free(line_buf);		    s = line_buf = fetchlines(art,i);		    break;#ifdef CONDSUB		case '(': {		    COMPEX *oldbra_compex = bra_compex;		    COMPEX cond_compex;		    char rch;		    bool matched;		    		    init_compex(&cond_compex);		    pattern = dointerp(dest,destsize,pattern+1,"!=");		    rch = *pattern;		    if (rch == '!')			pattern++;		    if (*pattern != '=')			goto getout;		    pattern = cpytill(scrbuf,pattern+1,'?');		    if (!*pattern)			goto getout;		    if (s = compile(&cond_compex,scrbuf,TRUE,TRUE)) {			printf("%s: %s\n",scrbuf,s) FLUSH;			pattern += strlen(pattern);			goto getout;		    }		    matched = (execute(&cond_compex,dest) != Nullch);		    if (cond_compex.nbra)	/* were there brackets? */			bra_compex = &cond_compex;		    if (matched==(rch == '=')) {			pattern = dointerp(dest,destsize,pattern+1,":)");			if (*pattern == ':')			    pattern = skipinterp(pattern+1,")");		    }		    else {			pattern = skipinterp(pattern+1,":)");			if (*pattern == ':')			    pattern++;			pattern = dointerp(dest,destsize,pattern,")");		    }		    s = dest;		    bra_compex = oldbra_compex;		    free_compex(&cond_compex);		    break;		}#endif#ifdef BACKTICK		case '`': {		    FILE *pipefp, *popen();		    pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"`");		    pipefp = popen(scrbuf,"r");		    if (pipefp != Nullfp) {			int len;			len = fread(scrbuf,sizeof(char),(sizeof scrbuf)-1,			    pipefp);			scrbuf[len] = '\0';			pclose(pipefp);		    }		    else {			printf("\nCan't run %s\n",scrbuf);			*scrbuf = '\0';		    }		    for (s=scrbuf; *s; s++) {			if (*s == '\n') {			    if (s[1])				*s = ' ';			    else				*s = '\0';			}		    }		    s = scrbuf;		    break;		}#endif#ifdef PROMPTTTY		case '"':		    pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"\"");		    fputs(scrbuf,stdout) FLUSH;		    resetty();		    gets(scrbuf);		    noecho();		    crmode();		    s = scrbuf;		    break;#endif		case '~':		    s = homedir;		    break;		case '.':		    s = dotdir;		    break;		case '$':		    s = scrbuf;		    sprintf(s,"%ld",our_pid);		    break;		case '#':

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -