home *** CD-ROM | disk | FTP | other *** search
- /* $Header: E:\SRC\UUPC\RN\RCS/INTRP.C 1.1 1992/11/21 06:14:58 ahd Exp $
- *
- * $Log: INTRP.C $
- * Revision 1.1 1992/11/21 06:14:58 ahd
- * Initial
- *
- *
- * Rev 1.0 18 Nov 1990 0:21:54
- * Initial revision.
- * 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 <stdio.h>
- #include <time.h>
-
- #include "lib.h"
- #include "importng.h"
-
- /*--------------------------------------------------------------------*/
- /* UUPC/extended include files */
- /*--------------------------------------------------------------------*/
-
- #include "pushpop.h"
-
- #ifdef msdos
- #include <process.h>
- #endif
-
- #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();
-
- /* get environmental stuff */
-
- #ifdef msdos
- if (E_organization)
- orgname = E_organization;
- #endif /* msdos */
-
- /* get home directory */
-
-
- #ifdef msdos
- if (homedir == Nullch)
- homedir = E_homedir;
- #endif /* msdos */
-
- if (homedir == Nullch)
- homedir = getenv("HOME");
-
- if (homedir == Nullch)
- homedir = getenv("LOGDIR");
-
- dotdir = getval("DOTDIR", homedir);
-
- /* get login name */
-
- if (logname == Nullch)
- logname = getenv("USER");
- if (logname == Nullch)
- logname = getenv("LOGNAME");
-
- #ifdef GETLOGIN
- if (logname == Nullch)
- logname = savestr(getlogin());
- #endif
-
- #ifdef msdos
- if (logname == Nullch)
- logname = E_mailbox;
- #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 */
- PushDir(".");
- atexit( PopDir );
- 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 */
-
- #ifdef msdos
- strcpy(tcbuf, E_name);
- #else
- strcpy(tcbuf, getrealname(getuid()));
- #endif
-
- 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;
- ImportNewsGroup( s, ngdir, 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;
- strcpy( s, 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 'J': /* tmp directory */
- s = tmpdir;
- 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
-
- #ifdef msdos
- if (E_name)
- return E_name;
- #endif /* msdos */
-
- 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);
- }
-