home *** CD-ROM | disk | FTP | other *** search
- From: sob@lib.tmc.edu (Stan Barber)
- Newsgroups: alt.sources
- Subject: rrn/rn combo kite part 4 of 9
- Message-ID: <430@lib.tmc.edu>
- Date: 14 Jun 90 03:27:35 GMT
-
- #! /bin/sh
-
- # Make a new directory for the rn sources, cd to it, and run kits 1 thru 9
- # through sh. When all 9 kits have been run, read README.
-
- echo "This is rn kit 4 (of 9). If kit 4 is complete, the line"
- echo '"'"End of kit 4 (of 9)"'" will echo at the end.'
- echo ""
- export PATH || (echo "You didn't use sh, you clunch." ; kill $$)
- echo Extracting intrp.c
- cat >intrp.c <<'!STUFFY!FUNK!'
- /* $Header: intrp.c,v 4.3.2.4 90/04/23 00:31:20 sob Exp $
- *
- * $Log: intrp.c,v $
- * Revision 4.3.2.4 90/04/23 00:31:20 sob
- * Removed unneeded atoi call.
- *
- * Revision 4.3.2.3 90/03/22 23:04:35 sob
- * Fixes provided by Wayne Davison <drivax!davison>
- *
- * Revision 4.3.2.2 90/03/17 17:03:12 sob
- * Fixed determination of the news superuser's id. Fix provided by Chip
- * Rosenthal <chip@chinacat.lonestar.org>.
- *
- * Revision 4.3.2.1 89/12/17 02:54:55 sob
- * Removed redundant include directive.
- *
- * Revision 4.3.1.5 85/05/23 17:21:24 lwall
- * Now allows 'r' and 'f' on null articles.
- *
- * Revision 4.3.1.4 85/05/21 13:35:21 lwall
- * Sped up "rn -c" by not doing unnecessary initialization.
- *
- * Revision 4.3.1.3 85/05/17 10:37:11 lwall
- * Fixed & substitution to capitalize last name too.
- *
- * Revision 4.3.1.2 85/05/15 14:39:45 lwall
- * Spelled gecos right.
- *
- * Revision 4.3.1.1 85/05/10 11:33:51 lwall
- * Branch for patches.
- *
- * Revision 4.3 85/05/01 11:40:54 lwall
- * Baseline for release with 4.3bsd.
- *
- */
-
- #include "EXTERN.h"
- #include "common.h"
- #include "util.h"
- #include "search.h"
- #include "head.h"
- #include "rn.h"
- #include "artsrch.h"
- #include "ng.h"
- #include "respond.h"
- #include "rcstuff.h"
- #include "bits.h"
- #include "artio.h"
- #include "term.h"
- #include "final.h"
- #include "INTERN.h"
- #include "intrp.h"
-
- char orgname[] = ORGNAME;
-
- /* name of this site */
- #ifdef GETHOSTNAME
- char *hostname;
- # undef SITENAME
- # define SITENAME hostname
- #else !GETHOSTNAME
- # ifdef DOUNAME
- # include <sys/utsname.h>
- struct utsname uts;
- # undef SITENAME
- # define SITENAME uts.nodename
- # else !DOUNAME
- # ifdef PHOSTNAME
- char *hostname;
- # undef SITENAME
- # define SITENAME hostname
- # else !PHOSTNAME
- # ifdef WHOAMI
- # undef SITENAME
- # define SITENAME sysname
- # endif WHOAMI
- # endif PHOSTNAME
- # endif DOUNAME
- #endif GETHOSTNAME
-
- #ifdef TILDENAME
- static char *tildename = Nullch;
- static char *tildedir = Nullch;
- #endif
-
- char *realname INIT(Nullch); /* real name of sender from /etc/passwd */
-
- char *dointerp();
- char *getrealname();
- #ifdef CONDSUB
- char *skipinterp();
- #endif
-
- static void abort_interp();
-
- void
- intrp_init(tcbuf)
- char *tcbuf;
- {
- char *getlogin();
-
- spool = savestr(filexp(SPOOL)); /* usually /usr/spool/news */
-
- /* get environmental stuff */
-
- /* 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
-
- 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(getuid()));
- realname = savestr(tcbuf);
-
- /* name of header file (%h) */
-
- headname = savestr(filexp(HEADNAME));
-
- /* name of this site (%H) */
-
- #ifdef GETHOSTNAME
- gethostname(buf,sizeof buf);
- hostname = savestr(buf);
- #else
- #ifdef DOUNAME
- /* get sysname */
- uname(&uts);
- #else
- #ifdef PHOSTNAME
- {
- FILE *popen();
- FILE *pipefp = popen(PHOSTNAME,"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 */
- hostname = savestr(buf);
- pclose(pipefp);
- }
- #endif
- #endif
- #endif
- sitename = savestr(SITENAME);
- }
-
- /* 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 DEBUGGING
- if (debug & DEB_FILEXP)
- printf("< %s\n",s) FLUSH;
- #endif
- interp(filename, (sizeof filename), s); /* interpret any % escapes */
- #ifdef DEBUGGING
- 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 DEBUGGING
- 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 DEBUGGING
- 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 GETPWENT /* getpwnam() is not the paragon of efficiency */
- {
- struct passwd *getpwnam();
- struct passwd *pwd = getpwnam(tildename);
-
- sprintf(scrbuf,"%s%s",pwd->pw_dir,s);
- tildedir = savestr(pwd->pw_dir);
- #ifdef NEWSADMIN
- if ((pwd != NULL) && strEQ(newsadmin,tildename))
- newsuid = pwd->pw_uid;
- #endif
- strcpy(filename,scrbuf);
- #ifdef GETPWENT
- endpwent();
- #endif
- }
- #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 DEBUGGING
- if (debug & DEB_FILEXP)
- printf("p %s\n",tmpbuf) FLUSH;
- #endif
- if (strEQ(scrbuf,tildename)) {
- #ifdef NEWSADMIN
- if (strEQ(newsadmin,tildename))
- newsuid = atoi(index(d+1,':')+1);
- #endif
- 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 DEBUGGING
- 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 DEBUGGING
- 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 DEBUGGING
- if (debug & 8)
- 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];
- bool upper = FALSE;
- bool lastcomp = FALSE;
- int metabit = 0;
-
- while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
- #ifdef DEBUGGING
- if (debug & 8)
- printf("dointerp till %s at %s\n",stoppers?stoppers:"",pattern);
- #endif
- if (*pattern == '%' && pattern[1]) {
- upper = FALSE;
- lastcomp = FALSE;
- for (s=Nullch; !s; ) {
- switch (*++pattern) {
- case '^':
- upper = TRUE;
- break;
- case '_':
- lastcomp = TRUE;
- 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,"%d",getpid());
- break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- #ifdef CONDSUB
- s = getbracket(bra_compex,*pattern - '0');
- #else
- s = nullstr;
- #endif
- break;
- case 'a':
- s = scrbuf;
- sprintf(s,"%ld",(long)art);
- break;
- case 'A':
- #ifdef LINKART
- s = linkartname; /* so Eunice people get right file */
- #else
- s = scrbuf;
- sprintf(s,"%s/%s/%ld",spool,ngdir,(long)art);
- #endif
- break;
- case 'b':
- s = savedest;
- break;
- case 'B':
- s = scrbuf;
- sprintf(s,"%ld",(long)savefrom);
- break;
- case 'c':
- s = ngdir;
- break;
- case 'C':
- s = ngname;
- break;
- case 'd':
- s = scrbuf;
- sprintf(s,"%s/%s",spool,ngdir);
- break;
- case 'D':
- s = dist_buf = fetchlines(art,DIST_LINE);
- break;
- case 'f': /* from line */
- #ifdef ASYNC_PARSE
- parse_maybe(art);
- #endif
- if (htype[REPLY_LINE].ht_minpos >= 0) {
- /* was there a reply line? */
- if (!(s=reply_buf))
- s = reply_buf = fetchlines(art,REPLY_LINE);
- }
- else if (!(s = from_buf))
- s = from_buf = fetchlines(art,FROM_LINE);
- break;
- case 'F':
- #ifdef ASYNC_PARSE
- parse_maybe(art);
- #endif
- if (htype[FOLLOW_LINE].ht_minpos >= 0)
- /* is there a Followup-To line? */
- s = follow_buf = fetchlines(art,FOLLOW_LINE);
- else {
- int off;
-
- s = ngs_buf = fetchlines(art,NGS_LINE);
- if (h = instr(s,"net.general")) {
- off = h-s;
- strncpy(scrbuf,s,off+4);
- strcpy(scrbuf+off+4,"followup");
- safecpy(scrbuf+off+12,h+11,sizeof(scrbuf));
- s = scrbuf;
- }
- }
- break;
- case 'h': /* header file name */
- s = headname;
- break;
- case 'H': /* host name */
- s = sitename;
- break;
- case 'i':
- if (!(s=artid_buf))
- s = artid_buf = fetchlines(art,MESSID_LINE);
- if (*s && *s != '<') {
- sprintf(scrbuf,"<%s>",artid_buf);
- s = scrbuf;
- }
- break;
- case 'I': /* ref article indicator */
- s = scrbuf;
- sprintf(scrbuf,"'%s'",indstr);
- break;
- case 'l': /* rn library */
- #ifdef NEWSADMIN
- s = newsadmin;
- #else
- s = "???";
- #endif
- break;
- case 'L': /* login id */
- s = logname;
- break;
- case 'm': /* current mode */
- s = scrbuf;
- *s = mode;
- s[1] = '\0';
- break;
- case 'M':
- #ifdef DELAYMARK
- sprintf(scrbuf,"%ld",(long)dmcount);
- s = scrbuf;
- #else
- s = nullstr;
- #endif
- break;
- case 'n': /* newsgroups */
- s = ngs_buf = fetchlines(art,NGS_LINE);
- break;
- case 'N': /* full name */
- s = getval("NAME",realname);
- break;
- case 'o': /* organization */
- s = getval("ORGANIZATION",orgname);
- #ifdef ORGFILE
- if (*s == '/') {
- FILE *ofp = fopen(s,"r");
-
- if (ofp) {
- fgets(scrbuf,sizeof scrbuf,ofp);
- fclose(ofp);
- s = scrbuf;
- s[strlen(s)-1] = '\0';
- }
- }
- #endif
- break;
- case 'O':
- s = origdir;
- break;
- case 'p':
- s = cwd;
- break;
- case 'P':
- s = spool;
- break;
- case 'r':
- #ifdef ASYNC_PARSE
- parse_maybe(art);
- #endif
- if (htype[REFS_LINE].ht_minpos >= 0) {
- refs_buf = fetchlines(art,REFS_LINE);
- refscpy(scrbuf,(sizeof scrbuf),refs_buf);
- }
- else
- *scrbuf = '\0';
- s = rindex(scrbuf,'<');
- break;
- case 'R':
- #ifdef ASYNC_PARSE
- parse_maybe(art);
- #endif
- if (htype[REFS_LINE].ht_minpos >= 0) {
- refs_buf = fetchlines(art,REFS_LINE);
- refscpy(scrbuf,(sizeof scrbuf),refs_buf);
- /* no more than 3 prior references allowed,
- ** including the one concatenated below */
- if ((s = rindex(scrbuf,'<')) > scrbuf) {
- *s = '\0';
- h = rindex(scrbuf,'<');
- *s = '<';
- if (h > scrbuf)
- strcpy(scrbuf,h);
- }
- }
- else
- *scrbuf = '\0';
- if (!artid_buf)
- artid_buf = fetchlines(art,MESSID_LINE);
- if (artid_buf[0] == '<')
- safecat(scrbuf,artid_buf,sizeof(scrbuf));
- else if (artid_buf[0]) {
- char tmpbuf[64];
-
- sprintf(tmpbuf,"<%s>",artid_buf);
- safecat(scrbuf,tmpbuf,sizeof(scrbuf));
- }
- s = scrbuf;
- break;
- case 's':
- if (!(s=subj_buf))
- s = subj_buf = fetchsubj(art,TRUE,TRUE);
- /* get subject handy */
- while ((*s=='R'||*s=='r')&&(s[1]=='E'||s[1]=='e')&&s[2]==':') {
- /* skip extra Re: */
- s += 3;
- if (*s == ' ')
- s++;
- }
- if (h = instr(s,"- (nf"))
- *h = '\0';
- break;
- case 'S':
- if (!(s=subj_buf))
- s = subj_buf = fetchsubj(art,TRUE,TRUE);
- /* get subject handy */
- if ((*s=='R'||*s=='r')&&(s[1]=='E'||s[1]=='e')&&s[2]==':') {
- /* skip extra Re: */
- s += 3;
- if (*s == ' ')
- s++;
- }
- break;
- case 't':
- case 'T':
- #ifdef ASYNC_PARSE
- parse_maybe(art);
- #endif
- if (htype[REPLY_LINE].ht_minpos >= 0) {
- /* was there a reply line? */
- if (!(s=reply_buf))
- s = reply_buf = fetchlines(art,REPLY_LINE);
- }
- else if (!(s = from_buf))
- s = from_buf = fetchlines(art,FROM_LINE);
- if (*pattern == 'T') {
- if (htype[PATH_LINE].ht_minpos >= 0) {
- /* should we substitute path? */
- s = path_buf = fetchlines(art,PATH_LINE);
- }
- i = strlen(sitename);
- if (strnEQ(sitename,s,i) && s[i] == '!')
- s += i + 1;
- }
- if ((h=index(s,'(')) != Nullch)
- /* strip garbage from end */
- *(h-1) = '\0';
- else if ((h=index(s,'<')) != Nullch) {
- /* or perhaps from beginning */
- s = h+1;
- if ((h=index(s,'>')) != Nullch)
- *h = '\0';
- }
- break;
- case 'u':
- sprintf(scrbuf,"%ld",(long)toread[ng]);
- s = scrbuf;
- break;
- case 'U':
- sprintf(scrbuf,"%ld",
- (long)(((ART_NUM)toread[ng]) - 1 + was_read(art)));
- s = scrbuf;
- break;
- case 'x': /* news library */
- s = lib;
- break;
- case 'X': /* rn library */
- s = rnlib;
- break;
- case 'z':
- #ifdef LINKART
- s = linkartname; /* so Eunice people get right file */
- #else
- s = scrbuf;
- sprintf(s,"%ld",(long)art);
- #endif
- if (stat(s,&filestat) < 0)
- filestat.st_size = 0L;
- sprintf(scrbuf,"%5ld",(long)filestat.st_size);
- s = scrbuf;
- break;
- default:
- if (--destsize <= 0)
- abort_interp();
- *dest++ = *pattern | metabit;
- s = nullstr;
- break;
- }
- }
- if (!s)
- s = nullstr;
- pattern++;
- if (upper || lastcomp) {
- char *t;
-
- if (s != scrbuf) {
- safecpy(scrbuf,s,(sizeof scrbuf));
- s = scrbuf;
- }
- if (upper || !(t=rindex(s,'/')))
- t = s;
- while (*t && !isalpha(*t))
- t++;
- if (islower(*t))
- *t = toupper(*t);
- }
- i = metabit; /* maybe get into register */
- if (s == dest) {
- while (*dest) {
- if (--destsize <= 0)
- abort_interp();
- *dest++ |= i;
- }
- }
- else {
- while (*s) {
- if (--destsize <= 0)
- abort_interp();
- *dest++ = *s++ | i;
- }
- }
- }
- else {
- if (--destsize <= 0)
- abort_interp();
- if (*pattern == '^' && pattern[1]) {
- ++pattern; /* skip uparrow */
- i = *pattern; /* get char into a register */
- if (i == '?')
- *dest++ = '\177' | metabit;
- else if (i == '(') {
- metabit = 0200;
- destsize++;
- }
- else if (i == ')') {
- metabit = 0;
- destsize++;
- }
- else
- *dest++ = i & 037 | metabit;
- pattern++;
- }
- else if (*pattern == '\\' && pattern[1]) {
- ++pattern; /* skip backslash */
- i = *pattern; /* get char into a register */
-
- /* this used to be a switch but the if may save space */
-
- if (i >= '0' && i <= '7') {
- i = 1;
- while (i < 01000 && *pattern >= '0' && *pattern <= '7') {
- i <<= 3;
- i += *pattern++ - '0';
- }
- *dest++ = i & 0377 | metabit;
- --pattern;
- }
- else if (i == 'b')
- *dest++ = '\b' | metabit;
- else if (i == 'f')
- *dest++ = '\f' | metabit;
- else if (i == 'n')
- *dest++ = '\n' | metabit;
- else if (i == 'r')
- *dest++ = '\r' | metabit;
- else if (i == 't')
- *dest++ = '\t' | metabit;
- else
- *dest++ = i | metabit;
- pattern++;
- }
- else
- *dest++ = *pattern++ | metabit;
- }
- }
- *dest = '\0';
- getout:
- if (subj_buf != Nullch) /* return any checked out storage */
- free(subj_buf);
- if (ngs_buf != Nullch)
- free(ngs_buf);
- if (refs_buf != Nullch)
- free(refs_buf);
- if (artid_buf != Nullch)
- free(artid_buf);
- if (reply_buf != Nullch)
- free(reply_buf);
- if (from_buf != Nullch)
- free(from_buf);
- if (path_buf != Nullch)
- free(path_buf);
- if (follow_buf != Nullch)
- free(follow_buf);
- if (dist_buf != Nullch)
- free(dist_buf);
- if (line_buf != Nullch)
- free(line_buf);
- return pattern; /* where we left off */
- }
-
- void
- interp(dest,destsize,pattern)
- char *dest;
- int destsize;
- char *pattern;
- {
- dointerp(dest,destsize,pattern,Nullch);
- #ifdef DEBUGGING
- if (debug & DEB_FILEXP)
- fputs(dest,stdout);
- #endif
- }
-
- /* copy a references line, normalizing as we go */
-
- void
- refscpy(dest,destsize,src)
- register char *dest, *src;
- register int destsize;
- {
- register char *dot, *at, *beg;
- char tmpbuf[64];
-
- while (*src) {
- if (*src != '<') {
- if (--destsize <= 0)
- break;
- *dest++ = '<';
- at = dot = Nullch;
- beg = src;
- while (*src && *src != ' ' && *src != ',') {
- if (*src == '.')
- dot = src;
- else if (*src == '@')
- at = src;
- if (--destsize <= 0)
- break;
- *dest++ = *src++;
- }
- if (destsize <= 0)
- break;
- if (dot && !at) {
- int len;
-
- *dest = *dot++ = '\0';
- sprintf(tmpbuf,"%s@%s.UUCP",dot,beg);
- len = strlen(tmpbuf);
- if (destsize > len) {
- strcpy(dest,tmpbuf);
- dest = dest + len;
- destsize -= len;
- }
- }
- if (--destsize <= 0)
- break;
- *dest++ = '>';
- }
- else {
- while (*src && --destsize > 0 && (*dest++ = *src++) != '>') ;
- if (destsize <= 0)
- break;
- }
- while (*src == ' ' || *src == ',') src++;
- if (*src && --destsize > 0)
- *dest++ = ' ';
- }
- *dest = '\0';
- }
-
- /* get the person's real name from /etc/passwd */
- /* (string is overwritten, so it must be copied) */
-
- char *
- getrealname(uid)
- int uid;
- {
- char *s, *c;
-
- #ifdef PASSNAMES
- #ifdef GETPWENT
- struct passwd *pwd = getpwuid(uid);
-
- s = pwd->pw_gecos;
- #else
- char tmpbuf[512];
- int i;
-
- getpw(uid, tmpbuf);
- for (s=tmpbuf, i=GCOSFIELD-1; i; i--) {
- if (s)
- s = index(s,':')+1;
- }
- if (!s)
- return nullstr;
- cpytill(tmpbuf,s,':');
- s = tmpbuf;
- #endif
- #ifdef BERKNAMES
- #ifdef BERKJUNK
- while (*s && !isalnum(*s) && *s != '&') s++;
- #endif
- if ((c = index(s, ',')) != Nullch)
- *c = '\0';
- if ((c = index(s, ';')) != Nullch)
- *c = '\0';
- s = cpytill(buf,s,'&');
- if (*s == '&') { /* whoever thought this one up was */
- c = buf + strlen(buf); /* in the middle of the night */
- strcat(c,logname); /* before the morning after */
- strcat(c,s+1);
- if (islower(*c))
- *c = toupper(*c); /* gack and double gack */
- }
- #else
- if ((c = index(s, '(')) != Nullch)
- *c = '\0';
- if ((c = index(s, '-')) != Nullch)
- s = c;
- strcpy(buf,tmpbuf);
- #endif
- #ifdef GETPWENT
- endpwent();
- #endif
- return buf; /* return something static */
- #else
- if ((tmpfp=fopen(filexp(FULLNAMEFILE),"r")) != Nullfp) {
- fgets(buf,sizeof buf,tmpfp);
- fclose(tmpfp);
- buf[strlen(buf)-1] = '\0';
- return buf;
- }
- return "PUT YOUR NAME HERE";
- #endif
- }
-
- static void
- abort_interp()
- {
- fputs("\n% interp buffer overflow!\n",stdout) FLUSH;
- sig_catcher(0);
- }
- !STUFFY!FUNK!
- echo Extracting term.c
- cat >term.c <<'!STUFFY!FUNK!'
- /* $Header: term.c,v 4.3.2.7 90/04/21 16:54:29 sob Exp $
- *
- * $Log: term.c,v $
- * Revision 4.3.2.7 90/04/21 16:54:29 sob
- * Installed patches provided by SCO for SCO Xenix
- *
- * Revision 4.3.2.6 90/04/13 23:48:17 sob
- * Modifications provided by Gene Hackney for 3b2.
- *
- * Revision 4.3.2.5 90/04/06 20:35:08 sob
- * Added fixes for SCO Xenix sent by ronald@robobar.co.uk.
- *
- * Revision 4.3.2.4 90/03/22 23:05:38 sob
- * Fixes provided by Wayne Davison <drivax!davison>
- *
- * Revision 4.3.2.3 89/11/28 01:51:58 sob
- * Now handles SIGWINCH correctly.
- *
- * Revision 4.3.2.2 89/11/27 01:31:34 sob
- * Altered NNTP code per ideas suggested by Bela Lubkin
- * <filbo@gorn.santa-cruz.ca.us>
- *
- * Revision 4.3.2.1 89/11/06 01:02:12 sob
- * Added RRN support from NNTP 1.5
- *
- * Revision 4.3.1.3 85/09/10 11:05:23 lwall
- * Improved %m in in_char().
- *
- * Revision 4.3.1.2 85/05/16 16:45:35 lwall
- * Forced \r to \n on input.
- * Fix for terminfo braindamage regarding bc emulation.
- *
- * Revision 4.3.1.1 85/05/10 11:41:03 lwall
- * Branch for patches.
- *
- * Revision 4.3 85/05/01 11:51:10 lwall
- * Baseline for release with 4.3bsd.
- *
- */
-
- #include "EXTERN.h"
- #include "common.h"
- #include "util.h"
- #include "final.h"
- #include "help.h"
- #include "cheat.h"
- #include "intrp.h"
- #include "INTERN.h"
- #include "term.h"
-
- char ERASECH; /* rubout character */
- char KILLCH; /* line delete character */
- char tcarea[TCSIZE]; /* area for "compiled" termcap strings */
-
- /* guarantee capability pointer != Nullch */
- /* (I believe terminfo will ignore the &tmpaddr argument.) */
-
- #define Tgetstr(key) ((tmpstr = tgetstr(key,&tmpaddr)) ? tmpstr : nullstr)
-
- #ifdef PUSHBACK
- struct keymap {
- char km_type[128];
- union km_union {
- struct keymap *km_km;
- char *km_str;
- } km_ptr[128];
- };
-
- #define KM_NOTHIN 0
- #define KM_STRING 1
- #define KM_KEYMAP 2
- #define KM_BOGUS 3
-
- #define KM_TMASK 3
- #define KM_GSHIFT 4
- #define KM_GMASK 7
-
- typedef struct keymap KEYMAP;
-
- KEYMAP *topmap INIT(Null(KEYMAP*));
-
- void mac_init();
- KEYMAP *newkeymap();
- void show_keymap();
- void pushstring();
- #endif
-
- void line_col_calcs();
-
- /* terminal initialization */
-
- void
- term_init()
- {
- savetty(); /* remember current tty state */
-
- #ifdef TERMIO
- ospeed = _tty.c_cflag & CBAUD; /* for tputs() */
- ERASECH = _tty.c_cc[VERASE]; /* for finish_command() */
- KILLCH = _tty.c_cc[VKILL]; /* for finish_command() */
- #else
- ospeed = _tty.sg_ospeed; /* for tputs() */
- ERASECH = _tty.sg_erase; /* for finish_command() */
- KILLCH = _tty.sg_kill; /* for finish_command() */
- #endif
-
- /* The following could be a table but I can't be sure that there isn't */
- /* some degree of sparsity out there in the world. */
-
- switch (ospeed) { /* 1 second of padding */
- #ifdef BEXTA
- case BEXTA: just_a_sec = 1920; break;
- #else
- #ifdef B19200
- case B19200: just_a_sec = 1920; break;
- #endif
- #endif
- case B9600: just_a_sec = 960; break;
- case B4800: just_a_sec = 480; break;
- case B2400: just_a_sec = 240; break;
- case B1800: just_a_sec = 180; break;
- case B1200: just_a_sec = 120; break;
- case B600: just_a_sec = 60; break;
- case B300: just_a_sec = 30; break;
- /* do I really have to type the rest of this??? */
- case B200: just_a_sec = 20; break;
- case B150: just_a_sec = 15; break;
- case B134: just_a_sec = 13; break;
- case B110: just_a_sec = 11; break;
- case B75: just_a_sec = 8; break;
- case B50: just_a_sec = 5; break;
- default: just_a_sec = 960; break;
- /* if we are running detached I */
- } /* don't want to know about it! */
- }
-
- /* set terminal characteristics */
-
- void
- term_set(tcbuf)
- char *tcbuf; /* temp area for "uncompiled" termcap entry */
- {
- char *tmpaddr; /* must not be register */
- register char *tmpstr;
- char *tgetstr();
- char *s;
- int status;
- #ifdef TIOCGWINSZ
- #ifdef u3b2
- struct winsize {
- unsigned short ws_row; /* rows, in characters*/
- unsigned short ws_col; /* columns, in character */
- unsigned short ws_xpixel; /* horizontal size, pixels */
- unsigned short ws_ypixel; /* vertical size, pixels */
- };
- #endif
- struct winsize winsize;
- #endif
-
- #ifdef PENDING
- #if ! defined (FIONREAD) && ! defined (RDCHK)
- /* do no delay reads on something that always gets closed on exit */
-
- devtty = open("/dev/tty",0);
- if (devtty < 0) {
- printf(cantopen,"/dev/tty") FLUSH;
- finalize(1);
- }
- fcntl(devtty,F_SETFL,O_NDELAY);
- #endif
- #endif
-
- /* get all that good termcap stuff */
-
- #ifdef HAVETERMLIB
- status = tgetent(tcbuf,getenv("TERM")); /* get termcap entry */
- if (status < 1) {
- #ifdef VERBOSE
- printf("No termcap %s found.\n", status ? "file" : "entry") FLUSH;
- #else
- fputs("Termcap botch\n",stdout) FLUSH
- #endif
- finalize(1);
- }
- tmpaddr = tcarea; /* set up strange tgetstr pointer */
- s = Tgetstr("pc"); /* get pad character */
- PC = *s; /* get it where tputs wants it */
- if (!tgetflag("bs")) { /* is backspace not used? */
- BC = Tgetstr("bc"); /* find out what is */
- if (BC == nullstr) /* terminfo grok's 'bs' but not 'bc' */
- BC = Tgetstr("le");
- } else
- BC = "\b"; /* make a backspace handy */
- UP = Tgetstr("up"); /* move up a line */
- if (!*UP) /* no UP string? */
- marking = 0; /* disable any marking */
- if (muck_up_clear) /* this is for weird HPs */
- CL = "\n\n\n\n";
- else
- CL = Tgetstr("cl"); /* get clear string */
- CE = Tgetstr("ce"); /* clear to end of line string */
- #ifdef CLEAREOL
- CM = Tgetstr("cm"); /* cursor motion */
- HO = Tgetstr("ho"); /* home cursor if no CM */
- CD = Tgetstr("cd"); /* clear to end of display */
- if (!*CE || !*CD || (!*CM && !*HO)) /* can we CE, CD, and home? */
- can_home_clear = FALSE; /* no, so disable use of clear eol */
- #endif CLEAREOL
- SO = Tgetstr("so"); /* begin standout */
- SE = Tgetstr("se"); /* end standout */
- if ((SG = tgetnum("sg"))<0)
- SG = 0; /* blanks left by SG, SE */
- US = Tgetstr("us"); /* start underline */
- UE = Tgetstr("ue"); /* end underline */
- if ((UG = tgetnum("ug"))<0)
- UG = 0; /* blanks left by US, UE */
- if (*US)
- UC = nullstr; /* UC must not be NULL */
- else
- UC = Tgetstr("uc"); /* underline a character */
- if (!*US && !*UC) { /* no underline mode? */
- US = SO; /* substitute standout mode */
- UE = SE;
- UG = SG;
- }
- LINES = tgetnum("li"); /* lines per page */
- COLS = tgetnum("co"); /* columns on page */
-
- #ifdef TIOCGWINSZ
- { struct winsize ws;
- if (ioctl(0, TIOCGWINSZ, &ws) >= 0 && ws.ws_row > 0 && ws.ws_col > 0) {
- LINES = ws.ws_row;
- COLS = ws.ws_col;
- }
- }
- #endif
-
- AM = tgetflag("am"); /* terminal wraps automatically? */
- XN = tgetflag("xn"); /* then eats next newline? */
- VB = Tgetstr("vb");
- if (!*VB)
- VB = "\007";
- CR = Tgetstr("cr");
- if (!*CR) {
- if (tgetflag("nc") && *UP) {
- CR = safemalloc((MEM_SIZE)strlen(UP)+2);
- sprintf(CR,"%s\r",UP);
- }
- else
- CR = "\r";
- }
- #ifdef TIOCGWINSZ
- if (ioctl(1, TIOCGWINSZ, &winsize)>=0) {
- if (winsize.ws_row>0) LINES=winsize.ws_row;
- if (winsize.ws_col>0) COLS=winsize.ws_col;
- }
- #endif
- #else
- ?????? /* Roll your own... */
- #endif
- line_col_calcs();
- noecho(); /* turn off echo */
- crmode(); /* enter cbreak mode */
-
- #ifdef PUSHBACK
- mac_init(tcbuf);
- #endif
- }
-
- #ifdef PUSHBACK
- void
- mac_init(tcbuf)
- char *tcbuf;
- {
- char tmpbuf[1024];
-
- tmpfp = fopen(filexp(getval("RNMACRO",RNMACRO)),"r");
- if (tmpfp != Nullfp) {
- while (fgets(tcbuf,1024,tmpfp) != Nullch) {
- mac_line(tcbuf,tmpbuf,(sizeof tmpbuf));
- }
- fclose(tmpfp);
- }
- }
-
- void
- mac_line(line,tmpbuf,tbsize)
- char *line;
- char *tmpbuf;
- int tbsize;
- {
- register char *s, *m;
- register KEYMAP *curmap;
- register int ch;
- register int garbage = 0;
- static char override[] = "\nkeymap overrides string\n";
-
- if (topmap == Null(KEYMAP*))
- topmap = newkeymap();
- if (*line == '#' || *line == '\n')
- return;
- if (line[ch = strlen(line)-1] == '\n')
- line[ch] = '\0';
- m = dointerp(tmpbuf,tbsize,line," \t");
- if (!*m)
- return;
- while (*m == ' ' || *m == '\t') m++;
- for (s=tmpbuf,curmap=topmap; *s; s++) {
- ch = *s & 0177;
- if (s[1] == '+' && isdigit(s[2])) {
- s += 2;
- garbage = (*s & KM_GMASK) << KM_GSHIFT;
- }
- else
- garbage = 0;
- if (s[1]) {
- if ((curmap->km_type[ch] & KM_TMASK) == KM_STRING) {
- fputs(override,stdout) FLUSH;
- free(curmap->km_ptr[ch].km_str);
- curmap->km_ptr[ch].km_str = Nullch;
- }
- curmap->km_type[ch] = KM_KEYMAP + garbage;
- if (curmap->km_ptr[ch].km_km == Null(KEYMAP*))
- curmap->km_ptr[ch].km_km = newkeymap();
- curmap = curmap->km_ptr[ch].km_km;
- }
- else {
- if ((curmap->km_type[ch] & KM_TMASK) == KM_KEYMAP)
- fputs(override,stdout) FLUSH;
- else {
- curmap->km_type[ch] = KM_STRING + garbage;
- curmap->km_ptr[ch].km_str = savestr(m);
- }
- }
- }
- }
-
- KEYMAP*
- newkeymap()
- {
- register int i;
- register KEYMAP *map;
-
- #ifndef lint
- map = (KEYMAP*)safemalloc(sizeof(KEYMAP));
- #else
- map = Null(KEYMAP*);
- #endif lint
- for (i=127; i>=0; --i) {
- map->km_ptr[i].km_km = Null(KEYMAP*);
- map->km_type[i] = KM_NOTHIN;
- }
- return map;
- }
-
- void
- show_macros()
- {
- char prebuf[64];
-
- if (topmap != Null(KEYMAP*)) {
- print_lines("Macros:\n",STANDOUT);
- *prebuf = '\0';
- show_keymap(topmap,prebuf);
- }
- }
-
- void
- show_keymap(curmap,prefix)
- register KEYMAP *curmap;
- char *prefix;
- {
- register int i;
- register char *next = prefix + strlen(prefix);
- register int kt;
-
- for (i=0; i<128; i++) {
- if (kt = curmap->km_type[i]) {
- if (i < ' ')
- sprintf(next,"^%c",i+64);
- else if (i == ' ')
- strcpy(next,"\\040");
- else if (i == 127)
- strcpy(next,"^?");
- else
- sprintf(next,"%c",i);
- if ((kt >> KM_GSHIFT) & KM_GMASK) {
- sprintf(cmd_buf,"+%d", (kt >> KM_GSHIFT) & KM_GMASK);
- strcat(next,cmd_buf);
- }
- switch (kt & KM_TMASK) {
- case KM_NOTHIN:
- sprintf(cmd_buf,"%s %c\n",prefix,i);
- print_lines(cmd_buf,NOMARKING);
- break;
- case KM_KEYMAP:
- show_keymap(curmap->km_ptr[(char)i].km_km, prefix);
- break;
- case KM_STRING:
- sprintf(cmd_buf,"%s %s\n",prefix,curmap->km_ptr[i].km_str);
- print_lines(cmd_buf,NOMARKING);
- break;
- case KM_BOGUS:
- sprintf(cmd_buf,"%s BOGUS\n",prefix);
- print_lines(cmd_buf,STANDOUT);
- break;
- }
- }
- }
- }
-
- #endif
-
- /* routine to pass to tputs */
-
- char
- putchr(ch)
- register char ch;
- {
- putchar(ch);
- #ifdef lint
- ch = Null(char);
- ch = ch;
- #endif
- return((char) 0);
- }
-
- /* input the 2nd and succeeding characters of a multi-character command */
- /* returns TRUE if command finished, FALSE if they rubbed out first character */
-
- bool
- finish_command(donewline)
- int donewline;
- {
- register char *s;
- register bool quoteone = FALSE;
-
- s = buf;
- if (s[1] != FINISHCMD) /* someone faking up a command? */
- return TRUE;
- do {
- top:
- if (*s < ' ') {
- putchar('^');
- putchar(*s | 64);
- }
- else if (*s == '\177') {
- putchar('^');
- putchar('?');
- }
- else
- putchar(*s); /* echo previous character */
- s++;
- re_read:
- fflush(stdout);
- getcmd(s);
- if (quoteone) {
- quoteone = FALSE;
- continue;
- }
- if (errno || *s == Ctl('l')) {
- *s = Ctl('r'); /* force rewrite on CONT */
- }
- if (*s == '\033') { /* substitution desired? */
- #ifdef ESCSUBS
- char tmpbuf[4], *cpybuf;
-
- tmpbuf[0] = '%';
- read_tty(&tmpbuf[1],1);
- #ifdef RAWONLY
- tmpbuf[1] &= 0177;
- #endif
- tmpbuf[2] = '\0';
- if (tmpbuf[1] == 'h') {
- (void) help_subs();
- *s = '\0';
- reprint();
- goto re_read;
- }
- else if (tmpbuf[1] == '\033') {
- *s = '\0';
- cpybuf = savestr(buf);
- interp(buf, (sizeof buf), cpybuf);
- free(cpybuf);
- s = buf + strlen(buf);
- reprint();
- goto re_read;
- }
- else {
- interp(s,(sizeof buf) - (s-buf),tmpbuf);
- fputs(s,stdout);
- s += strlen(s);
- }
- goto re_read;
- #else
- notincl("^[");
- *s = '\0';
- reprint();
- goto re_read;
- #endif
- }
- else if (*s == ERASECH) { /* they want to rubout a char? */
- rubout();
- s--; /* discount the char rubbed out */
- if (*s < ' ' || *s == '\177')
- rubout();
- if (s == buf) { /* entire string gone? */
- fflush(stdout); /* return to single char command mode */
- return FALSE;
- }
- else
- goto re_read;
- }
- else if (*s == KILLCH) { /* wipe out the whole line? */
- while (s-- != buf) { /* emulate that many ERASEs */
- rubout();
- if (*s < ' ' || *s == '\177')
- rubout();
- }
- fflush(stdout);
- return FALSE; /* return to single char mode */
- }
- #ifdef WORDERASE
- else if (*s == Ctl('w')) { /* wipe out one word? */
- *s-- = ' ';
- while (!isspace(*s) || isspace(s[1])) {
- rubout();
- if (s-- == buf) {
- fflush(stdout);
- return FALSE; /* return to single char mode */
- }
- if (*s < ' ' || *s == '\177')
- rubout();
- }
- s++;
- goto re_read;
- }
- #endif
- else if (*s == Ctl('r')) {
- *s = '\0';
- reprint();
- goto re_read;
- }
- else if (*s == Ctl('v')) {
- putchar('^');
- backspace();
- fflush(stdout);
- getcmd(s);
- goto top;
- }
- else if (*s == '\\') {
- quoteone = TRUE;
- }
- } while (*s != '\n'); /* till a newline (not echoed) */
- *s = '\0'; /* terminate the string nicely */
- if (donewline)
- putchar('\n') FLUSH;
- return TRUE; /* say we succeeded */
- }
-
- /* discard any characters typed ahead */
-
- void
- eat_typeahead()
- {
- #ifdef PUSHBACK
- if (!typeahead && nextin==nextout) /* cancel only keyboard stuff */
- #else
- if (!typeahead)
- #endif
- {
- #ifdef PENDING
- while (input_pending())
- read_tty(buf,sizeof(buf));
- #else /* this is probably v7 */
- ioctl(_tty_ch,TIOCSETP,&_tty);
- #endif
- }
- }
-
- void
- settle_down()
- {
- dingaling();
- fflush(stdout);
- sleep(1);
- #ifdef PUSHBACK
- nextout = nextin; /* empty circlebuf */
- #endif
- eat_typeahead();
- }
-
- #ifdef PUSHBACK
- /* read a character from the terminal, with multi-character pushback */
-
- int
- read_tty(addr,size)
- char *addr;
- int size;
- {
- if (nextout != nextin) {
- *addr = circlebuf[nextout++];
- nextout %= PUSHSIZE;
- return 1;
- }
- else {
- size = read(0,addr,size);
- #ifdef RAWONLY
- *addr &= 0177;
- #endif
- return size;
- }
- }
-
- #ifdef PENDING
- #if ! defined (FIONREAD) && ! defined (RDCHK)
- int
- circfill()
- {
- register int Howmany = read(devtty,circlebuf+nextin,1);
-
- if (Howmany) {
- nextin += Howmany;
- nextin %= PUSHSIZE;
- }
- return Howmany;
- }
- #endif PENDING
- #endif FIONREAD
-
- void
- pushchar(c)
- char c;
- {
- nextout--;
- if (nextout < 0)
- nextout = PUSHSIZE - 1;
- if (nextout == nextin) {
- fputs("\npushback buffer overflow\n",stdout) FLUSH;
- sig_catcher(0);
- }
- circlebuf[nextout] = c;
- }
-
- #else PUSHBACK
- #ifndef read_tty
- /* read a character from the terminal, with hacks for O_NDELAY reads */
-
- int
- read_tty(addr,size)
- char *addr;
- int size;
- {
- if (is_input) {
- *addr = pending_ch;
- is_input = FALSE;
- return 1;
- }
- else {
- size = read(0,addr,size);
- #ifdef RAWONLY
- *addr &= 0177;
- #endif
- return size;
- }
- }
- #endif read_tty
- #endif PUSHBACK
-
- /* print an underlined string, one way or another */
-
- void
- underprint(s)
- register char *s;
- {
- assert(UC);
- if (*UC) { /* char by char underline? */
- while (*s) {
- if (*s < ' ') {
- putchar('^');
- backspace();/* back up over it */
- underchar();/* and do the underline */
- putchar(*s+64);
- backspace();/* back up over it */
- underchar();/* and do the underline */
- }
- else {
- putchar(*s);
- backspace();/* back up over it */
- underchar();/* and do the underline */
- }
- s++;
- }
- }
- else { /* start and stop underline */
- underline(); /* start underlining */
- while (*s) {
- if (*s < ' ') {
- putchar('^');
- putchar(*s+64);
- }
- else
- putchar(*s);
- s++;
- }
- un_underline(); /* stop underlining */
- }
- }
-
- /* keep screen from flashing strangely on magic cookie terminals */
-
- #ifdef NOFIREWORKS
- void
- no_sofire()
- {
- if (*UP && *SE) { /* should we disable fireworks? */
- putchar('\n');
- un_standout();
- up_line();
- carriage_return();
- }
- }
-
- void
- no_ulfire()
- {
- if (*UP && *US) { /* should we disable fireworks? */
- putchar('\n');
- un_underline();
- up_line();
- carriage_return();
- }
- }
- #endif
-
- /* get a character into a buffer */
-
- void
- getcmd(whatbuf)
- register char *whatbuf;
- {
- #ifdef PUSHBACK
- register KEYMAP *curmap;
- register int i;
- bool no_macros;
- int times = 0; /* loop detector */
- char scrchar;
-
- tryagain:
- curmap = topmap;
- no_macros = (whatbuf != buf && nextin == nextout);
- #endif
- for (;;) {
- int_count = 0;
- errno = 0;
- if (read_tty(whatbuf,1) < 0)
- if (!errno)
- errno = EINTR;
- else {
- perror(readerr);
- sig_catcher(0);
- }
- #ifdef PUSHBACK
- if (*whatbuf & 0200 || no_macros) {
- *whatbuf &= 0177;
- goto got_canonical;
- }
- if (curmap == Null(KEYMAP*))
- goto got_canonical;
- for (i = (curmap->km_type[*whatbuf] >> KM_GSHIFT) & KM_GMASK; i; --i){
- read_tty(&scrchar,1);
- }
- switch (curmap->km_type[*whatbuf] & KM_TMASK) {
- case KM_NOTHIN: /* no entry? */
- if (curmap == topmap) /* unmapped canonical */
- goto got_canonical;
- settle_down();
- goto tryagain;
- case KM_KEYMAP: /* another keymap? */
- curmap = curmap->km_ptr[*whatbuf].km_km;
- assert(curmap != Null(KEYMAP*));
- break;
- case KM_STRING: /* a string? */
- pushstring(curmap->km_ptr[*whatbuf].km_str);
- if (++times > 20) { /* loop? */
- fputs("\nmacro loop?\n",stdout);
- settle_down();
- }
- no_macros = FALSE;
- goto tryagain;
- }
- #else
- #ifdef RAWONLY
- *whatbuf &= 0177;
- #endif
- break;
- #endif
- }
-
- got_canonical:
- #ifndef TERMIO
- if (*whatbuf == '\r')
- *whatbuf = '\n';
- #endif
- if (whatbuf == buf)
- whatbuf[1] = FINISHCMD; /* tell finish_command to work */
- }
-
- #ifdef PUSHBACK
- void
- pushstring(str)
- char *str;
- {
- register int i;
- char tmpbuf[PUSHSIZE];
- register char *s = tmpbuf;
-
- assert(str != Nullch);
- interp(s,PUSHSIZE,str);
- for (i = strlen(s)-1; i >= 0; --i) {
- s[i] ^= 0200;
- pushchar(s[i]);
- }
- }
- #endif
-
- int
- get_anything()
- {
- char tmpbuf[2];
-
- reask_anything:
- unflush_output(); /* disable any ^O in effect */
- standout();
- #ifdef VERBOSE
- IF(verbose)
- fputs("[Type space to continue] ",stdout);
- ELSE
- #endif
- #ifdef TERSE
- fputs("[MORE] ",stdout);
- #endif
- un_standout();
- fflush(stdout);
- eat_typeahead();
- if (int_count) {
- return -1;
- }
- collect_subjects(); /* loads subject cache until */
- /* input is pending */
- getcmd(tmpbuf);
- if (errno || *tmpbuf == '\f') {
- putchar('\n') FLUSH; /* if return from stop signal */
- goto reask_anything; /* give them a prompt again */
- }
- if (*tmpbuf == 'h') {
- #ifdef VERBOSE
- IF(verbose)
- fputs("\nType q to quit or space to continue.\n",stdout) FLUSH;
- ELSE
- #endif
- #ifdef TERSE
- fputs("\nq to quit, space to continue.\n",stdout) FLUSH;
- #endif
- goto reask_anything;
- }
- else if (*tmpbuf != ' ' && *tmpbuf != '\n') {
- carriage_return();
- erase_eol(); /* erase the prompt */
- carriage_return();
- return *tmpbuf == 'q' ? -1 : *tmpbuf;
- }
- if (*tmpbuf == '\n') {
- page_line = LINES - 1;
- carriage_return();
- erase_eol();
- carriage_return();
- }
- else {
- page_line = 1;
- if (erase_screen) /* -e? */
- clear(); /* clear screen */
- else {
- carriage_return();
- erase_eol(); /* erase the prompt */
- carriage_return();
- }
- }
- return 0;
- }
-
- void
- in_char(prompt, newmode)
- char *prompt;
- char newmode;
- {
- char oldmode = mode;
-
- reask_in_char:
- unflush_output(); /* disable any ^O in effect */
- fputs(prompt,stdout);
- fflush(stdout);
- eat_typeahead();
- mode = newmode;
- getcmd(buf);
- if (errno || *buf == '\f') {
- putchar('\n') FLUSH; /* if return from stop signal */
- goto reask_in_char; /* give them a prompt again */
- }
- mode = oldmode;
- }
-
- int
- print_lines(what_to_print,hilite)
- char *what_to_print;
- int hilite;
- {
- register char *s;
- register int i;
-
- if (page_line < 0) /* they do not want to see this? */
- return -1;
- for (s=what_to_print; *s; ) {
- if (page_line >= LINES || int_count) {
- if (i = -1, int_count || (i = get_anything())) {
- page_line = -1; /* disable further print_lines */
- return i;
- }
- }
- page_line++;
- if (hilite == STANDOUT) {
- #ifdef NOFIREWORKS
- if (erase_screen)
- no_sofire();
- #endif
- standout();
- }
- else if (hilite == UNDERLINE) {
- #ifdef NOFIREWORKS
- if (erase_screen)
- no_ulfire();
- #endif
- underline();
- }
- for (i=0; i<COLS; i++) {
- if (!*s)
- break;
- if (*s >= ' ')
- putchar(*s);
- else if (*s == '\t') {
- putchar(*s);
- i = ((i+8) & ~7) - 1;
- }
- else if (*s == '\n') {
- i = 32000;
- }
- else {
- i++;
- putchar('^');
- putchar(*s + 64);
- }
- s++;
- }
- if (i) {
- if (hilite == STANDOUT)
- un_standout();
- else if (hilite == UNDERLINE)
- un_underline();
- if (AM && i == COLS)
- fflush(stdout);
- else
- putchar('\n') FLUSH;
- }
- }
- return 0;
- }
-
- void
- page_init()
- {
- page_line = 1;
- if (erase_screen)
- clear();
- else
- putchar('\n') FLUSH;
- }
-
- void
- pad(num)
- int num;
- {
- register int i;
-
- for (i = num; i; --i)
- putchar(PC);
- fflush(stdout);
- }
-
- /* echo the command just typed */
-
- #ifdef VERIFY
- void
- printcmd()
- {
- if (verify && buf[1] == FINISHCMD) {
- if (*buf < ' ') {
- putchar('^');
- putchar(*buf | 64);
- backspace();
- backspace();
- }
- else {
- putchar(*buf);
- backspace();
- }
- fflush(stdout);
- }
- }
- #endif
-
- void
- rubout()
- {
- backspace(); /* do the old backspace, */
- putchar(' '); /* space, */
- backspace(); /* backspace trick */
- }
-
- void
- reprint()
- {
- register char *s;
-
- fputs("^R\n",stdout) FLUSH;
- for (s = buf; *s; s++) {
- if (*s < ' ') {
- putchar('^');
- putchar(*s | 64);
- }
- else
- putchar(*s);
- }
- }
-
- #ifdef CLEAREOL
- void
- home_cursor()
- {
- char *tgoto();
-
- if (!*HO) { /* no home sequence? */
- if (!*CM) { /* no cursor motion either? */
- fputs ("\n\n\n", stdout);
- return; /* forget it. */
- }
- tputs (tgoto (CM, 0, 0), 1, putchr); /* go to home via CM */
- return;
- }
- else { /* we have home sequence */
- tputs (HO, 1, putchr); /* home via HO */
- }
- }
- #endif CLEAREOL
-
-
- void
- line_col_calcs()
- {
- if (LINES > 0) { /* is this a crt? */
- if ((!initlines) || (!initlines_specified))
- /* no -i or unreasonable value for initlines */
- if (ospeed >= B9600) /* whole page at >= 9600 baud */
- initlines = LINES;
- else if (ospeed >= B4800)/* 16 lines at 4800 */
- initlines = 16;
- else /* otherwise just header */
- initlines = 8;
- }
- else { /* not a crt */
- LINES = 30000; /* so don't page */
- CL = "\n\n"; /* put a couple of lines between */
- if ((!initlines) || (!initlines_specified))
- /* make initlines reasonable */
- initlines = 8;
- }
- if (COLS <= 0)
- COLS = 80;
- }
-
-
- #ifdef SIGWINCH
- int
- winch_catcher()
- {
- /* Come here if window size change signal received */
- #ifdef TIOCGWINSZ
- struct winsize ws;
-
- if (ioctl(0, TIOCGWINSZ, &ws) >= 0 && ws.ws_row > 0 && ws.ws_col > 0) {
- LINES = ws.ws_row;
- COLS = ws.ws_col;
- line_col_calcs();
- }
- #else
- ???????
- /* Well, if SIGWINCH is defined, but TIOCGWINSZ isn't, there's */
- /* almost certainly something wrong. Figure it out for yourself, */
- /* because I don't know now to deal :-) */
- #endif
- }
- #endif
- !STUFFY!FUNK!
- echo Extracting search.c
- cat >search.c <<'!STUFFY!FUNK!'
- /* $Header: search.c,v 4.3.2.2 90/03/22 23:05:31 sob Exp $
- *
- * $Log: search.c,v $
- * Revision 4.3.2.2 90/03/22 23:05:31 sob
- * Fixes provided by Wayne Davison <drivax!davison>
- *
- * Revision 4.3.2.1 90/03/17 17:46:29 sob
- * Added changes to insure that null search strings won't result in core dumps
- * on non-VAX computers.
- *
- * Revision 4.3 85/05/01 11:50:16 lwall
- * Baseline for release with 4.3bsd.
- *
- */
-
- /* string search routines */
-
- /* Copyright (c) 1981,1980 James Gosling */
-
- /* Modified Aug. 12, 1981 by Tom London to include regular expressions
- as in ed. RE stuff hacked over by jag to correct a few major problems,
- mainly dealing with searching within the buffer rather than copying
- each line to a separate array. Newlines can now appear in RE's */
-
- /* Ripped to shreds and glued back together to make a search package,
- * July 6, 1984, by Larry Wall. (If it doesn't work, it's probably my fault.)
- * Changes include:
- * Buffer, window, and mlisp stuff gone.
- * Translation tables reduced to 1 table.
- * Expression buffer is now dynamically allocated.
- * Character classes now implemented with a bitmap.
- */
-
- #include "EXTERN.h"
- #include "common.h"
- #include "util.h"
- #include "INTERN.h"
- #include "search.h"
-
- #ifndef BITSPERBYTE
- #define BITSPERBYTE 8
- #endif
-
- #define BMAPSIZ (127 / BITSPERBYTE + 1)
-
- /* meta characters in the "compiled" form of a regular expression */
- #define CBRA 2 /* \( -- begin bracket */
- #define CCHR 4 /* a vanilla character */
- #define CDOT 6 /* . -- match anything except a newline */
- #define CCL 8 /* [...] -- character class */
- #define NCCL 10 /* [^...] -- negated character class */
- #define CDOL 12 /* $ -- matches the end of a line */
- #define CEND 14 /* The end of the pattern */
- #define CKET 16 /* \) -- close bracket */
- #define CBACK 18 /* \N -- backreference to the Nth bracketed
- string */
- #define CIRC 20 /* ^ matches the beginning of a line */
-
- #define WORD 32 /* matches word character \w */
- #define NWORD 34 /* matches non-word characer \W */
- #define WBOUND 36 /* matches word boundary \b */
- #define NWBOUND 38 /* matches non-(word boundary) \B */
-
- #define STAR 01 /* * -- Kleene star, repeats the previous
- REas many times as possible; the value
- ORs with the other operator types */
-
- #define ASCSIZ 0200
- typedef char TRANSTABLE[ASCSIZ];
-
- static TRANSTABLE trans = {
- 0000,0001,0002,0003,0004,0005,0006,0007,
- 0010,0011,0012,0013,0014,0015,0016,0017,
- 0020,0021,0022,0023,0024,0025,0026,0027,
- 0030,0031,0032,0033,0034,0035,0036,0037,
- 0040,0041,0042,0043,0044,0045,0046,0047,
- 0050,0051,0052,0053,0054,0055,0056,0057,
- 0060,0061,0062,0063,0064,0065,0066,0067,
- 0070,0071,0072,0073,0074,0075,0076,0077,
- 0100,0101,0102,0103,0104,0105,0106,0107,
- 0110,0111,0112,0113,0114,0115,0116,0117,
- 0120,0121,0122,0123,0124,0125,0126,0127,
- 0130,0131,0132,0133,0134,0135,0136,0137,
- 0140,0141,0142,0143,0144,0145,0146,0147,
- 0150,0151,0152,0153,0154,0155,0156,0157,
- 0160,0161,0162,0163,0164,0165,0166,0167,
- 0170,0171,0172,0173,0174,0175,0176,0177,
- };
- static bool folding = FALSE;
-
- static int err;
- static char *FirstCharacter;
-
- void
- search_init()
- {
- #ifdef UNDEF
- register int i;
-
- for (i = 0; i < ASCSIZ; i++)
- trans[i] = i;
- #else
- ;
- #endif
- }
-
- void
- init_compex(compex)
- register COMPEX *compex;
- {
- /* the following must start off zeroed */
-
- compex->eblen = 0;
- compex->brastr = Nullch;
- }
-
- void
- free_compex(compex)
- register COMPEX *compex;
- {
- if (compex->eblen) {
- free(compex->expbuf);
- compex->eblen = 0;
- }
- if (compex->brastr) {
- free(compex->brastr);
- compex->brastr = Nullch;
- }
- }
-
- static char *gbr_str = Nullch;
- static int gbr_siz = 0;
-
- char *
- getbracket(compex,n)
- register COMPEX *compex;
- int n;
- {
- int length = compex->braelist[n] - compex->braslist[n];
-
- if (!compex->nbra || n > compex->nbra || !compex->braelist[n] || length<0)
- return nullstr;
- growstr(&gbr_str, &gbr_siz, length+1);
- safecpy(gbr_str, compex->braslist[n], length+1);
- return gbr_str;
- }
-
- void
- case_fold(which)
- int which;
- {
- register int i;
-
- if (which != folding) {
- if (which) {
- for (i = 'A'; i <= 'Z'; i++)
- trans[i] = tolower(i);
- }
- else {
- for (i = 'A'; i <= 'Z'; i++)
- trans[i] = i;
- }
- folding = which;
- }
- }
-
- /* Compile the given regular expression into a [secret] internal format */
-
- char *
- compile (compex, strp, RE, fold)
- register COMPEX *compex;
- register char *strp;
- int RE;
- int fold;
- {
- register int c;
- register char *ep;
- char *lastep;
- char bracket[NBRA],
- *bracketp;
- char **alt = compex->alternatives;
- char *retmes = "Badly formed search string";
-
- case_fold(compex->do_folding = fold);
- if (!compex->eblen) {
- compex->expbuf = safemalloc(84);
- compex->eblen = 80;
- }
- ep = compex->expbuf; /* point at expression buffer */
- *alt++ = ep; /* first alternative starts here */
- bracketp = bracket; /* first bracket goes here */
- if (*strp == 0) { /* nothing to compile? */
- if (*ep == 0) /* nothing there yet? */
- return "Null search string";
- return Nullch; /* just keep old expression */
- }
- compex->nbra = 0; /* no brackets yet */
- lastep = 0;
- for (;;) {
- if (ep - compex->expbuf >= compex->eblen)
- grow_eb(compex);
- c = *strp++; /* fetch next char of pattern */
- if (c == 0) { /* end of pattern? */
- if (bracketp != bracket) { /* balanced brackets? */
- #ifdef VERBOSE
- retmes = "Unbalanced parens";
- #endif
- goto cerror;
- }
- *ep++ = CEND; /* terminate expression */
- *alt++ = 0; /* terminal alternative list */
- /*
- compex->eblen = ep - compex->expbuf + 1;
- compex->expbuf = saferealloc(compex->expbuf,compex->eblen+4); */
- return Nullch; /* return success */
- }
- if (c != '*')
- lastep = ep;
- if (!RE) { /* just a normal search string? */
- *ep++ = CCHR; /* everything is a normal char */
- *ep++ = c;
- }
- else /* it is a regular expression */
- switch (c) {
-
- case '\\': /* meta something */
- switch (c = *strp++) {
- case '(':
- if (compex->nbra >= NBRA) {
- #ifdef VERBOSE
- retmes = "Too many parens";
- #endif
- goto cerror;
- }
- *bracketp++ = ++compex->nbra;
- *ep++ = CBRA;
- *ep++ = compex->nbra;
- break;
- case '|':
- if (bracketp>bracket) {
- #ifdef VERBOSE
- retmes = "No \\| in parens"; /* Alas! */
- #endif
- goto cerror;
- }
- *ep++ = CEND;
- *alt++ = ep;
- break;
- case ')':
- if (bracketp <= bracket) {
- #ifdef VERBOSE
- retmes = "Unmatched right paren";
- #endif
- goto cerror;
- }
- *ep++ = CKET;
- *ep++ = *--bracketp;
- break;
- case 'w':
- *ep++ = WORD;
- break;
- case 'W':
- *ep++ = NWORD;
- break;
- case 'b':
- *ep++ = WBOUND;
- break;
- case 'B':
- *ep++ = NWBOUND;
- break;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- *ep++ = CBACK;
- *ep++ = c - '0';
- break;
- default:
- *ep++ = CCHR;
- if (c == '\0')
- goto cerror;
- *ep++ = c;
- break;
- }
- break;
- case '.':
- *ep++ = CDOT;
- continue;
-
- case '*':
- if (lastep == 0 || *lastep == CBRA || *lastep == CKET
- || *lastep == CIRC
- || (*lastep&STAR)|| *lastep>NWORD)
- goto defchar;
- *lastep |= STAR;
- continue;
-
- case '^':
- if (ep != compex->expbuf && ep[-1] != CEND)
- goto defchar;
- *ep++ = CIRC;
- continue;
-
- case '$':
- if (*strp != 0 && (*strp != '\\' || strp[1] != '|'))
- goto defchar;
- *ep++ = CDOL;
- continue;
-
- case '[': { /* character class */
- register int i;
-
- if (ep - compex->expbuf >= compex->eblen - BMAPSIZ)
- grow_eb(compex); /* reserve bitmap */
- for (i = BMAPSIZ; i; --i)
- ep[i] = 0;
-
- if ((c = *strp++) == '^') {
- c = *strp++;
- *ep++ = NCCL; /* negated */
- }
- else
- *ep++ = CCL; /* normal */
-
- i = 0; /* remember oldchar */
- do {
- if (c == '\0') {
- #ifdef VERBOSE
- retmes = "Missing ]";
- #endif
- goto cerror;
- }
- if (*strp == '-' && *(++strp))
- i = *strp++;
- else
- i = c;
- while (c <= i) {
- ep[c / BITSPERBYTE] |= 1 << (c % BITSPERBYTE);
- if (fold && isalpha(c))
- ep[(c ^ 32) / BITSPERBYTE] |=
- 1 << ((c ^ 32) % BITSPERBYTE);
- /* set the other bit too */
- c++;
- }
- } while ((c = *strp++) != ']');
- ep += BMAPSIZ;
- continue;
- }
-
- defchar:
- default:
- *ep++ = CCHR;
- *ep++ = c;
- }
- }
- cerror:
- compex->expbuf[0] = 0;
- compex->nbra = 0;
- return retmes;
- }
-
- void
- grow_eb(compex)
- register COMPEX *compex;
- {
- compex->eblen += 80;
- compex->expbuf = saferealloc(compex->expbuf, (MEM_SIZE)compex->eblen + 4);
- }
-
- char *
- execute (compex, addr)
- register COMPEX *compex;
- char *addr;
- {
- register char *p1 = addr;
- register char *trt = trans;
- register int c;
-
- if (addr == Nullch || compex->expbuf == Nullch)
- return Nullch;
- if (compex->nbra) { /* any brackets? */
- for (c = 0; c <= compex->nbra; c++)
- compex->braslist[c] = compex->braelist[c] = Nullch;
- if (compex->brastr)
- free(compex->brastr);
- compex->brastr = savestr(p1); /* in case p1 is not static */
- p1 = compex->brastr; /* ! */
- }
- case_fold(compex->do_folding); /* make sure table is correct */
- FirstCharacter = p1; /* for ^ tests */
- if (compex->expbuf[0] == CCHR && !compex->alternatives[1]) {
- c = trt[compex->expbuf[1]]; /* fast check for first character */
- do {
- if (trt[*p1] == c && advance (compex, p1, compex->expbuf))
- return p1;
- p1++;
- } while (*p1 && !err);
- return Nullch;
- }
- else { /* regular algorithm */
- do {
- register char **alt = compex->alternatives;
- while (*alt) {
- if (advance (compex, p1, *alt++))
- return p1;
- }
- p1++;
- } while (*p1 && !err);
- return Nullch;
- }
- }
-
- /* advance the match of the regular expression starting at ep along the
- string lp, simulates an NDFSA */
- bool
- advance (compex, lp, ep)
- register COMPEX *compex;
- register char *ep;
- register char *lp;
- {
- register char *curlp;
- register char *trt = trans;
- register int i;
-
- while ((*ep & STAR) || *lp || *ep == CIRC || *ep == CKET)
- switch (*ep++) {
-
- case CCHR:
- if (trt[*ep++] != trt[*lp]) return FALSE;
- lp++;
- continue;
-
- case CDOT:
- if (*lp == '\n') return FALSE;
- lp++;
- continue;
-
- case CDOL:
- if (!*lp || *lp == '\n')
- continue;
- return FALSE;
-
- case CIRC:
- if (lp == FirstCharacter || lp[-1]=='\n')
- continue;
- return FALSE;
-
- case WORD:
- if (isalnum(*lp)) {
- lp++;
- continue;
- }
- return FALSE;
-
- case NWORD:
- if (!isalnum(*lp)) {
- lp++;
- continue;
- }
- return FALSE;
-
- case WBOUND:
- if ((lp == FirstCharacter || !isalnum(lp[-1])) !=
- (!*lp || !isalnum(*lp)) )
- continue;
- return FALSE;
-
- case NWBOUND:
- if ((lp == FirstCharacter || !isalnum(lp[-1])) ==
- (!*lp || !isalnum(*lp)))
- continue;
- return FALSE;
-
- case CEND:
- return TRUE;
-
- case CCL:
- if (cclass (ep, *lp, 1)) {
- ep += BMAPSIZ;
- lp++;
- continue;
- }
- return FALSE;
-
- case NCCL:
- if (cclass (ep, *lp, 0)) {
- ep += BMAPSIZ;
- lp++;
- continue;
- }
- return FALSE;
-
- case CBRA:
- compex->braslist[*ep++] = lp;
- continue;
-
- case CKET:
- i = *ep++;
- compex->braelist[i] = lp;
- compex->braelist[0] = lp;
- compex->braslist[0] = compex->braslist[i];
- continue;
-
- case CBACK:
- if (compex->braelist[i = *ep++] == 0) {
- fputs("bad braces\n",stdout) FLUSH;
- err = TRUE;
- return FALSE;
- }
- if (backref (compex, i, lp)) {
- lp += compex->braelist[i] - compex->braslist[i];
- continue;
- }
- return FALSE;
-
- case CBACK | STAR:
- if (compex->braelist[i = *ep++] == 0) {
- fputs("bad braces\n",stdout) FLUSH;
- err = TRUE;
- return FALSE;
- }
- curlp = lp;
- while (backref (compex, i, lp)) {
- lp += compex->braelist[i] - compex->braslist[i];
- }
- while (lp >= curlp) {
- if (advance (compex, lp, ep))
- return TRUE;
- lp -= compex->braelist[i] - compex->braslist[i];
- }
- continue;
-
- case CDOT | STAR:
- curlp = lp;
- while (*lp++ && lp[-1] != '\n');
- goto star;
-
- case WORD | STAR:
- curlp = lp;
- while (*lp++ && isalnum(lp[-1]));
- goto star;
-
- case NWORD | STAR:
- curlp = lp;
- while (*lp++ && !isalnum(lp[-1]));
- goto star;
-
- case CCHR | STAR:
- curlp = lp;
- while (*lp++ && trt[lp[-1]] == trt[*ep]);
- ep++;
- goto star;
-
- case CCL | STAR:
- case NCCL | STAR:
- curlp = lp;
- while (*lp++ && cclass (ep, lp[-1], ep[-1] == (CCL | STAR)));
- ep += BMAPSIZ;
- goto star;
-
- star:
- do {
- lp--;
- if (advance (compex, lp, ep))
- return TRUE;
- } while (lp > curlp);
- return FALSE;
-
- default:
- fputs("Badly compiled pattern\n",stdout) FLUSH;
- err = TRUE;
- return -1;
- }
- if (*ep == CEND || *ep == CDOL) {
- return TRUE;
- }
- return FALSE;
- }
-
- bool
- backref (compex, i, lp)
- register COMPEX *compex;
- register int i;
- register char *lp;
- {
- register char *bp;
-
- bp = compex->braslist[i];
- while (*lp && *bp == *lp) {
- bp++;
- lp++;
- if (bp >= compex->braelist[i])
- return TRUE;
- }
- return FALSE;
- }
-
- bool
- cclass (set, c, af)
- register char *set;
- register int c;
- {
- c &= 0177;
- #if BITSPERBYTE == 8
- if (set[c >> 3] & 1 << (c & 7))
- #else
- if (set[c / BITSPERBYTE] & 1 << (c % BITSPERBYTE))
- #endif
- return af;
- return !af;
- }
- !STUFFY!FUNK!
- echo Extracting artsrch.h
- cat >artsrch.h <<'!STUFFY!FUNK!'
- /* $Header: artsrch.h,v 4.3 85/05/01 11:35:55 lwall Exp $
- *
- * $Log: artsrch.h,v $
- * Revision 4.3 85/05/01 11:35:55 lwall
- * Baseline for release with 4.3bsd.
- *
- */
-
- #ifndef NBRA
- #include "search.h"
- #endif
-
- #ifdef ARTSEARCH
-
- #define SRCH_ABORT 0
- #define SRCH_INTR 1
- #define SRCH_FOUND 2
- #define SRCH_NOTFOUND 3
- #define SRCH_DONE 4
- #define SRCH_SUBJDONE 5
- #define SRCH_ERROR 6
- #endif
-
- EXT char *lastpat INIT(nullstr); /* last search pattern */
- #ifdef ARTSEARCH
- EXT COMPEX sub_compex; /* last compiled subject search */
- EXT COMPEX art_compex; /* last compiled normal search */
- # ifdef CONDSUB
- EXT COMPEX *bra_compex INIT(&art_compex);
- /* current compex with brackets */
- # endif
- EXT char art_howmuch; /* search just the subjects */
- EXT bool art_doread; /* search read articles? */
- #endif
-
- void artsrch_init();
- #ifdef ARTSEARCH
- int art_search();
- bool wanted(); /* return TRUE if current article matches pattern */
- #endif
- !STUFFY!FUNK!
- echo ""
- echo "End of kit 4 (of 9)"
- cat /dev/null >kit4isdone
- config=true
- for iskit in 1 2 3 4 5 6 7 8 9 ; do
- if test -f kit${iskit}isdone; then
- echo "You have run kit ${iskit}."
- else
- echo "You still need to run kit ${iskit}."
- config=false
- fi
- done
- case $config in
- true)
- echo "You have run all your kits. Please read README and then type Configure."
- chmod 755 Configure
- ;;
- esac
- : I do not append .signature, but someone might mail this.
- exit
-