Annotation of 43BSD/contrib/rn/intrp.c, revision 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.