Annotation of 43BSD/contrib/rn/intrp.c, revision 1.1.1.1

1.1       root        1: /* $Header: intrp.c,v 4.3.1.5 85/05/23 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: #ifdef GETPWENT                /* getpwnam() is not the paragon of efficiency */
                    211:                {
                    212:                    struct passwd *getpwnam();
                    213:                    struct passwd *pwd = getpwnam(tildename);
                    214: 
                    215:                    sprintf(scrbuf,"%s%s",pwd->pw_dir,s);
                    216:                    tildedir = savestr(pwd->pw_dir);
                    217: #ifdef NEWSADMIN
                    218:                    if (strEQ(newsadmin,tildename))
                    219:                        newsuid = atoi(pwd->pw_uid);
                    220: #endif
                    221:                    strcpy(filename,scrbuf);
                    222: #ifdef GETPWENT
                    223:                    endpwent();
                    224: #endif
                    225:                }
                    226: #else                  /* this will run faster, and is less D space */
                    227:                {       /* just be sure LOGDIRFIELD is correct */
                    228:                    FILE *pfp = fopen("/etc/passwd","r");
                    229:                    char tmpbuf[512];
                    230:                    int i;
                    231:                    
                    232:                    if (pfp == Nullfp) {
                    233:                        printf(cantopen,"passwd") FLUSH;
                    234:                        sig_catcher(0);
                    235:                    }
                    236:                    while (fgets(tmpbuf,512,pfp) != Nullch) {
                    237:                        d = cpytill(scrbuf,tmpbuf,':');
                    238: #ifdef DEBUGGING
                    239:                        if (debug & DEB_FILEXP)
                    240:                            printf("p %s\n",tmpbuf) FLUSH;
                    241: #endif
                    242:                        if (strEQ(scrbuf,tildename)) {
                    243: #ifdef NEWSADMIN
                    244:                            if (strEQ(newsadmin,tildename))
                    245:                                newsuid = atoi(index(d,':')+1);
                    246: #endif
                    247:                            for (i=LOGDIRFIELD-2; i; i--) {
                    248:                                if (d)
                    249:                                    d = index(d+1,':');
                    250:                            }
                    251:                            if (d) {
                    252:                                cpytill(scrbuf,d+1,':');
                    253:                                tildedir = savestr(scrbuf);
                    254:                                strcat(scrbuf,s);
                    255:                                strcpy(filename,scrbuf);
                    256:                            }
                    257:                            break;
                    258:                        }
                    259:                    }
                    260:                    fclose(pfp);
                    261:                }
                    262: #endif
                    263:            }
                    264: #else !TILDENAME
                    265: #ifdef VERBOSE
                    266:            IF(verbose)
                    267:                fputs("~loginname not implemented.\n",stdout) FLUSH;
                    268:            ELSE
                    269: #endif
                    270: #ifdef TERSE
                    271:                fputs("~login not impl.\n",stdout) FLUSH;
                    272: #endif
                    273: #endif
                    274:        }
                    275:     }
                    276:     else if (*s == '$') {      /* starts with some env variable? */
                    277:        d = scrbuf;
                    278:        *d++ = '%';
                    279:        if (s[1] == '{')
                    280:            strcpy(d,s+2);
                    281:        else {
                    282:            *d++ = '{';
                    283:            for (s++; isalnum(*s); s++) *d++ = *s;
                    284:                                /* skip over token */
                    285:            *d++ = '}';
                    286:            strcpy(d,s);
                    287:        }
                    288: #ifdef DEBUGGING
                    289:        if (debug & DEB_FILEXP)
                    290:            printf("$ %s\n",scrbuf) FLUSH;
                    291: #endif
                    292:        interp(filename, (sizeof filename), scrbuf);
                    293:                                        /* this might do some extra '%'s but */
                    294:                                        /* that is how the Mercedes Benz */
                    295:     }
                    296: #ifdef DEBUGGING
                    297:     if (debug & DEB_FILEXP)
                    298:        printf("> %s\n",filename) FLUSH;
                    299: #endif
                    300:     return filename;
                    301: }
                    302: 
                    303: #ifdef CONDSUB
                    304: /* skip interpolations */
                    305: 
                    306: char *
                    307: skipinterp(pattern,stoppers)
                    308: register char *pattern;
                    309: char *stoppers;
                    310: {
                    311: 
                    312:     while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
                    313: #ifdef DEBUGGING
                    314:        if (debug & 8)
                    315:            printf("skipinterp till %s at %s\n",stoppers?stoppers:"",pattern);
                    316: #endif
                    317:        if (*pattern == '%' && pattern[1]) {
                    318:            switch (*++pattern) {
                    319:            case '{':
                    320:                for (pattern++; *pattern && *pattern != '}'; pattern++)
                    321:                    if (*pattern == '\\')
                    322:                        pattern++;
                    323:                break;
                    324:            case '[':
                    325:                for (pattern++; *pattern && *pattern != ']'; pattern++)
                    326:                    if (*pattern == '\\')
                    327:                        pattern++;
                    328:                break;
                    329: #ifdef CONDSUB
                    330:            case '(': {
                    331:                pattern = skipinterp(pattern+1,"!=");
                    332:                if (!*pattern)
                    333:                    goto getout;
                    334:                for (pattern++; *pattern && *pattern != '?'; pattern++)
                    335:                    if (*pattern == '\\')
                    336:                        pattern++;
                    337:                if (!*pattern)
                    338:                    goto getout;
                    339:                pattern = skipinterp(pattern+1,":)");
                    340:                if (*pattern == ':')
                    341:                    pattern = skipinterp(pattern+1,")");
                    342:                break;
                    343:            }
                    344: #endif
                    345: #ifdef BACKTICK
                    346:            case '`': {
                    347:                pattern = skipinterp(pattern+1,"`");
                    348:                break;
                    349:            }
                    350: #endif
                    351: #ifdef PROMPTTTY
                    352:            case '"':
                    353:                pattern = skipinterp(pattern+1,"\"");
                    354:                break;
                    355: #endif
                    356:            default:
                    357:                break;
                    358:            }
                    359:            pattern++;
                    360:        }
                    361:        else {
                    362:            if (*pattern == '^' && pattern[1])
                    363:                pattern += 2;
                    364:            else if (*pattern == '\\' && pattern[1])
                    365:                pattern += 2;
                    366:            else
                    367:                pattern++;
                    368:        }
                    369:     }
                    370: getout:
                    371:     return pattern;                    /* where we left off */
                    372: }
                    373: #endif
                    374: 
                    375: /* interpret interpolations */
                    376: 
                    377: char *
                    378: dointerp(dest,destsize,pattern,stoppers)
                    379: register char *dest;
                    380: register int destsize;
                    381: register char *pattern;
                    382: char *stoppers;
                    383: {
                    384:     char *subj_buf = Nullch;
                    385:     char *ngs_buf = Nullch;
                    386:     char *refs_buf = Nullch;
                    387:     char *artid_buf = Nullch;
                    388:     char *reply_buf = Nullch;
                    389:     char *from_buf = Nullch;
                    390:     char *path_buf = Nullch;
                    391:     char *follow_buf = Nullch;
                    392:     char *dist_buf = Nullch;
                    393:     char *line_buf = Nullch;
                    394:     register char *s, *h;
                    395:     register int i;
                    396:     char scrbuf[512];
                    397:     bool upper = FALSE;
                    398:     bool lastcomp = FALSE;
                    399:     int metabit = 0;
                    400: 
                    401:     while (*pattern && (!stoppers || !index(stoppers,*pattern))) {
                    402: #ifdef DEBUGGING
                    403:        if (debug & 8)
                    404:            printf("dointerp till %s at %s\n",stoppers?stoppers:"",pattern);
                    405: #endif
                    406:        if (*pattern == '%' && pattern[1]) {
                    407:            upper = FALSE;
                    408:            lastcomp = FALSE;
                    409:            for (s=Nullch; !s; ) {
                    410:                switch (*++pattern) {
                    411:                case '^':
                    412:                    upper = TRUE;
                    413:                    break;
                    414:                case '_':
                    415:                    lastcomp = TRUE;
                    416:                    break;
                    417:                case '/':
                    418: #ifdef ARTSRCH
                    419:                    s = scrbuf;
                    420:                    if (!index("/?g",pattern[-2]))
                    421:                        *s++ = '/';
                    422:                    strcpy(s,lastpat);
                    423:                    s += strlen(s);
                    424:                    if (pattern[-2] != 'g') {
                    425:                        if (index("/?",pattern[-2]))
                    426:                            *s++ = pattern[-2];
                    427:                        else
                    428:                            *s++ = '/';
                    429:                        if (art_howmuch == 1)
                    430:                            *s++ = 'h';
                    431:                        else if (art_howmuch == 2)
                    432:                            *s++ = 'a';
                    433:                        if (art_doread)
                    434:                            *s++ = 'r';
                    435:                    }
                    436:                    *s = '\0';
                    437:                    s = scrbuf;
                    438: #else
                    439:                    s = nullstr;
                    440: #endif
                    441:                    break;
                    442:                case '{':
                    443:                    pattern = cpytill(scrbuf,pattern+1,'}');
                    444:                    if (s = index(scrbuf,'-'))
                    445:                        *s++ = '\0';
                    446:                    else
                    447:                        s = nullstr;
                    448:                    s = getval(scrbuf,s);
                    449:                    break;
                    450:                case '[':
                    451:                    pattern = cpytill(scrbuf,pattern+1,']');
                    452:                    i = set_line_type(scrbuf,scrbuf+strlen(scrbuf));
                    453:                    if (line_buf)
                    454:                        free(line_buf);
                    455:                    s = line_buf = fetchlines(art,i);
                    456:                    break;
                    457: #ifdef CONDSUB
                    458:                case '(': {
                    459:                    COMPEX *oldbra_compex = bra_compex;
                    460:                    COMPEX cond_compex;
                    461:                    char rch;
                    462:                    bool matched;
                    463:                    
                    464:                    init_compex(&cond_compex);
                    465:                    pattern = dointerp(dest,destsize,pattern+1,"!=");
                    466:                    rch = *pattern;
                    467:                    if (rch == '!')
                    468:                        pattern++;
                    469:                    if (*pattern != '=')
                    470:                        goto getout;
                    471:                    pattern = cpytill(scrbuf,pattern+1,'?');
                    472:                    if (!*pattern)
                    473:                        goto getout;
                    474:                    if (s = compile(&cond_compex,scrbuf,TRUE,TRUE)) {
                    475:                        printf("%s: %s\n",scrbuf,s) FLUSH;
                    476:                        pattern += strlen(pattern);
                    477:                        goto getout;
                    478:                    }
                    479:                    matched = (execute(&cond_compex,dest) != Nullch);
                    480:                    if (cond_compex.nbra)       /* were there brackets? */
                    481:                        bra_compex = &cond_compex;
                    482:                    if (matched==(rch == '=')) {
                    483:                        pattern = dointerp(dest,destsize,pattern+1,":)");
                    484:                        if (*pattern == ':')
                    485:                            pattern = skipinterp(pattern+1,")");
                    486:                    }
                    487:                    else {
                    488:                        pattern = skipinterp(pattern+1,":)");
                    489:                        if (*pattern == ':')
                    490:                            pattern++;
                    491:                        pattern = dointerp(dest,destsize,pattern,")");
                    492:                    }
                    493:                    s = dest;
                    494:                    bra_compex = oldbra_compex;
                    495:                    free_compex(&cond_compex);
                    496:                    break;
                    497:                }
                    498: #endif
                    499: #ifdef BACKTICK
                    500:                case '`': {
                    501:                    FILE *pipefp, *popen();
                    502: 
                    503:                    pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"`");
                    504:                    pipefp = popen(scrbuf,"r");
                    505:                    if (pipefp != Nullfp) {
                    506:                        int len;
                    507: 
                    508:                        len = fread(scrbuf,sizeof(char),(sizeof scrbuf)-1,
                    509:                            pipefp);
                    510:                        scrbuf[len] = '\0';
                    511:                        pclose(pipefp);
                    512:                    }
                    513:                    else {
                    514:                        printf("\nCan't run %s\n",scrbuf);
                    515:                        *scrbuf = '\0';
                    516:                    }
                    517:                    for (s=scrbuf; *s; s++) {
                    518:                        if (*s == '\n') {
                    519:                            if (s[1])
                    520:                                *s = ' ';
                    521:                            else
                    522:                                *s = '\0';
                    523:                        }
                    524:                    }
                    525:                    s = scrbuf;
                    526:                    break;
                    527:                }
                    528: #endif
                    529: #ifdef PROMPTTTY
                    530:                case '"':
                    531:                    pattern = dointerp(scrbuf,(sizeof scrbuf),pattern+1,"\"");
                    532:                    fputs(scrbuf,stdout) FLUSH;
                    533:                    resetty();
                    534:                    gets(scrbuf);
                    535:                    noecho();
                    536:                    crmode();
                    537:                    s = scrbuf;
                    538:                    break;
                    539: #endif
                    540:                case '~':
                    541:                    s = homedir;
                    542:                    break;
                    543:                case '.':
                    544:                    s = dotdir;
                    545:                    break;
                    546:                case '$':
                    547:                    s = scrbuf;
                    548:                    sprintf(s,"%d",getpid());
                    549:                    break;
                    550:                case '0': case '1': case '2': case '3': case '4':
                    551:                case '5': case '6': case '7': case '8': case '9':
                    552: #ifdef CONDSUB
                    553:                    s = getbracket(bra_compex,*pattern - '0');
                    554: #else
                    555:                    s = nullstr;
                    556: #endif
                    557:                    break;
                    558:                case 'a':
                    559:                    s = scrbuf;
                    560:                    sprintf(s,"%ld",(long)art);
                    561:                    break;
                    562:                case 'A':
                    563: #ifdef LINKART
                    564:                    s = linkartname;    /* so Eunice people get right file */
                    565: #else
                    566:                    s = scrbuf;
                    567:                    sprintf(s,"%s/%s/%ld",spool,ngdir,(long)art);
                    568: #endif
                    569:                    break;
                    570:                case 'b':
                    571:                    s = savedest;
                    572:                    break;
                    573:                case 'B':
                    574:                    s = scrbuf;
                    575:                    sprintf(s,"%ld",(long)savefrom);
                    576:                    break;
                    577:                case 'c':
                    578:                    s = ngdir;
                    579:                    break;
                    580:                case 'C':
                    581:                    s = ngname;
                    582:                    break;
                    583:                case 'd':
                    584:                    s = scrbuf;
                    585:                    sprintf(s,"%s/%s",spool,ngdir);
                    586:                    break;
                    587:                case 'D':
                    588:                    s = dist_buf = fetchlines(art,DIST_LINE);
                    589:                    break;
                    590:                case 'f':                       /* from line */
                    591: #ifdef ASYNC_PARSE
                    592:                    parse_maybe(art);
                    593: #endif
                    594:                    if (htype[REPLY_LINE].ht_minpos >= 0) {
                    595:                                                /* was there a reply line? */
                    596:                        if (!(s=reply_buf))
                    597:                            s = reply_buf = fetchlines(art,REPLY_LINE);
                    598:                    }
                    599:                    else if (!(s = from_buf))
                    600:                        s = from_buf = fetchlines(art,FROM_LINE);
                    601:                    break;
                    602:                case 'F':
                    603: #ifdef ASYNC_PARSE
                    604:                    parse_maybe(art);
                    605: #endif
                    606:                    if (htype[FOLLOW_LINE].ht_minpos >= 0)
                    607:                                        /* is there a Followup-To line? */
                    608:                        s = follow_buf = fetchlines(art,FOLLOW_LINE);
                    609:                    else {
                    610:                        int off;
                    611:                
                    612:                        s = ngs_buf = fetchlines(art,NGS_LINE);
                    613:                        if (h = instr(s,"net.general")) {
                    614:                            off = h-s;
                    615:                            strncpy(scrbuf,s,off+4);
                    616:                            strcpy(scrbuf+off+4,"followup");
                    617:                            safecpy(scrbuf+off+12,h+11,sizeof(scrbuf));
                    618:                            s = scrbuf;
                    619:                        }
                    620:                    }
                    621:                    break;
                    622:                case 'h':                       /* header file name */
                    623:                    s = headname;
                    624:                    break;
                    625:                case 'H':                       /* host name */
                    626:                    s = sitename;
                    627:                    break;
                    628:                case 'i':
                    629:                    if (!(s=artid_buf))
                    630:                        s = artid_buf = fetchlines(art,MESSID_LINE);
                    631:                    if (*s && *s != '<') {
                    632:                        sprintf(scrbuf,"<%s>",artid_buf);
                    633:                        s = scrbuf;
                    634:                    }
                    635:                    break;
                    636:                case 'I':                       /* ref article indicator */
                    637:                    s = scrbuf;
                    638:                    sprintf(scrbuf,"'%s'",indstr);
                    639:                    break;
                    640:                case 'l':                       /* rn library */
                    641: #ifdef NEWSADMIN
                    642:                    s = newsadmin;
                    643: #else
                    644:                    s = "???";
                    645: #endif
                    646:                    break;
                    647:                case 'L':                       /* login id */
                    648:                    s = logname;
                    649:                    break;
                    650:                case 'm':               /* current mode */
                    651:                    s = scrbuf;
                    652:                    *s = mode;
                    653:                    s[1] = '\0';
                    654:                    break;
                    655:                case 'M':
                    656: #ifdef DELAYMARK
                    657:                    sprintf(scrbuf,"%ld",(long)dmcount);
                    658:                    s = scrbuf;
                    659: #else
                    660:                    s = nullstr;
                    661: #endif
                    662:                    break;
                    663:                case 'n':                       /* newsgroups */
                    664:                    s = ngs_buf = fetchlines(art,NGS_LINE);
                    665:                    break;
                    666:                case 'N':                       /* full name */
                    667:                    s = getval("NAME",realname);
                    668:                    break;
                    669:                case 'o':                       /* organization */
                    670:                    s = getval("ORGANIZATION",orgname);
                    671: #ifdef ORGFILE
                    672:                    if (*s == '/') {
                    673:                        FILE *ofp = fopen(s,"r");
                    674: 
                    675:                        if (ofp) {
                    676:                            fgets(scrbuf,sizeof scrbuf,ofp);
                    677:                            fclose(ofp);
                    678:                            s = scrbuf;
                    679:                            s[strlen(s)-1] = '\0';
                    680:                        }
                    681:                    }
                    682: #endif
                    683:                    break;
                    684:                case 'O':
                    685:                    s = origdir;
                    686:                    break;
                    687:                case 'p':
                    688:                    s = cwd;
                    689:                    break;
                    690:                case 'P':
                    691:                    s = spool;
                    692:                    break;
                    693:                case 'r':
                    694: #ifdef ASYNC_PARSE
                    695:                    parse_maybe(art);
                    696: #endif
                    697:                    if (htype[REFS_LINE].ht_minpos >= 0) {
                    698:                        refs_buf = fetchlines(art,REFS_LINE);
                    699:                        refscpy(scrbuf,(sizeof scrbuf),refs_buf);
                    700:                    }
                    701:                    else
                    702:                        *scrbuf = '\0';
                    703:                    s = rindex(scrbuf,'<');
                    704:                    break;
                    705:                case 'R':
                    706: #ifdef ASYNC_PARSE
                    707:                    parse_maybe(art);
                    708: #endif
                    709:                    if (htype[REFS_LINE].ht_minpos >= 0) {
                    710:                        refs_buf = fetchlines(art,REFS_LINE);
                    711:                        refscpy(scrbuf,(sizeof scrbuf),refs_buf);
                    712:                    }
                    713:                    else
                    714:                        *scrbuf = '\0';
                    715:                    if (!artid_buf)
                    716:                        artid_buf = fetchlines(art,MESSID_LINE);
                    717:                    if (artid_buf[0] == '<')
                    718:                        safecat(scrbuf,artid_buf,sizeof(scrbuf));
                    719:                    else if (artid_buf[0]) {
                    720:                        char tmpbuf[64];
                    721:     
                    722:                        sprintf(tmpbuf,"<%s>",artid_buf);
                    723:                        safecat(scrbuf,tmpbuf,sizeof(scrbuf));
                    724:                    }
                    725:                    s = scrbuf;
                    726:                    break;
                    727:                case 's':
                    728:                    if (!(s=subj_buf))
                    729:                        s = subj_buf = fetchsubj(art,TRUE,TRUE);
                    730:                                                /* get subject handy */
                    731:                    while ((*s=='R'||*s=='r')&&(s[1]=='E'||s[1]=='e')&&s[2]==':') {
                    732:                                                /* skip extra Re: */
                    733:                        s += 3;
                    734:                        if (*s == ' ')
                    735:                            s++;
                    736:                    }
                    737:                    if (h = instr(s,"- (nf"))
                    738:                        *h = '\0';
                    739:                    break;
                    740:                case 'S':
                    741:                    if (!(s=subj_buf))
                    742:                        s = subj_buf = fetchsubj(art,TRUE,TRUE);
                    743:                                                /* get subject handy */
                    744:                    if ((*s=='R'||*s=='r')&&(s[1]=='E'||s[1]=='e')&&s[2]==':') {
                    745:                                                /* skip extra Re: */
                    746:                        s += 3;
                    747:                        if (*s == ' ')
                    748:                            s++;
                    749:                    }
                    750:                    break;
                    751:                case 't':
                    752:                case 'T':
                    753: #ifdef ASYNC_PARSE
                    754:                    parse_maybe(art);
                    755: #endif
                    756:                    if (htype[REPLY_LINE].ht_minpos >= 0) {
                    757:                                        /* was there a reply line? */
                    758:                        if (!(s=reply_buf))
                    759:                            s = reply_buf = fetchlines(art,REPLY_LINE);
                    760:                    }
                    761:                    else if (!(s = from_buf))
                    762:                        s = from_buf = fetchlines(art,FROM_LINE);
                    763:                    if (*pattern == 'T') {
                    764:                        if (htype[PATH_LINE].ht_minpos >= 0) {
                    765:                                        /* should we substitute path? */
                    766:                            s = path_buf = fetchlines(art,PATH_LINE);
                    767:                        }
                    768:                        i = strlen(sitename);
                    769:                        if (strnEQ(sitename,s,i) && s[i] == '!')
                    770:                            s += i + 1;
                    771:                    }
                    772:                    if ((h=index(s,'(')) != Nullch)
                    773:                                                /* strip garbage from end */
                    774:                        *(h-1) = '\0';
                    775:                    else if ((h=index(s,'<')) != Nullch) {
                    776:                                                /* or perhaps from beginning */
                    777:                        s = h+1;
                    778:                        if ((h=index(s,'>')) != Nullch)
                    779:                            *h = '\0';
                    780:                    }
                    781:                    break;
                    782:                case 'u':
                    783:                    sprintf(scrbuf,"%ld",(long)toread[ng]);
                    784:                    s = scrbuf;
                    785:                    break;
                    786:                case 'U':
                    787:                    sprintf(scrbuf,"%ld",
                    788:                        (long)(((ART_NUM)toread[ng]) - 1 + was_read(art)));
                    789:                    s = scrbuf;
                    790:                    break;
                    791:                case 'x':                       /* news library */
                    792:                    s = lib;
                    793:                    break;
                    794:                case 'X':                       /* rn library */
                    795:                    s = rnlib;
                    796:                    break;
                    797:                case 'z':
                    798: #ifdef LINKART
                    799:                    s = linkartname;    /* so Eunice people get right file */
                    800: #else
                    801:                    s = scrbuf;
                    802:                    sprintf(s,"%ld",(long)art);
                    803: #endif
                    804:                    if (stat(s,&filestat) < 0)
                    805:                        filestat.st_size = 0L;
                    806:                    sprintf(scrbuf,"%5ld",(long)filestat.st_size);
                    807:                    s = scrbuf;
                    808:                    break;
                    809:                default:
                    810:                    if (--destsize <= 0)
                    811:                        abort_interp();
                    812:                    *dest++ = *pattern | metabit;
                    813:                    s = nullstr;
                    814:                    break;
                    815:                }
                    816:            }
                    817:            if (!s)
                    818:                s = nullstr;
                    819:            pattern++;
                    820:            if (upper || lastcomp) {
                    821:                char *t;
                    822: 
                    823:                if (s != scrbuf) {
                    824:                    safecpy(scrbuf,s,(sizeof scrbuf));
                    825:                    s = scrbuf;
                    826:                }
                    827:                if (upper || !(t=rindex(s,'/')))
                    828:                    t = s;
                    829:                while (*t && !isalpha(*t))
                    830:                    t++;
                    831:                if (islower(*t))
                    832:                    *t = toupper(*t);
                    833:            }
                    834:            i = metabit;                /* maybe get into register */
                    835:            if (s == dest) {
                    836:                while (*dest) {
                    837:                    if (--destsize <= 0)
                    838:                        abort_interp();
                    839:                    *dest++ |= i;
                    840:                }
                    841:            }
                    842:            else {
                    843:                while (*s) {
                    844:                    if (--destsize <= 0)
                    845:                        abort_interp();
                    846:                    *dest++ = *s++ | i;
                    847:                }
                    848:            }
                    849:        }
                    850:        else {
                    851:            if (--destsize <= 0)
                    852:                abort_interp();
                    853:            if (*pattern == '^' && pattern[1]) {
                    854:                ++pattern;                      /* skip uparrow */
                    855:                i = *pattern;           /* get char into a register */
                    856:                if (i == '?')
                    857:                    *dest++ = '\177' | metabit;
                    858:                else if (i == '(') {
                    859:                    metabit = 0200;
                    860:                    destsize++;
                    861:                }
                    862:                else if (i == ')') {
                    863:                    metabit = 0;
                    864:                    destsize++;
                    865:                }
                    866:                else
                    867:                    *dest++ = i & 037 | metabit;
                    868:                pattern++;
                    869:            }
                    870:            else if (*pattern == '\\' && pattern[1]) {
                    871:                ++pattern;                      /* skip backslash */
                    872:                i = *pattern;           /* get char into a register */
                    873:     
                    874:                /* this used to be a switch but the if may save space */
                    875:                
                    876:                if (i >= '0' && i <= '7') {
                    877:                    i = 1;
                    878:                    while (i < 01000 && *pattern >= '0' && *pattern <= '7') {
                    879:                        i <<= 3;
                    880:                        i += *pattern++ - '0';
                    881:                    }
                    882:                    *dest++ = i & 0377 | metabit;
                    883:                    --pattern;
                    884:                }
                    885:                else if (i == 'b')
                    886:                    *dest++ = '\b' | metabit;
                    887:                else if (i == 'f')
                    888:                    *dest++ = '\f' | metabit;
                    889:                else if (i == 'n')
                    890:                    *dest++ = '\n' | metabit;
                    891:                else if (i == 'r')
                    892:                    *dest++ = '\r' | metabit;
                    893:                else if (i == 't')
                    894:                    *dest++ = '\t' | metabit;
                    895:                else
                    896:                    *dest++ = i | metabit;
                    897:                pattern++;
                    898:            }
                    899:            else
                    900:                *dest++ = *pattern++ | metabit;
                    901:        }
                    902:     }
                    903:     *dest = '\0';
                    904: getout:
                    905:     if (subj_buf != Nullch)    /* return any checked out storage */
                    906:        free(subj_buf);
                    907:     if (ngs_buf != Nullch)
                    908:        free(ngs_buf);
                    909:     if (refs_buf != Nullch)
                    910:        free(refs_buf);
                    911:     if (artid_buf != Nullch)
                    912:        free(artid_buf);
                    913:     if (reply_buf != Nullch)
                    914:        free(reply_buf);
                    915:     if (from_buf != Nullch)
                    916:        free(from_buf);
                    917:     if (path_buf != Nullch)
                    918:        free(path_buf);
                    919:     if (follow_buf != Nullch)
                    920:        free(follow_buf);
                    921:     if (dist_buf != Nullch)
                    922:        free(dist_buf);
                    923:     if (line_buf != Nullch)
                    924:        free(line_buf);
                    925:     return pattern;                    /* where we left off */
                    926: }
                    927: 
                    928: void
                    929: interp(dest,destsize,pattern)
                    930: char *dest;
                    931: int destsize;
                    932: char *pattern;
                    933: {
                    934:     dointerp(dest,destsize,pattern,Nullch);
                    935: #ifdef DEBUGGING
                    936:     if (debug & DEB_FILEXP)
                    937:        fputs(dest,stdout);
                    938: #endif
                    939: }
                    940: 
                    941: /* copy a references line, normalizing as we go */
                    942: 
                    943: void
                    944: refscpy(dest,destsize,src)
                    945: register char *dest, *src;
                    946: register int destsize;
                    947: {
                    948:     register char *dot, *at, *beg;
                    949:     char tmpbuf[64];
                    950:     
                    951:     while (*src) {
                    952:        if (*src != '<') {
                    953:            if (--destsize <= 0)
                    954:                break;
                    955:            *dest++ = '<';
                    956:            at = dot = Nullch;
                    957:            beg = src;
                    958:            while (*src && *src != ' ' && *src != ',') {
                    959:                if (*src == '.')
                    960:                    dot = src;
                    961:                else if (*src == '@')
                    962:                    at = src;
                    963:                if (--destsize <= 0)
                    964:                    break;
                    965:                *dest++ = *src++;
                    966:            }
                    967:            if (destsize <= 0)
                    968:                break;
                    969:            if (dot && !at) {
                    970:                int len;
                    971: 
                    972:                *dest = *dot++ = '\0';
                    973:                sprintf(tmpbuf,"%s@%s.UUCP",dot,beg);
                    974:                len = strlen(tmpbuf);
                    975:                if (destsize > len) {
                    976:                    strcpy(dest,tmpbuf);
                    977:                    dest = dest + len;
                    978:                    destsize -= len;
                    979:                }
                    980:            }
                    981:            if (--destsize <= 0)
                    982:                break;
                    983:            *dest++ = '>';
                    984:        }
                    985:        else {
                    986:            while (*src && --destsize > 0 && (*dest++ = *src++) != '>') ;
                    987:            if (destsize <= 0)
                    988:                break;
                    989:        }
                    990:        while (*src == ' ' || *src == ',') src++;
                    991:        if (*src && --destsize > 0)
                    992:            *dest++ = ' ';
                    993:     }
                    994:     *dest = '\0';
                    995: } 
                    996: 
                    997: /* get the person's real name from /etc/passwd */
                    998: /* (string is overwritten, so it must be copied) */
                    999: 
                   1000: char *
                   1001: getrealname(uid)
                   1002: int uid;
                   1003: {
                   1004:     char *s, *c;
                   1005: 
                   1006: #ifdef PASSNAMES
                   1007: #ifdef GETPWENT
                   1008:     struct passwd *pwd = getpwuid(uid);
                   1009:     
                   1010:     s = pwd->pw_gecos;
                   1011: #else
                   1012:     char tmpbuf[512];
                   1013:     int i;
                   1014: 
                   1015:     getpw(uid, tmpbuf);
                   1016:     for (s=tmpbuf, i=GCOSFIELD-1; i; i--) {
                   1017:        if (s)
                   1018:            s = index(s,':')+1;
                   1019:     }
                   1020:     if (!s)
                   1021:        return nullstr;
                   1022:     cpytill(tmpbuf,s,':');
                   1023:     s = tmpbuf;
                   1024: #endif
                   1025: #ifdef BERKNAMES
                   1026: #ifdef BERKJUNK
                   1027:     while (*s && !isalnum(*s) && *s != '&') s++;
                   1028: #endif
                   1029:     if ((c = index(s, ',')) != Nullch)
                   1030:        *c = '\0';
                   1031:     if ((c = index(s, ';')) != Nullch)
                   1032:        *c = '\0';
                   1033:     s = cpytill(buf,s,'&');
                   1034:     if (*s == '&') {                   /* whoever thought this one up was */
                   1035:        c = buf + strlen(buf);          /* in the middle of the night */
                   1036:        strcat(c,logname);              /* before the morning after */
                   1037:        strcat(c,s+1);
                   1038:        if (islower(*c))
                   1039:            *c = toupper(*c);           /* gack and double gack */
                   1040:     }
                   1041: #else
                   1042:     if ((c = index(s, '(')) != Nullch)
                   1043:        *c = '\0';
                   1044:     if ((c = index(s, '-')) != Nullch)
                   1045:        s = c;
                   1046:     strcpy(buf,tmpbuf);
                   1047: #endif
                   1048: #ifdef GETPWENT
                   1049:     endpwent();
                   1050: #endif
                   1051:     return buf;                                /* return something static */
                   1052: #else
                   1053:     if ((tmpfp=fopen(filexp(FULLNAMEFILE),"r")) != Nullfp) {
                   1054:        fgets(buf,sizeof buf,tmpfp);
                   1055:        fclose(tmpfp);
                   1056:        buf[strlen(buf)-1] = '\0';
                   1057:        return buf;
                   1058:     }
                   1059:     return "PUT YOUR NAME HERE";
                   1060: #endif
                   1061: }
                   1062: 
                   1063: static void
                   1064: abort_interp()
                   1065: {
                   1066:     fputs("\n% interp buffer overflow!\n",stdout) FLUSH;
                   1067:     sig_catcher(0);
                   1068: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.