# 2.11BSD#431 - /usr/src/new/rn/intrp.c

##### Functions

    dointerp          X
    filexp            X
    getrealname       X
    interp            X
    intrp_init        X
    refscpy           X
    skipinterp        X

##### Variables

    hostname          X
    orgname           X
    realname          X
    uts               X

##### Macros

    SITENAME          X

       1: /* $Header: intrp.c,v 4.3.1.5.1 95/01/21 17:21:24 lwall Exp $
       2:  *
       3:  * $Log:	intrp.c,v $
       4:  * Revision 4.3.1.5  85/05/23  17:21:24  lwall
       5:  * Now allows 'r' and 'f' on null articles.
       6:  *
       7:  * Revision 4.3.1.4  85/05/21  13:35:21  lwall
       8:  * Sped up "rn -c" by not doing unnecessary initialization.
       9:  *
      10:  * Revision 4.3.1.3  85/05/17  10:37:11  lwall
      11:  * Fixed & substitution to capitalize last name too.
      12:  *
      13:  * Revision 4.3.1.2  85/05/15  14:39:45  lwall
      14:  * Spelled gecos right.
      15:  *
      16:  * Revision 4.3.1.1  85/05/10  11:33:51  lwall
      17:  * Branch for patches.
      18:  *
      19:  * Revision 4.3  85/05/01  11:40:54  lwall
      20:  * Baseline for release with 4.3bsd.
      21:  *
      22:  */
      23:
      24: #include "EXTERN.h"
      25: #include "common.h"
      26: #include "util.h"
      27: #include "search.h"
      28: #include "head.h"
      29: #include "rn.h"
      30: #include "artsrch.h"
      31: #include "ng.h"
      32: #include "util.h"
      33: #include "respond.h"
      34: #include "rcstuff.h"
      35: #include "bits.h"
      36: #include "artio.h"
      37: #include "term.h"
      38: #include "final.h"
      39: #include "INTERN.h"
      40: #include "intrp.h"
      41:
      42: char orgname[] = ORGNAME;
      43:
      44: /* name of this site */
      45: #ifdef GETHOSTNAME
      46:     char *hostname;
      47: #   undef SITENAME
      48: #   define SITENAME hostname
      49: #else !GETHOSTNAME
      50: #   ifdef DOUNAME
      51: #	include <sys/utsname.h>
      52:     struct utsname uts;
      53: #	undef SITENAME
      54: #	define SITENAME uts.nodename
      55: #   else !DOUNAME
      56: #	ifdef PHOSTNAME
      57:         char *hostname;
      58: #	    undef SITENAME
      59: #	    define SITENAME hostname
      60: #	else !PHOSTNAME
      61: #	    ifdef WHOAMI
      62: #		undef SITENAME
      63: #		define SITENAME sysname
      64: #	    endif WHOAMI
      65: #	endif PHOSTNAME
      66: #   endif DOUNAME
      67: #endif GETHOSTNAME
      68:
      69: #ifdef TILDENAME
      70: static char *tildename = Nullch;
      71: static char *tildedir = Nullch;
      72: #endif
      73:
      74: char *realname INIT(Nullch);    /* real name of sender from /etc/passwd */
      75:
      76: char *dointerp();
      77: char *getrealname();
      78: #ifdef CONDSUB
      79: char *skipinterp();
      80: #endif
      81:
      82: static void abort_interp();
      83:
      84: void
      85: intrp_init(tcbuf)
      86: char *tcbuf;
      87: {
      88:     char *getlogin();
      89:
      90:     spool = savestr(filexp(SPOOL)); /* usually /usr/spool/news */
      91:
      92:     /* get environmental stuff */
      93:
      94:     /* get home directory */
      95:
      96:     homedir = getenv("HOME");
      97:     if (homedir == Nullch)
      98:     homedir = getenv("LOGDIR");
      99:
     100:     dotdir = getval("DOTDIR",homedir);
     101:
     102:     /* get login name */
     103:
     104:     logname = getenv("USER");
     105:     if (logname == Nullch)
     106:     logname = getenv("LOGNAME");
     107: #ifdef GETLOGIN
     108:     if (logname == Nullch)
     109:     logname = savestr(getlogin());
     110: #endif
     111:
     112:     if (checkflag)          /* that getwd below takes ~1/3 sec. */
     113:     return;             /* and we do not need it for -c */
     114:     getwd(tcbuf);           /* find working directory name */
     115:     origdir = savestr(tcbuf);       /* and remember it */
     116:
     117:     /* get the real name of the person (%N) */
     118:     /* Must be done after logname is read in because BERKNAMES uses that */
     119:
     120:     strcpy(tcbuf,getrealname(getuid()));
     121:     realname = savestr(tcbuf);
     122:
     123:     /* name of header file (%h) */
     124:
     125:     headname = savestr(filexp(HEADNAME));
     126:
     127:     /* name of this site (%H) */
     128:
     129: #ifdef GETHOSTNAME
     130:     gethostname(buf,sizeof buf);
     131:     hostname = savestr(buf);
     132: #else
     133: #ifdef DOUNAME
     134:     /* get sysname */
     135:     uname(&uts);
     136: #else
     137: #ifdef PHOSTNAME
     138:     {
     139:     FILE *popen();
     140:     FILE *pipefp = popen(PHOSTNAME,"r");
     141:
     142:     if (pipefp == Nullfp) {
     143:         printf("Can't find hostname\n");
     144:         sig_catcher(0);
     145:     }
     146:     fgets(buf,sizeof buf,pipefp);
     147:     buf[strlen(buf)-1] = '\0';  /* wipe out newline */
     148:     hostname = savestr(buf);
     149:     pclose(pipefp);
     150:     }
     151: #endif
     152: #endif
     153: #endif
     154:     sitename = savestr(SITENAME);
     155: }
     156:
     157: /* expand filename via %, ~, and $ interpretation */
     158: /* returns pointer to static area */
     159: /* Note that there is a 1-deep cache of ~name interpretation */
     160:
     161: char *
     162: filexp(s)
     163: register char *s;
     164: {
     165:     static char filename[CBUFLEN];
     166:     char scrbuf[CBUFLEN];
     167:     register char *d;
     168:
     169: #ifdef DEBUGGING
     170:     if (debug & DEB_FILEXP)
     171:     printf("< %s\n",s) FLUSH;
     172: #endif
     173:     interp(filename, (sizeof filename), s);         /* interpret any % escapes */
     174: #ifdef DEBUGGING
     175:     if (debug & DEB_FILEXP)
     176:     printf("%% %s\n",filename) FLUSH;
     177: #endif
     178:     s = filename;
     179:     if (*s == '~') {    /* does destination start with ~? */
     180:     if (!*(++s) || *s == '/') {
     181:         sprintf(scrbuf,"%s%s",homedir,s);
     182:                 /* swap $HOME for it */
     183: #ifdef DEBUGGING
     184:     if (debug & DEB_FILEXP)
     185:     printf("~ %s\n",scrbuf) FLUSH;
     186: #endif
     187:         strcpy(filename,scrbuf);
     188:     }
     189:     else {
     190: #ifdef TILDENAME
     191:         for (d=scrbuf; isalnum(*s); s++,d++)
     192:         *d = *s;
     193:         *d = '\0';
     194:         if (tildedir && strEQ(tildename,scrbuf)) {
     195:         strcpy(scrbuf,tildedir);
     196:         strcat(scrbuf, s);
     197:         strcpy(filename, scrbuf);
     198: #ifdef DEBUGGING
     199:         if (debug & DEB_FILEXP)
     200:             printf("r %s %s\n",tildename,tildedir) FLUSH;
     201: #endif
     202:         }
     203:         else {
     204:         if (tildename) {
     205:             free(tildename);
     206:             free(tildedir);
     207:         }
     208:         tildedir = Nullch;
     209:         tildename = savestr(scrbuf);
     210:         {
     211:             struct passwd *getpwnam();
     212:             struct passwd *pwd = getpwnam(tildename);
     213:
     214:             sprintf(scrbuf,"%s%s",pwd->pw_dir,s);
     215:             tildedir = savestr(pwd->pw_dir);
     216: #ifdef NEWSADMIN
     217:             if (strEQ(newsadmin,tildename))
     218:             newsuid = atoi(pwd->pw_uid);
     219: #endif
     220:             strcpy(filename,scrbuf);
     221:             endpwent();
     222:         }
     223:         }
     224: #else !TILDENAME
     225: #ifdef VERBOSE
     226:         IF(verbose)
     227:         fputs("~loginname not implemented.\n",stdout) FLUSH;
     228:         ELSE
     229: #endif
     230: #ifdef TERSE
     231:         fputs("~login not impl.\n",stdout) FLUSH;
     232: #endif
     233: #endif
     234:     }
     235:     }
     236:     else if (*s == '$') {   /* starts with some env variable? */
     237:     d = scrbuf;
     238:     *d++ = '%';
     239:     if (s[1] == '{')
     240:         strcpy(d,s+2);
     241:     else {
     242:         *d++ = '{';
     243:         for (s++; isalnum(*s); s++) *d++ = *s;
     244:                 /* skip over token */
     245:         *d++ = '}';
     246:         strcpy(d,s);
     247:     }
     248: #ifdef DEBUGGING
     249:     if (debug & DEB_FILEXP)
     250:         printf("$ %s\n",scrbuf) FLUSH;
     251: #endif
     252:     interp(filename, (sizeof filename), scrbuf);
     253:                     /* this might do some extra '%'s but */
     254:                     /* that is how the Mercedes Benz */
     255:     }
     256: #ifdef DEBUGGING
     257:     if (debug & DEB_FILEXP)
     258:     printf("> %s\n",filename) FLUSH;
     259: #endif
     260:     return filename;
     261: }
     262:
     263: #ifdef CONDSUB
     264: /* skip interpolations */
     265:
     266: char *
     267: skipinterp(pattern,stoppers)
     268: register char *pattern;
     269: char *stoppers;
     270: {
     271:
     272:     while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
     273: #ifdef DEBUGGING
     274:     if (debug & 8)
     275:         printf("skipinterp till %s at %s\n",stoppers?stoppers:"",pattern);
     276: #endif
     277:     if (*pattern == '%' && pattern[1]) {
     278:         switch (*++pattern) {
     279:         case '{':
     280:         for (pattern++; *pattern && *pattern != '}'; pattern++)
     281:             if (*pattern == '\\')
     282:             pattern++;
     283:         break;
     284:         case '[':
     285:         for (pattern++; *pattern && *pattern != ']'; pattern++)
     286:             if (*pattern == '\\')
     287:             pattern++;
     288:         break;
     289: #ifdef CONDSUB
     290:         case '(': {
     291:         pattern = skipinterp(pattern+1,"!=");
     292:         if (!*pattern)
     293:             goto getout;
     294:         for (pattern++; *pattern && *pattern != '?'; pattern++)
     295:             if (*pattern == '\\')
     296:             pattern++;
     297:         if (!*pattern)
     298:             goto getout;
     299:         pattern = skipinterp(pattern+1,":)");
     300:         if (*pattern == ':')
     301:             pattern = skipinterp(pattern+1,")");
     302:         break;
     303:         }
     304: #endif
     305: #ifdef BACKTICK
     306:         case '`': {
     307:         pattern = skipinterp(pattern+1,"`");
     308:         break;
     309:         }
     310: #endif
     311: #ifdef PROMPTTTY
     312:         case '"':
     313:         pattern = skipinterp(pattern+1,"\"");
     314:         break;
     315: #endif
     316:         default:
     317:         break;
     318:         }
     319:         pattern++;
     320:     }
     321:     else {
     322:         if (*pattern == '^' && pattern[1])
     323:         pattern += 2;
     324:         else if (*pattern == '\\' && pattern[1])
     325:         pattern += 2;
     326:         else
     327:         pattern++;
     328:     }
     329:     }
     330: getout:
     331:     return pattern;         /* where we left off */
     332: }
     333: #endif
     334:
     335: /* interpret interpolations */
     336:
     337: char *
     338: dointerp(dest,destsize,pattern,stoppers)
     339: register char *dest;
     340: register int destsize;
     341: register char *pattern;
     342: char *stoppers;
     343: {
     344:     char *subj_buf = Nullch;
     345:     char *ngs_buf = Nullch;
     346:     char *refs_buf = Nullch;
     347:     char *artid_buf = Nullch;
     348:     char *reply_buf = Nullch;
     349:     char *from_buf = Nullch;
     350:     char *path_buf = Nullch;
     351:     char *follow_buf = Nullch;
     352:     char *dist_buf = Nullch;
     353:     char *line_buf = Nullch;
     354:     register char *s, *h;
     355:     register int i;
     356:     char scrbuf[512];
     357:     bool upper = FALSE;
     358:     bool lastcomp = FALSE;
     359:     int metabit = 0;
     360:
     361:     while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
     362: #ifdef DEBUGGING
     363:     if (debug & 8)
     364:         printf("dointerp till %s at %s\n",stoppers?stoppers:"",pattern);
     365: #endif
     366:     if (*pattern == '%' && pattern[1]) {
     367:         upper = FALSE;
     368:         lastcomp = FALSE;
     369:         for (s=Nullch; !s; ) {
     370:         switch (*++pattern) {
     371:         case '^':
     372:             upper = TRUE;
     373:             break;
     374:         case '_':
     375:             lastcomp = TRUE;
     376:             break;
     377:         case '/':
     378: #ifdef ARTSRCH
     379:             s = scrbuf;
     380:             if (!index("/?g",pattern[-2]))
     381:             *s++ = '/';
     382:             strcpy(s,lastpat);
     383:             s += strlen(s);
     384:             if (pattern[-2] != 'g') {
     385:             if (index("/?",pattern[-2]))
     386:                 *s++ = pattern[-2];
     387:             else
     388:                 *s++ = '/';
     389:             if (art_howmuch == 1)
     390:                 *s++ = 'h';
     391:             else if (art_howmuch == 2)
     392:                 *s++ = 'a';
     393:             if (art_doread)
     394:                 *s++ = 'r';
     395:             }
     396:             *s = '\0';
     397:             s = scrbuf;
     398: #else
     399:             s = nullstr;
     400: #endif
     401:             break;
     402:         case '{':
     403:             pattern = cpytill(scrbuf,pattern+1,'}');
     404:             if (s = index(scrbuf,'-'))
     405:             *s++ = '\0';
     406:             else
     407:             s = nullstr;
     408:             s = getval(scrbuf,s);
     409:             break;
     410:         case '[':
     411:             pattern = cpytill(scrbuf,pattern+1,']');
     412:             i = set_line_type(scrbuf,scrbuf+strlen(scrbuf));
     413:             if (line_buf)
     414:             free(line_buf);
     415:             s = line_buf = fetchlines(art,i);
     416:             break;
     417: #ifdef CONDSUB
     418:         case '(': {
     419:             COMPEX *oldbra_compex = bra_compex;
     420:             COMPEX cond_compex;
     421:             char rch;
     422:             bool matched;
     423:
     424:             init_compex(&cond_compex);
     425:             pattern = dointerp(dest,destsize,pattern+1,"!=");
     426:             rch = *pattern;
     427:             if (rch == '!')
     428:             pattern++;
     429:             if (*pattern != '=')
     430:             goto getout;
     431:             pattern = cpytill(scrbuf,pattern+1,'?');
     432:             if (!*pattern)
     433:             goto getout;
     434:             if (s = compile(&cond_compex,scrbuf,TRUE,TRUE)) {
     435:             printf("%s: %s\n",scrbuf,s) FLUSH;
     436:             pattern += strlen(pattern);
     437:             goto getout;
     438:             }
     439:             matched = (execute(&cond_compex,dest) != Nullch);
     440:             if (cond_compex.nbra)   /* were there brackets? */
     441:             bra_compex = &cond_compex;
     442:             if (matched==(rch == '=')) {
     443:             pattern = dointerp(dest,destsize,pattern+1,":)");
     444:             if (*pattern == ':')
     445:                 pattern = skipinterp(pattern+1,")");
     446:             }
     447:             else {
     448:             pattern = skipinterp(pattern+1,":)");
     449:             if (*pattern == ':')
     450:                 pattern++;
     451:             pattern = dointerp(dest,destsize,pattern,")");
     452:             }
     453:             s = dest;
     454:             bra_compex = oldbra_compex;
     455:             free_compex(&cond_compex);
     456:             break;
     457:         }
     458: #endif
     459: #ifdef BACKTICK
     460:         case '`': {
     461:             FILE *pipefp, *popen();
     462:
     463:             pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"`");
     464:             pipefp = popen(scrbuf,"r");
     465:             if (pipefp != Nullfp) {
     466:             int len;
     467:
     468:             len = fread(scrbuf,sizeof(char),(sizeof scrbuf)-1,
     469:                 pipefp);
     470:             scrbuf[len] = '\0';
     471:             pclose(pipefp);
     472:             }
     473:             else {
     474:             printf("\nCan't run %s\n",scrbuf);
     475:             *scrbuf = '\0';
     476:             }
     477:             for (s=scrbuf; *s; s++) {
     478:             if (*s == '\n') {
     479:                 if (s[1])
     480:                 *s = ' ';
     481:                 else
     482:                 *s = '\0';
     483:             }
     484:             }
     485:             s = scrbuf;
     486:             break;
     487:         }
     488: #endif
     489: #ifdef PROMPTTTY
     490:         case '"':
     491:             pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"\"");
     492:             fputs(scrbuf,stdout) FLUSH;
     493:             resetty();
     494:             gets(scrbuf);
     495:             noecho();
     496:             crmode();
     497:             s = scrbuf;
     498:             break;
     499: #endif
     500:         case '~':
     501:             s = homedir;
     502:             break;
     503:         case '.':
     504:             s = dotdir;
     505:             break;
     506:         case '$':
     507:             s = scrbuf;
     508:             sprintf(s,"%d",getpid());
     509:             break;
     510:         case '0': case '1': case '2': case '3': case '4':
     511:         case '5': case '6': case '7': case '8': case '9':
     512: #ifdef CONDSUB
     513:             s = getbracket(bra_compex,*pattern - '0');
     514: #else
     515:             s = nullstr;
     516: #endif
     517:             break;
     518:         case 'a':
     519:             s = scrbuf;
     520:             sprintf(s,"%ld",(long)art);
     521:             break;
     522:         case 'A':
     523: #ifdef LINKART
     524:             s = linkartname;    /* so Eunice people get right file */
     525: #else
     526:             s = scrbuf;
     527:             sprintf(s,"%s/%s/%ld",spool,ngdir,(long)art);
     528: #endif
     529:             break;
     530:         case 'b':
     531:             s = savedest;
     532:             break;
     533:         case 'B':
     534:             s = scrbuf;
     535:             sprintf(s,"%ld",(long)savefrom);
     536:             break;
     537:         case 'c':
     538:             s = ngdir;
     539:             break;
     540:         case 'C':
     541:             s = ngname;
     542:             break;
     543:         case 'd':
     544:             s = scrbuf;
     545:             sprintf(s,"%s/%s",spool,ngdir);
     546:             break;
     547:         case 'D':
     548:             s = dist_buf = fetchlines(art,DIST_LINE);
     549:             break;
     550:         case 'f':           /* from line */
     551: #ifdef ASYNC_PARSE
     552:             parse_maybe(art);
     553: #endif
     554:             if (htype[REPLY_LINE].ht_minpos >= 0) {
     555:                         /* was there a reply line? */
     556:             if (!(s=reply_buf))
     557:                 s = reply_buf = fetchlines(art,REPLY_LINE);
     558:             }
     559:             else if (!(s = from_buf))
     560:             s = from_buf = fetchlines(art,FROM_LINE);
     561:             break;
     562:         case 'F':
     563: #ifdef ASYNC_PARSE
     564:             parse_maybe(art);
     565: #endif
     566:             if (htype[FOLLOW_LINE].ht_minpos >= 0)
     567:                     /* is there a Followup-To line? */
     568:             s = follow_buf = fetchlines(art,FOLLOW_LINE);
     569:             else {
     570:             int off;
     571:
     572:             s = ngs_buf = fetchlines(art,NGS_LINE);
     573:             if (h = instr(s,"net.general")) {
     574:                 off = h-s;
     575:                 strncpy(scrbuf,s,off+4);
     576:                 strcpy(scrbuf+off+4,"followup");
     577:                 safecpy(scrbuf+off+12,h+11,sizeof(scrbuf));
     578:                 s = scrbuf;
     579:             }
     580:             }
     581:             break;
     582:         case 'h':           /* header file name */
     583:             s = headname;
     584:             break;
     585:         case 'H':           /* host name */
     586:             s = sitename;
     587:             break;
     588:         case 'i':
     589:             if (!(s=artid_buf))
     590:             s = artid_buf = fetchlines(art,MESSID_LINE);
     591:             if (*s && *s != '<') {
     592:             sprintf(scrbuf,"<%s>",artid_buf);
     593:             s = scrbuf;
     594:             }
     595:             break;
     596:         case 'I':           /* ref article indicator */
     597:             s = scrbuf;
     598:             sprintf(scrbuf,"'%s'",indstr);
     599:             break;
     600:         case 'l':           /* rn library */
     601: #ifdef NEWSADMIN
     602:             s = newsadmin;
     603: #else
     604:             s = "???";
     605: #endif
     606:             break;
     607:         case 'L':           /* login id */
     608:             s = logname;
     609:             break;
     610:         case 'm':       /* current mode */
     611:             s = scrbuf;
     612:             *s = mode;
     613:             s[1] = '\0';
     614:             break;
     615:         case 'M':
     616: #ifdef DELAYMARK
     617:             sprintf(scrbuf,"%ld",(long)dmcount);
     618:             s = scrbuf;
     619: #else
     620:             s = nullstr;
     621: #endif
     622:             break;
     623:         case 'n':           /* newsgroups */
     624:             s = ngs_buf = fetchlines(art,NGS_LINE);
     625:             break;
     626:         case 'N':           /* full name */
     627:             s = getval("NAME",realname);
     628:             break;
     629:         case 'o':           /* organization */
     630:             s = getval("ORGANIZATION",orgname);
     631: #ifdef ORGFILE
     632:             if (*s == '/') {
     633:             FILE *ofp = fopen(s,"r");
     634:
     635:             if (ofp) {
     636:                 fgets(scrbuf,sizeof scrbuf,ofp);
     637:                 fclose(ofp);
     638:                 s = scrbuf;
     639:                 s[strlen(s)-1] = '\0';
     640:             }
     641:             }
     642: #endif
     643:             break;
     644:         case 'O':
     645:             s = origdir;
     646:             break;
     647:         case 'p':
     648:             s = cwd;
     649:             break;
     650:         case 'P':
     651:             s = spool;
     652:             break;
     653:         case 'r':
     654: #ifdef ASYNC_PARSE
     655:             parse_maybe(art);
     656: #endif
     657:             if (htype[REFS_LINE].ht_minpos >= 0) {
     658:             refs_buf = fetchlines(art,REFS_LINE);
     659:             refscpy(scrbuf,(sizeof scrbuf),refs_buf);
     660:             }
     661:             else
     662:             *scrbuf = '\0';
     663:             s = rindex(scrbuf,'<');
     664:             break;
     665:         case 'R':
     666: #ifdef ASYNC_PARSE
     667:             parse_maybe(art);
     668: #endif
     669:             if (htype[REFS_LINE].ht_minpos >= 0) {
     670:             refs_buf = fetchlines(art,REFS_LINE);
     671:             refscpy(scrbuf,(sizeof scrbuf),refs_buf);
     672:             }
     673:             else
     674:             *scrbuf = '\0';
     675:             if (!artid_buf)
     676:             artid_buf = fetchlines(art,MESSID_LINE);
     677:             if (artid_buf[0] == '<')
     678:             safecat(scrbuf,artid_buf,sizeof(scrbuf));
     679:             else if (artid_buf[0]) {
     680:             char tmpbuf[64];
     681:
     682:             sprintf(tmpbuf,"<%s>",artid_buf);
     683:             safecat(scrbuf,tmpbuf,sizeof(scrbuf));
     684:             }
     685:             s = scrbuf;
     686:             break;
     687:         case 's':
     688:             if (!(s=subj_buf))
     689:             s = subj_buf = fetchsubj(art,TRUE,TRUE);
     690:                         /* get subject handy */
     691:             while ((*s=='R'||*s=='r')&&(s[1]=='E'||s[1]=='e')&&s[2]==':') {
     692:                         /* skip extra Re: */
     693:             s += 3;
     694:             if (*s == ' ')
     695:                 s++;
     696:             }
     697:             if (h = instr(s,"- (nf"))
     698:             *h = '\0';
     699:             break;
     700:         case 'S':
     701:             if (!(s=subj_buf))
     702:             s = subj_buf = fetchsubj(art,TRUE,TRUE);
     703:                         /* get subject handy */
     704:             if ((*s=='R'||*s=='r')&&(s[1]=='E'||s[1]=='e')&&s[2]==':') {
     705:                         /* skip extra Re: */
     706:             s += 3;
     707:             if (*s == ' ')
     708:                 s++;
     709:             }
     710:             break;
     711:         case 't':
     712:         case 'T':
     713: #ifdef ASYNC_PARSE
     714:             parse_maybe(art);
     715: #endif
     716:             if (htype[REPLY_LINE].ht_minpos >= 0) {
     717:                     /* was there a reply line? */
     718:             if (!(s=reply_buf))
     719:                 s = reply_buf = fetchlines(art,REPLY_LINE);
     720:             }
     721:             else if (!(s = from_buf))
     722:             s = from_buf = fetchlines(art,FROM_LINE);
     723:             if (*pattern == 'T') {
     724:             if (htype[PATH_LINE].ht_minpos >= 0) {
     725:                     /* should we substitute path? */
     726:                 s = path_buf = fetchlines(art,PATH_LINE);
     727:             }
     728:             i = strlen(sitename);
     729:             if (strnEQ(sitename,s,i) && s[i] == '!')
     730:                 s += i + 1;
     731:             }
     732:             if ((h=index(s,'(')) != Nullch)
     733:                         /* strip garbage from end */
     734:             *(h-1) = '\0';
     735:             else if ((h=index(s,'<')) != Nullch) {
     736:                         /* or perhaps from beginning */
     737:             s = h+1;
     738:             if ((h=index(s,'>')) != Nullch)
     739:                 *h = '\0';
     740:             }
     741:             break;
     742:         case 'u':
     743:             sprintf(scrbuf,"%ld",(long)toread[ng]);
     744:             s = scrbuf;
     745:             break;
     746:         case 'U':
     747:             sprintf(scrbuf,"%ld",
     748:             (long)(((ART_NUM)toread[ng]) - 1 + was_read(art)));
     749:             s = scrbuf;
     750:             break;
     751:         case 'x':           /* news library */
     752:             s = lib;
     753:             break;
     754:         case 'X':           /* rn library */
     755:             s = rnlib;
     756:             break;
     757:         case 'z':
     758: #ifdef LINKART
     759:             s = linkartname;    /* so Eunice people get right file */
     760: #else
     761:             s = scrbuf;
     762:             sprintf(s,"%ld",(long)art);
     763: #endif
     764:             if (stat(s,&filestat) < 0)
     765:             filestat.st_size = 0L;
     766:             sprintf(scrbuf,"%5ld",(long)filestat.st_size);
     767:             s = scrbuf;
     768:             break;
     769:         default:
     770:             if (--destsize <= 0)
     771:             abort_interp();
     772:             *dest++ = *pattern | metabit;
     773:             s = nullstr;
     774:             break;
     775:         }
     776:         }
     777:         if (!s)
     778:         s = nullstr;
     779:         pattern++;
     780:         if (upper || lastcomp) {
     781:         char *t;
     782:
     783:         if (s != scrbuf) {
     784:             safecpy(scrbuf,s,(sizeof scrbuf));
     785:             s = scrbuf;
     786:         }
     787:         if (upper || !(t=rindex(s,'/')))
     788:             t = s;
     789:         while (*t && !isalpha(*t))
     790:             t++;
     791:         if (islower(*t))
     792:             *t = toupper(*t);
     793:         }
     794:         i = metabit;        /* maybe get into register */
     795:         if (s == dest) {
     796:         while (*dest) {
     797:             if (--destsize <= 0)
     798:             abort_interp();
     799:             *dest++ |= i;
     800:         }
     801:         }
     802:         else {
     803:         while (*s) {
     804:             if (--destsize <= 0)
     805:             abort_interp();
     806:             *dest++ = *s++ | i;
     807:         }
     808:         }
     809:     }
     810:     else {
     811:         if (--destsize <= 0)
     812:         abort_interp();
     813:         if (*pattern == '^' && pattern[1]) {
     814:         ++pattern;          /* skip uparrow */
     815:         i = *pattern;       /* get char into a register */
     816:         if (i == '?')
     817:             *dest++ = '\177' | metabit;
     818:         else if (i == '(') {
     819:             metabit = 0200;
     820:             destsize++;
     821:         }
     822:         else if (i == ')') {
     823:             metabit = 0;
     824:             destsize++;
     825:         }
     826:         else
     827:             *dest++ = i & 037 | metabit;
     828:         pattern++;
     829:         }
     830:         else if (*pattern == '\\' && pattern[1]) {
     831:         ++pattern;          /* skip backslash */
     832:         i = *pattern;       /* get char into a register */
     833:
     834:         /* this used to be a switch but the if may save space */
     835:
     836:         if (i >= '0' && i <= '7') {
     837:             i = 1;
     838:             while (i < 01000 && *pattern >= '0' && *pattern <= '7') {
     839:             i <<= 3;
     840:             i += *pattern++ - '0';
     841:             }
     842:             *dest++ = i & 0377 | metabit;
     843:             --pattern;
     844:         }
     845:         else if (i == 'b')
     846:             *dest++ = '\b' | metabit;
     847:         else if (i == 'f')
     848:             *dest++ = '\f' | metabit;
     849:         else if (i == 'n')
     850:             *dest++ = '\n' | metabit;
     851:         else if (i == 'r')
     852:             *dest++ = '\r' | metabit;
     853:         else if (i == 't')
     854:             *dest++ = '\t' | metabit;
     855:         else
     856:             *dest++ = i | metabit;
     857:         pattern++;
     858:         }
     859:         else
     860:         *dest++ = *pattern++ | metabit;
     861:     }
     862:     }
     863:     *dest = '\0';
     864: getout:
     865:     if (subj_buf != Nullch) /* return any checked out storage */
     866:     free(subj_buf);
     867:     if (ngs_buf != Nullch)
     868:     free(ngs_buf);
     869:     if (refs_buf != Nullch)
     870:     free(refs_buf);
     871:     if (artid_buf != Nullch)
     872:     free(artid_buf);
     873:     if (reply_buf != Nullch)
     874:     free(reply_buf);
     875:     if (from_buf != Nullch)
     876:     free(from_buf);
     877:     if (path_buf != Nullch)
     878:     free(path_buf);
     879:     if (follow_buf != Nullch)
     880:     free(follow_buf);
     881:     if (dist_buf != Nullch)
     882:     free(dist_buf);
     883:     if (line_buf != Nullch)
     884:     free(line_buf);
     885:     return pattern;         /* where we left off */
     886: }
     887:
     888: void
     889: interp(dest,destsize,pattern)
     890: char *dest;
     891: int destsize;
     892: char *pattern;
     893: {
     894:     dointerp(dest,destsize,pattern,Nullch);
     895: #ifdef DEBUGGING
     896:     if (debug & DEB_FILEXP)
     897:     fputs(dest,stdout);
     898: #endif
     899: }
     900:
     901: /* copy a references line, normalizing as we go */
     902:
     903: void
     904: refscpy(dest,destsize,src)
     905: register char *dest, *src;
     906: register int destsize;
     907: {
     908:     register char *dot, *at, *beg;
     909:     char tmpbuf[64];
     910:
     911:     while (*src) {
     912:     if (*src != '<') {
     913:         if (--destsize <= 0)
     914:         break;
     915:         *dest++ = '<';
     916:         at = dot = Nullch;
     917:         beg = src;
     918:         while (*src && *src != ' ' && *src != ',') {
     919:         if (*src == '.')
     920:             dot = src;
     921:         else if (*src == '@')
     922:             at = src;
     923:         if (--destsize <= 0)
     924:             break;
     925:         *dest++ = *src++;
     926:         }
     927:         if (destsize <= 0)
     928:         break;
     929:         if (dot && !at) {
     930:         int len;
     931:
     932:         *dest = *dot++ = '\0';
     933:         sprintf(tmpbuf,"%s@%s.UUCP",dot,beg);
     934:         len = strlen(tmpbuf);
     935:         if (destsize > len) {
     936:             strcpy(dest,tmpbuf);
     937:             dest = dest + len;
     938:             destsize -= len;
     939:         }
     940:         }
     941:         if (--destsize <= 0)
     942:         break;
     943:         *dest++ = '>';
     944:     }
     945:     else {
     946:         while (*src && --destsize > 0 && (*dest++ = *src++) != '>') ;
     947:         if (destsize <= 0)
     948:         break;
     949:     }
     950:     while (*src == ' ' || *src == ',') src++;
     951:     if (*src && --destsize > 0)
     952:         *dest++ = ' ';
     953:     }
     954:     *dest = '\0';
     955: }
     956:
     957: /* get the person's real name from /etc/passwd */
     958: /* (string is overwritten, so it must be copied) */
     959:
     960: char *
     961: getrealname(uid)
     962: int uid;
     963: {
     964:     char *s, *c;
     965:
     966: #ifdef PASSNAMES
     967:     struct passwd *pwd = getpwuid(uid);
     968:
     969:     s = pwd->pw_gecos;
     970: #ifdef BERKNAMES
     971: #ifdef BERKJUNK
     972:     while (*s && !isalnum(*s) && *s != '&') s++;
     973: #endif
     974:     if ((c = index(s, ',')) != Nullch)
     975:     *c = '\0';
     976:     if ((c = index(s, ';')) != Nullch)
     977:     *c = '\0';
     978:     s = cpytill(buf,s,'&');
     979:     if (*s == '&') {            /* whoever thought this one up was */
     980:     c = buf + strlen(buf);      /* in the middle of the night */
     981:     strcat(c,logname);      /* before the morning after */
     982:     strcat(c,s+1);
     983:     if (islower(*c))
     984:         *c = toupper(*c);       /* gack and double gack */
     985:     }
     986: #else
     987:     if ((c = index(s, '(')) != Nullch)
     988:     *c = '\0';
     989:     if ((c = index(s, '-')) != Nullch)
     990:     s = c;
     991:     strcpy(buf,tmpbuf);
     992: #endif
     993:     endpwent();
     994:     return buf;             /* return something static */
     995: #else
     996:     if ((tmpfp=fopen(filexp(FULLNAMEFILE),"r")) != Nullfp) {
     997:     fgets(buf,sizeof buf,tmpfp);
     998:     fclose(tmpfp);
     999:     buf[strlen(buf)-1] = '\0';
    1000:     return buf;
    1001:     }
    1002:     return "PUT YOUR NAME HERE";
    1003: #endif
    1004: }
    1005:
    1006: static void
    1007: abort_interp()
    1008: {
    1009:     fputs("\n% interp buffer overflow!\n",stdout) FLUSH;
    1010:     sig_catcher(0);
    1011: }

#### Defined functions

abort_interp defined in line 1006; used 5 times

- in line 82, 771, 798, 805, 812

dointerp defined in line 337; used 10 times

- in line 76, 425, 443, 451, 463, 491, 894
- in /usr/src/new/rn/intrp.h line 24
- in /usr/src/new/rn/ngstuff.c line 282
- in /usr/src/new/rn/term.c line 279

filexp defined in line 161; used 49 times

- in line 90, 125, 996
- in /usr/src/new/rn/addng.c line 53
- in /usr/src/new/rn/backpage.c line 24
- in /usr/src/new/rn/bits.c line 51, 343-344(2)
- in /usr/src/new/rn/help.c line 34, 89, 172, 246
- in /usr/src/new/rn/init.c line 82-83(2), 255, 329
- in /usr/src/new/rn/intrp.h line 23
- in /usr/src/new/rn/kfile.c line 188, 212-217(3), 235, 259
- in /usr/src/new/rn/last.c line 23
- in /usr/src/new/rn/ng.c line 1009
- in /usr/src/new/rn/ngdata.c line 51-55(2), 70-75(2)
- in /usr/src/new/rn/rcstuff.c line 71-83(6), 908, 967-969(2)
- in /usr/src/new/rn/respond.c line 84, 116, 222, 303, 317, 390
- in /usr/src/new/rn/rn.c line 439
- in /usr/src/new/rn/sw.c line 457-460(2)
- in /usr/src/new/rn/term.c line 252
- in /usr/src/new/rn/util.c line 436

getrealname defined in line 960; used 3 times

- in line 77, 120
- in /usr/src/new/rn/intrp.h line 27

interp defined in line 888; used 23 times

- in line 173, 252
- in /usr/src/new/rn/art.c line 135
- in /usr/src/new/rn/artsrch.c line 119
- in /usr/src/new/rn/cheat.c line 55
- in /usr/src/new/rn/intrp.h line 25
- in /usr/src/new/rn/ng.c line 851, 867
- in /usr/src/new/rn/ngstuff.c line 61
- in /usr/src/new/rn/respond.c line 86, 119, 136, 300, 325, 338, 350, 368, 378
- in /usr/src/new/rn/sw.c line 36, 462
- in /usr/src/new/rn/term.c line 457, 464, 794

intrp_init defined in line 84; used 2 times

- in /usr/src/new/rn/init.c line 96
- in /usr/src/new/rn/intrp.h line 22

refscpy defined in line 903; used 3 times

- in line 659, 671
- in /usr/src/new/rn/intrp.h line 26

skipinterp defined in line 266; used 8 times

- in line 79, 291, 299-301(2), 307, 313, 445-448(2)

#### Defined variables

hostname defined in line 57; used 4 times

- in line 48, 59, 131, 148

orgname defined in line 42; used 1 times

- in line 630

realname defined in line 74; used 2 times

- in line 121, 627

tildedir defined in line 71; used 6 times

- in line 194-200(3), 206-208(2), 215

tildename defined in line 70; used 7 times

- in line 194, 200-217(6)

uts defined in line 52; used 2 times

- in line 54, 135

#### Defined macros

SITENAME defined in line 63; used 5 times

- in line 47, 53-62(3), 154

Last modified: 1995-01-22 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 2064 |