home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / UUPC11XT.ZIP / RN / ART.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-21  |  32.7 KB  |  1,182 lines

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