|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.