1: /* $Header: art.c,v 4.3.1.4 85/05/23 12:13:31 lwall Exp $ 2: * 3: * $Log: art.c,v $ 4: * Revision 4.3.1.4 85/05/23 12:13:31 lwall 5: * shouldn't display article that's really a subdirectory. 6: * 7: * Revision 4.3.1.3 85/05/13 09:29:55 lwall 8: * Added CUSTOMLINES option. 9: * 10: * Revision 4.3.1.2 85/05/10 13:46:07 lwall 11: * Fixed header reparse bug on backpage. 12: * 13: * Revision 4.3.1.1 85/05/10 11:30:56 lwall 14: * Branch for patches. 15: * 16: * Revision 4.3 85/05/01 11:34:51 lwall 17: * Baseline for release with 4.3bsd. 18: * 19: */ 20: 21: #include "EXTERN.h" 22: #include "common.h" 23: #include "rn.h" 24: #include "ngstuff.h" 25: #include "head.h" 26: #include "cheat.h" 27: #include "help.h" 28: #include "search.h" 29: #include "artio.h" 30: #include "ng.h" 31: #include "bits.h" 32: #include "final.h" 33: #include "artstate.h" 34: #include "rcstuff.h" 35: #include "term.h" 36: #include "sw.h" 37: #include "util.h" 38: #include "backpage.h" 39: #include "intrp.h" 40: #include "INTERN.h" 41: #include "art.h" 42: 43: /* page_switch() return values */ 44: 45: #define PS_NORM 0 46: #define PS_ASK 1 47: #define PS_RAISE 2 48: #define PS_TOEND 3 49: 50: bool special = FALSE; /* is next page special length? */ 51: int slines = 0; /* how long to make page when special */ 52: ART_LINE highlight = -1; /* next line to be highlighted */ 53: char *restart = Nullch; /* if nonzero, the place where last */ 54: /* line left off on line split */ 55: char *blinebeg; /* where in buffer current line began */ 56: ART_POS alinebeg; /* where in file current line began */ 57: 58: #ifdef INNERSEARCH 59: ART_POS innersearch = 0; /* artpos of end of line we found */ 60: /* for 'g' command */ 61: ART_LINE isrchline = 0; /* last line to display */ 62: bool hide_everything = FALSE; 63: /* if set, do not write page now, */ 64: /* but refresh when done with page */ 65: COMPEX gcompex; /* in article search pattern */ 66: #endif 67: 68: bool firstpage; /* is this the 1st page of article? */ 69: 70: char art_buf[LBUFLEN]; /* place for article lines */ 71: 72: void 73: art_init() 74: { 75: ; 76: } 77: 78: int 79: do_article() 80: { 81: register char *s; 82: ART_POS artsize; /* size in bytes of article */ 83: bool hide_this_line = FALSE; /* hidden header line? */ 84: ART_LINE linenum; /* line # on page, 1 origin */ 85: #ifdef ULSMARTS 86: bool under_lining = FALSE; 87: /* are we underlining a word? */ 88: #endif 89: register char *bufptr = art_buf; 90: /* pointer to input buffer */ 91: register int outpos; /* column position of output */ 92: static char prompt_buf[64]; /* place to hold prompt */ 93: bool notesfiles = FALSE; /* might there be notesfiles junk? */ 94: char oldmode = mode; 95: 96: #ifdef INNERSEARCH 97: register int outputok; 98: #endif 99: 100: if (fstat(artfp->_file,&filestat)) 101: /* get article file stats */ 102: return DA_CLEAN; 103: if (filestat.st_mode & S_IFMT != S_IFREG) 104: return DA_NORM; 105: artsize = filestat.st_size; 106: /* from that get article size */ 107: sprintf(prompt_buf, 108: "%%sEnd of article %ld (of %ld)--what next? [%%s]", 109: (long)art,(long)lastart); /* format prompt string */ 110: prompt = prompt_buf; 111: int_count = 0; /* interrupt count is 0 */ 112: firstpage = (topline < 0); 113: for (;;) { /* for each page */ 114: assert(art == openart); 115: if (do_fseek) { 116: #ifdef ASYNC_PARSE 117: parse_maybe(art); /* make sure header is ours */ 118: #endif 119: artpos = vrdary(artline); 120: if (artpos < 0) 121: artpos = -artpos; /* labs(), anyone? */ 122: if (firstpage) 123: artpos = (ART_POS)0; 124: fseek(artfp,artpos,0); 125: if (artpos < htype[PAST_HEADER].ht_minpos) 126: in_header = SOME_LINE; 127: do_fseek = FALSE; 128: restart = Nullch; 129: } 130: if (firstpage) { 131: if (firstline) { 132: interp(art_buf, (sizeof art_buf), firstline); 133: #ifdef CLEAREOL 134: maybe_eol(); /* PWP */ 135: #endif CLEAREOL 136: fputs(art_buf,stdout) FLUSH; 137: artopen(art); /* rewind article in case interp */ 138: /* forced a header parse */ 139: } 140: else { 141: ART_NUM i; 142: 143: #ifdef CLEAREOL 144: maybe_eol(); /* PWP */ 145: #endif CLEAREOL 146: printf("Article %ld",(long)art); 147: i = (((ART_NUM)toread[ng]) - 1 + was_read(art)); 148: #ifdef DELAYMARK 149: if (i || dmcount) { 150: printf(" (%ld more",(long)i); 151: if (dmcount) 152: printf(" + %ld Marked to return)",(long)dmcount); 153: putchar(')'); 154: } 155: #else 156: if (i) 157: printf(" (%ld more)",(long)i); 158: #endif 159: if (htype[NGS_LINE].ht_flags & HT_HIDE) 160: printf(" in %s", ngname); 161: fputs(":\n",stdout) FLUSH; 162: } 163: start_header(art); 164: forcelast = FALSE; /* we will have our day in court */ 165: restart = Nullch; 166: artline = 0; /* start counting lines */ 167: artpos = 0; 168: vwtary(artline,artpos); /* remember pos in file */ 169: } 170: for (linenum=(firstpage?2:1); 171: in_header || ( 172: #ifdef INNERSEARCH 173: innersearch ? innermore() : 174: #endif 175: linenum<(firstpage?initlines:(special?slines:LINES)) ); 176: linenum++) { /* for each line on page */ 177: if (int_count) { /* exit via interrupt? */ 178: putchar('\n') FLUSH; /* get to left margin */ 179: int_count = 0; /* reset interrupt count */ 180: return DA_NORM; /* skip out of loops */ 181: } 182: if (restart) { /* did not finish last line? */ 183: bufptr = restart; /* then start again here */ 184: restart = Nullch; /* and reset the flag */ 185: } 186: else { /* not a restart */ 187: if (fgets(art_buf,LBUFLEN,artfp)==Nullch) { 188: /* if all done */ 189: return DA_NORM; /* skip out of loops */ 190: } 191: bufptr = art_buf; /* so start at beginning */ 192: art_buf[LBUFLEN-1] = '\0'; 193: /* make sure string ends */ 194: } 195: blinebeg = bufptr; /* remember where we began */ 196: alinebeg = artpos; /* both in buffer and file */ 197: if (in_header && bufptr == art_buf) 198: hide_this_line = 199: parseline(art_buf,do_hiding,hide_this_line); 200: else if (notesfiles && do_hiding && 201: bufptr == art_buf && *art_buf == '#' && 202: isupper(art_buf[1]) && art_buf[2] == ':' ) { 203: fgets(art_buf,sizeof(art_buf),artfp); 204: if (index(art_buf,'!') != Nullch) 205: fgets(art_buf,sizeof(art_buf),artfp); 206: htype[PAST_HEADER].ht_minpos = ftell(artfp); 207: /* exclude notesfiles droppings */ 208: hide_this_line = TRUE; /* and do not print either */ 209: notesfiles = FALSE; 210: } 211: #ifdef CUSTOMLINES 212: if (hideline && bufptr == art_buf && 213: execute(&hide_compex,art_buf) ) 214: hide_this_line = TRUE; 215: #endif 216: if (in_header && htype[in_header].ht_flags & HT_MAGIC) { 217: if (in_header == NGS_LINE) { 218: hide_this_line = (index(art_buf,',') == Nullch); 219: } 220: else if (in_header == EXPIR_LINE) { 221: if (!(htype[EXPIR_LINE].ht_flags & HT_HIDE)) 222: hide_this_line = (strlen(art_buf) < 10); 223: } 224: } 225: if (in_header == SUBJ_LINE && 226: htype[SUBJ_LINE].ht_flags & HT_MAGIC) { 227: /* is this the subject? */ 228: int length; 229: 230: length = strlen(art_buf)-1; 231: artline++; 232: art_buf[length] = '\0'; /* wipe out newline */ 233: #ifdef NOFIREWORKS 234: no_ulfire(); 235: #endif 236: notesfiles = 237: (instr(&art_buf[length-10]," - (nf") != Nullch); 238: if (oldsubject) { 239: length += 7; 240: fputs("(SAME) ",stdout); 241: oldsubject = FALSE; 242: } 243: if (length+UG > COLS) { /* rarely true */ 244: linenum++; 245: vwtary(artline,vrdary(artline-1)+COLS); 246: artline++; 247: } 248: s = art_buf + 8; 249: *s++ = '\0'; /* make into 2 strings */ 250: #ifdef CLEAREOL 251: maybe_eol(); /* PWP */ 252: #endif CLEAREOL 253: fputs(art_buf,stdout) FLUSH; 254: /* print up through : */ 255: if (!UG) 256: putchar(' '); 257: underprint(s); /* print subject underlined */ 258: putchar('\n') FLUSH; /* and finish the line */ 259: } 260: else if (hide_this_line && do_hiding) { 261: /* do not print line? */ 262: linenum--; /* compensate for linenum++ */ 263: if (!in_header) 264: hide_this_line = FALSE; 265: } 266: else { /* just a normal line */ 267: if (highlight==artline) { /* this line to be highlit? */ 268: if (marking == STANDOUT) { 269: #ifdef NOFIREWORKS 270: if (erase_screen) 271: no_sofire(); 272: #endif 273: standout(); 274: } 275: else { 276: #ifdef NOFIREWORKS 277: if (erase_screen) 278: no_ulfire(); 279: #endif 280: underline(); 281: } 282: if (*bufptr == '\n') 283: putchar(' '); 284: } 285: #ifdef INNERSEARCH 286: outputok = !hide_everything; 287: /* get it into register, hopefully */ 288: #endif 289: #ifdef CLEAREOL 290: #ifdef INNERSEARCH 291: if (outputok) 292: #endif 293: maybe_eol(); /* PWP */ 294: #endif CLEAREOL 295: #ifdef CUSTOMLINES 296: if (pagestop && bufptr == art_buf && 297: execute(&page_compex,art_buf) ) 298: linenum = 32700; 299: #endif 300: for (outpos = 0; outpos < COLS; ) { 301: /* while line has room */ 302: if (*bufptr >= ' ') { /* normal char? */ 303: #ifdef ULSMARTS 304: if (*bufptr == '_') { 305: if (bufptr[1] == '\b') { 306: if (!under_lining && highlight!=artline 307: #ifdef INNERSEARCH 308: && outputok 309: #endif 310: ) { 311: under_lining++; 312: if (UG) { 313: if (bufptr != buf && 314: bufptr[-1] == ' ') { 315: outpos--; 316: backspace(); 317: } 318: } 319: underline(); 320: } 321: bufptr += 2; 322: } 323: } 324: else { 325: if (under_lining) { 326: under_lining = 0; 327: un_underline(); 328: if (UG) { 329: if (*bufptr == ' ') 330: goto skip_put; 331: outpos++; 332: } 333: } 334: } 335: #endif 336: #ifdef INNERSEARCH 337: if (outputok) 338: #endif 339: { 340: #ifdef ROTATION 341: if (rotate && !in_header 342: && isalpha(*bufptr)) { 343: if ((*bufptr & 31) <= 13) 344: putchar(*bufptr+13); 345: else 346: putchar(*bufptr-13); 347: } 348: else 349: #endif 350: putchar(*bufptr); 351: } 352: if (*UC && ((highlight==artline && marking == 1) 353: #ifdef ULSMARTS 354: || under_lining 355: #endif 356: )) { 357: backspace(); 358: underchar(); 359: } 360: skip_put: 361: bufptr++; 362: outpos++; 363: } 364: else if (*bufptr == '\n' || !*bufptr) { 365: /* newline? */ 366: #ifdef ULSMARTS 367: if (under_lining) { 368: under_lining = 0; 369: un_underline(); 370: } 371: #endif 372: #ifdef DEBUGGING 373: if (debug & DEB_INNERSRCH && outpos < COLS - 6) { 374: standout(); 375: printf("%4d",artline); 376: un_standout(); 377: } 378: #endif 379: #ifdef INNERSEARCH 380: if (outputok) 381: #endif 382: putchar('\n') FLUSH; 383: restart = 0; 384: outpos = 1000; /* signal normal \n */ 385: } 386: else if (*bufptr == '\t') { /* tab? */ 387: #ifdef INNERSEARCH 388: if (outputok) 389: #endif 390: putchar(*bufptr); 391: bufptr++; 392: outpos += 8 - outpos % 8; 393: } 394: else if (*bufptr == '\f') { /* form feed? */ 395: #ifdef INNERSEARCH 396: if (outputok) 397: #endif 398: fputs("^L",stdout); 399: if (bufptr == blinebeg && highlight != artline) 400: linenum = 32700; 401: /* how is that for a magic number? */ 402: bufptr++; 403: outpos += 2; 404: } 405: else { /* other control char */ 406: #ifdef INNERSEARCH 407: if (outputok) 408: #endif 409: { 410: putchar('^'); 411: if (highlight == artline && *UC && marking == 1) { 412: backspace(); 413: underchar(); 414: putchar(*bufptr+64); 415: backspace(); 416: underchar(); 417: } 418: else 419: putchar(*bufptr+64); 420: } 421: bufptr++; 422: outpos += 2; 423: } 424: 425: } /* end of column loop */ 426: 427: if (outpos < 1000) {/* did line overflow? */ 428: restart = bufptr; 429: /* restart here next time */ 430: if (AM) { /* automatic margins on tty? */ 431: if (!XN && *bufptr == '\n') 432: /* need we simulate XN? */ 433: restart = 0; 434: /* skip the newline */ 435: } 436: else { /* cursor just hangs there */ 437: #ifdef INNERSEARCH 438: if (outputok) 439: #endif 440: putchar('\n') FLUSH; 441: /* so move it down ourselves */ 442: if (*bufptr == '\n') 443: restart = 0; 444: /* simulate XN if need be */ 445: } 446: #ifdef CLEAREOL 447: /* #ifdef INNERSEARCH 448: if (outputok) 449: #endif 450: maybe_eol(); */ /* PWP *//* comment this out for now 451: until I am sure it is 452: needed*/ 453: 454: #endif CLEAREOL 455: } 456: 457: /* handle normal end of output line formalities */ 458: 459: if (highlight == artline) { 460: /* were we highlighting line? */ 461: if (marking == STANDOUT) 462: un_standout(); 463: else 464: un_underline(); 465: highlight = -1; /* no more we are */ 466: } 467: artline++; /* count the line just printed */ 468: if (artline - LINES + 1 > topline) 469: /* did we just scroll top line off? */ 470: topline = artline - LINES + 1; 471: /* then recompute top line # */ 472: } 473: 474: /* determine actual position in file */ 475: 476: if (restart) /* stranded somewhere in the buffer? */ 477: artpos += restart - blinebeg; 478: /* just calculate position */ 479: else /* no, ftell will do */ 480: artpos = ftell(artfp); 481: /* so do ftell */ 482: vwtary(artline,artpos); /* remember pos in file */ 483: } /* end of line loop */ 484: 485: #ifdef INNERSEARCH 486: innersearch = 0; 487: if (hide_everything) { 488: hide_everything = FALSE; 489: *buf = Ctl('l'); 490: goto fake_command; 491: } 492: #endif 493: if (linenum >= 32700)/* did last line have formfeed? */ 494: vwtary(artline-1,-vrdary(artline-1)); 495: /* remember by negating pos in file */ 496: 497: special = FALSE; /* end of page, so reset page length */ 498: firstpage = FALSE; /* and say it is not 1st time thru */ 499: 500: /* extra loop bombout */ 501: 502: if (artpos == artsize) /* did we just now reach EOF? */ 503: return DA_NORM; /* avoid --MORE--(100%) */ 504: 505: /* not done with this article, so pretend we are a pager */ 506: 507: reask_pager: 508: unflush_output(); /* disable any ^O in effect */ 509: standout(); /* enter standout mode */ 510: printf("--MORE--(%ld%%)",(long)(artpos*100/artsize)); 511: un_standout(); /* leave standout mode */ 512: fflush(stdout); 513: /* reinp_pager: /* unused, commented for lint */ 514: eat_typeahead(); 515: #ifdef DEBUGGING 516: if (debug & DEB_CHECKPOINTING) { 517: printf("(%d %d %d)",checkcount,linenum,artline); 518: fflush(stdout); 519: } 520: #endif 521: if (checkcount >= docheckwhen && 522: linenum == LINES && 523: (artline > 40 || checkcount >= docheckwhen+10) ) { 524: /* while he is reading a whole page */ 525: /* in an article he is interested in */ 526: checkcount = 0; 527: checkpoint_rc(); /* update .newsrc */ 528: } 529: collect_subjects(); /* loads subject cache until */ 530: /* input is pending */ 531: mode = 'p'; 532: getcmd(buf); 533: if (errno) { 534: if (LINES < 100 && !int_count) 535: *buf = '\f';/* on CONT fake up refresh */ 536: else { 537: *buf = 'q'; /* on INTR or paper just quit */ 538: } 539: } 540: carriage_return(); 541: #ifndef CLEAREOL 542: erase_eol(); /* and erase the prompt */ 543: #else 544: if (erase_screen && can_home_clear) /* PWP was here */ 545: clear_rest(); 546: else 547: erase_eol(); /* and erase the prompt */ 548: #endif CLEAREOL 549: fflush(stdout); 550: 551: fake_command: /* used by innersearch */ 552: 553: /* parse and process pager command */ 554: 555: switch (page_switch()) { 556: case PS_ASK: /* reprompt "--MORE--..." */ 557: goto reask_pager; 558: case PS_RAISE: /* reparse on article level */ 559: mode = oldmode; 560: return DA_RAISE; 561: case PS_TOEND: /* fast pager loop exit */ 562: mode = oldmode; 563: return DA_TOEND; 564: case PS_NORM: /* display more article */ 565: break; 566: } 567: } /* end of page loop */ 568: } 569: 570: /* process pager commands */ 571: 572: int 573: page_switch() 574: { 575: register char *s; 576: 577: switch (*buf) { 578: case 'd': 579: case Ctl('d'): /* half page */ 580: special = TRUE; 581: slines = LINES / 2 + 1; 582: if (marking && *blinebeg != '\f' 583: #ifdef CUSTOMLINES 584: && (!pagestop || blinebeg != art_buf || 585: !execute(&page_compex,blinebeg)) 586: #endif 587: ) { 588: up_line(); 589: highlight = --artline; 590: restart = blinebeg; 591: artpos = alinebeg; 592: } 593: return PS_NORM; 594: case '!': /* shell escape */ 595: escapade(); 596: return PS_ASK; 597: #ifdef INNERSEARCH 598: case Ctl('i'): 599: gline = 3; 600: sprintf(cmd_buf,"^[^%c]",*blinebeg); 601: compile(&gcompex,cmd_buf,TRUE,TRUE); 602: goto caseG; 603: case Ctl('g'): 604: gline = 3; 605: compile(&gcompex,"^Subject:",TRUE,TRUE); 606: goto caseG; 607: case 'g': /* in-article search */ 608: if (!finish_command(FALSE))/* get rest of command */ 609: return PS_ASK; 610: s = buf+1; 611: if (isspace(*s)) 612: s++; 613: if ((s = compile(&gcompex,s,TRUE,TRUE)) != Nullch) { 614: /* compile regular expression */ 615: printf("\n%s\n",s) FLUSH; 616: return PS_ASK; 617: } 618: carriage_return(); 619: erase_eol(); /* erase the prompt */ 620: /* FALL THROUGH */ 621: caseG: 622: case 'G': { 623: /* ART_LINE lines_to_skip = 0; */ 624: ART_POS start_where; 625: 626: if (gline < 0 || gline > LINES-2) 627: gline = LINES-2; 628: #ifdef DEBUGGING 629: if (debug & DEB_INNERSRCH) 630: printf("Start here? %d >=? %d\n",topline + gline + 1,artline) 631: FLUSH; 632: #endif 633: if (*buf == Ctl('i') || topline+gline+1 >= artline) 634: start_where = artpos; 635: /* in case we had a line wrap */ 636: else { 637: start_where = vrdary(topline+gline+1); 638: if (start_where < 0) 639: start_where = -start_where; 640: } 641: if (start_where < htype[PAST_HEADER].ht_minpos) 642: start_where = htype[PAST_HEADER].ht_minpos; 643: fseek(artfp,(long)start_where,0); 644: innersearch = 0; /* assume not found */ 645: while (fgets(buf, sizeof buf, artfp) != Nullch) { 646: /* lines_to_skip++; NOT USED NOW */ 647: #ifdef DEBUGGING 648: if (debug & DEB_INNERSRCH) 649: printf("Test %s",buf) FLUSH; 650: #endif 651: if (execute(&gcompex,buf) != Nullch) { 652: innersearch = ftell(artfp); 653: break; 654: } 655: } 656: if (!innersearch) { 657: fseek(artfp,artpos,0); 658: fputs("(Not found)",stdout) FLUSH; 659: return PS_ASK; 660: } 661: #ifdef DEBUGGING 662: if (debug & DEB_INNERSRCH) 663: printf("On page? %ld <=? %ld\n",(long)innersearch,(long)artpos) 664: FLUSH; 665: #endif 666: if (innersearch <= artpos) { /* already on page? */ 667: if (innersearch < artpos) { 668: artline = topline+1; 669: while (vrdary(artline) < innersearch) 670: artline++; 671: } 672: highlight = artline - 1; 673: #ifdef DEBUGGING 674: if (debug & DEB_INNERSRCH) 675: printf("@ %d\n",highlight) FLUSH; 676: #endif 677: topline = highlight - gline; 678: if (topline < -1) 679: topline = -1; 680: *buf = '\f'; /* fake up a refresh */ 681: innersearch = 0; 682: return page_switch(); 683: } 684: else { /* who knows how many lines it is? */ 685: do_fseek = TRUE; 686: hide_everything = TRUE; 687: } 688: return PS_NORM; 689: } 690: #else 691: case 'g': case 'G': case Ctl('g'): 692: notincl("g"); 693: return PS_ASK; 694: #endif 695: case '\n': /* one line */ 696: special = TRUE; 697: slines = 2; 698: return PS_NORM; 699: #ifdef ROTATION 700: case 'X': 701: rotate = !rotate; 702: /* FALL THROUGH */ 703: #endif 704: case 'l': 705: case '\f': /* refresh screen */ 706: #ifdef DEBUGGING 707: if (debug & DEB_INNERSRCH) { 708: printf("Topline = %d",topline) FLUSH; 709: gets(buf); 710: } 711: #endif 712: clear(); 713: do_fseek = TRUE; 714: artline = topline; 715: if (artline < 0) 716: artline = 0; 717: firstpage = (topline < 0); 718: return PS_NORM; 719: case 'b': 720: case '\b': /* I like backspace for this -- PWP */ 721: /* Leaving it undocumented in case */ 722: /* I want to steal the key--LAW */ 723: case Ctl('b'): { /* back up a page */ 724: ART_LINE target; 725: 726: #ifndef CLEAREOL 727: clear(); 728: #else 729: if (can_home_clear) /* if we can home do it -- PWP */ 730: home_cursor(); 731: else 732: clear(); 733: 734: #endif CLEAREOL 735: do_fseek = TRUE; /* reposition article file */ 736: target = topline - (LINES - 2); 737: artline = topline; 738: do { 739: artline--; 740: } while (artline >= 0 && artline > target && 741: vrdary(artline-1) >= 0); 742: topline = artline; 743: /* remember top line of screen */ 744: /* (line # within article file) */ 745: if (artline < 0) 746: artline = 0; 747: firstpage = (topline < 0); 748: return PS_NORM; 749: } 750: case 'h': { /* help */ 751: int cmd; 752: 753: if ((cmd = help_page()) > 0) 754: pushchar(cmd); 755: return PS_ASK; 756: } 757: case '\177': 758: case '\0': /* treat del,break as 'n' */ 759: *buf = 'n'; 760: /* FALL THROUGH */ 761: case 'k': case 'K': 762: case 'n': case 'N': case Ctl('n'): 763: case 's': case 'S': 764: case 'u': 765: case 'w': case 'W': 766: case '|': 767: mark_as_read(art); /* mark article as read */ 768: /* FALL THROUGH */ 769: case '#': 770: case '$': 771: case '&': 772: case '-': 773: case '.': 774: case '/': 775: case '1': case '2': case '3': case '4': case '5': 776: case '6': case '7': case '8': case '9': 777: case '=': 778: case '?': 779: case 'c': case 'C': 780: case 'f': case 'F': 781: case 'j': 782: case Ctl('k'): 783: case 'm': case 'M': 784: case 'p': case 'P': case Ctl('p'): 785: case 'Q': 786: case 'r': case 'R': case Ctl('r'): 787: case 'v': 788: case 'Y': 789: #ifndef ROTATION 790: case 'x': case 'X': 791: #endif 792: case Ctl('x'): 793: case '^': 794: 795: #ifdef ROTATION 796: rotate = FALSE; 797: #endif 798: reread = FALSE; 799: do_hiding = TRUE; 800: if (index("nNpP",*buf) == Nullch && 801: index("wWsS!&|/?123456789.",*buf) != Nullch) { 802: setdfltcmd(); 803: standout(); /* enter standout mode */ 804: printf(prompt,mailcall,dfltcmd); 805: /* print prompt, whatever it is */ 806: un_standout(); /* leave standout mode */ 807: putchar(' '); 808: fflush(stdout); 809: } 810: return PS_RAISE; /* and pretend we were at end */ 811: #ifdef ROTATION 812: case 'x': 813: rotate = TRUE; 814: /* FALL THROUGH */ 815: #endif 816: case 'y': 817: case Ctl('v'): /* I like emacs -- PWP */ 818: /* Leaving it undocumented in case */ 819: /* I want to steal the key--LAW */ 820: case ' ': /* continue current article */ 821: if (erase_screen) { /* -e? */ 822: #ifndef CLEAREOL 823: clear(); /* clear screen */ 824: #else 825: if (can_home_clear) /* if we can home do it -- PWP */ 826: home_cursor(); 827: else 828: clear(); /* else clear screen */ 829: 830: #endif CLEAREOL 831: if (*blinebeg != '\f' 832: #ifdef CUSTOMLINES 833: && (!pagestop || blinebeg != art_buf || 834: !execute(&page_compex,blinebeg)) 835: #endif 836: ) { 837: restart = blinebeg; 838: artline--; /* restart this line */ 839: artpos = alinebeg; 840: if (marking) /* and mark repeated line */ 841: highlight = artline; 842: } 843: topline = artline; 844: /* and remember top line of screen */ 845: /* (line # within article file) */ 846: } 847: else if (marking && *blinebeg != '\f' 848: #ifdef CUSTOMLINES 849: && (!pagestop || blinebeg != art_buf || 850: !execute(&page_compex,blinebeg)) 851: #endif 852: ) { 853: /* are we marking repeats? */ 854: up_line(); /* go up one line */ 855: highlight = --artline;/* and get ready to highlight */ 856: restart = blinebeg; /* the old line */ 857: artpos = alinebeg; 858: } 859: return PS_NORM; 860: case 'q': /* quit this article? */ 861: do_hiding = TRUE; 862: return PS_TOEND; 863: default: 864: fputs(hforhelp,stdout) FLUSH; 865: settle_down(); 866: return PS_ASK; 867: } 868: } 869: 870: #ifdef INNERSEARCH 871: bool 872: innermore() 873: { 874: if (artpos < innersearch) { /* not even on page yet? */ 875: #ifdef DEBUGGING 876: if (debug & DEB_INNERSRCH) 877: printf("Not on page %ld < %ld\n",(long)artpos,(long)innersearch) 878: FLUSH; 879: #endif 880: return TRUE; 881: } 882: if (artpos == innersearch) { /* just got onto page? */ 883: isrchline = artline; /* remember first line after */ 884: highlight = artline - 1; 885: #ifdef DEBUGGING 886: if (debug & DEB_INNERSRCH) 887: printf("There it is %ld = %ld, %d @ %d\n",(long)artpos, 888: (long)innersearch,hide_everything,highlight) FLUSH; 889: #endif 890: if (hide_everything) { /* forced refresh? */ 891: topline = highlight - gline; 892: if (topline < -1) 893: topline = -1; 894: return FALSE; /* let refresh do it all */ 895: } 896: } 897: #ifdef DEBUGGING 898: if (debug & DEB_INNERSRCH) 899: printf("Not far enough? %d <? %d + %d\n",artline,isrchline,gline) 900: FLUSH; 901: #endif 902: if (artline < isrchline + gline) { 903: return TRUE; 904: } 905: return FALSE; 906: } 907: #endif