home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / TELECOM / rn_4_3_blars.lzh / head.c < prev    next >
Text File  |  1990-08-26  |  9KB  |  387 lines

  1. /* $Header: head.c,v 4.3.2.5 90/03/22 23:04:22 sob Exp $
  2.  *
  3.  * $Log:    head.c,v $
  4.  * Revision 4.3.2.5  90/03/22  23:04:22  sob
  5.  * Fixes provided by Wayne Davison <drivax!davison>
  6.  * 
  7.  * Revision 4.3.2.4  89/11/27  01:30:35  sob
  8.  * Altered NNTP code per ideas suggested by Bela Lubkin
  9.  * <filbo@gorn.santa-cruz.ca.us>
  10.  * 
  11.  * Revision 4.3.2.3  89/11/26  22:53:52  sob
  12.  * Add new patches to make RRN be faster.
  13.  * 
  14.  * Revision 4.3.2.2  89/11/08  01:17:46  sob
  15.  * Added changes to insure that this will compile for RN or RRN with no
  16.  * changes to the source code.
  17.  * 
  18.  * Revision 4.3.2.1  89/11/06  00:37:18  sob
  19.  * Added RRN support from NNTP 1.5
  20.  * 
  21.  * Revision 4.3.1.2  85/05/10  13:47:25  lwall
  22.  * Added debugging stuff.
  23.  * 
  24.  * Revision 4.3.1.1  85/05/10  11:32:30  lwall
  25.  * Branch for patches.
  26.  * 
  27.  * Revision 4.3  85/05/01  11:38:21  lwall
  28.  * Baseline for release with 4.3bsd.
  29.  * 
  30.  */
  31.  
  32. #include "EXTERN.h"
  33. #include "common.h"
  34. #include "artio.h"
  35. #include "bits.h"
  36. #ifdef SERVER
  37. #include "server.h"
  38. #endif
  39. #include "util.h"
  40. #include "INTERN.h"
  41. #include "head.h"
  42.  
  43. bool first_one;        /* is this the 1st occurance of this header line? */
  44.  
  45. static char htypeix[26] =
  46.     {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  47.  
  48. void
  49. head_init()
  50. {
  51.     register int i;
  52.  
  53.     for (i=HEAD_FIRST+1; i<HEAD_LAST; i++)
  54.     htypeix[*htype[i].ht_name - 'a'] = i;
  55. }
  56.  
  57. #ifdef DEBUGGING
  58. dumpheader(where)
  59. char *where;
  60. {
  61.     register int i;
  62.  
  63.     printf("header: %d %s", parsed_art, where);
  64.  
  65.     for (i=0; i<HEAD_LAST; i++) {
  66.     printf("%15s %4d %4d %03o\n",htype[i].ht_name,
  67.         htype[i].ht_minpos,
  68.         htype[i].ht_maxpos,
  69.         htype[i].ht_flags) FLUSH;
  70.     }
  71. }
  72. #endif
  73.  
  74. int
  75. set_line_type(bufptr,colon)
  76. char *bufptr;
  77. register char *colon;
  78. {
  79.     char lc[LONGKEY+3];
  80.     register char *t, *f;
  81.     register int i, len;
  82.  
  83.     if (colon-bufptr > LONGKEY+2)
  84.     return SOME_LINE;
  85.  
  86.     for (t=lc,f=bufptr; f<colon; f++, t++) {
  87.     if (isspace(*f))
  88.     /* guard against space before : */
  89.         break;
  90.     *t = isupper(*f) ? tolower(*f) : *f;
  91.     }
  92.     *t = '\0';
  93.     f = lc;                /* get lc into register */
  94.     len = t - f;
  95.  
  96.     /* now scan the headtype table, backwards so we don't have to supply an
  97.      * extra terminating value, using first letter as index, and length as
  98.      * optimization to avoid calling subroutine strEQ unnecessarily.  Hauls.
  99.      */
  100.     
  101.     if (islower(*f)) {
  102.     for (i = htypeix[*f - 'a']; *htype[i].ht_name == *f; --i) {
  103.         if (len == htype[i].ht_length && strEQ(f, htype[i].ht_name)) {
  104.         return i;
  105.         }
  106.     }
  107.     }
  108.     return SOME_LINE;
  109. }
  110.  
  111. void
  112. start_header(artnum)
  113. ART_NUM artnum;
  114. {
  115.     register int i;
  116.  
  117. #ifdef DEBUGGING
  118.     if (debug & DEB_HEADER)
  119.     dumpheader("start_header\n");
  120. #endif
  121.     for (i=0; i<HEAD_LAST; i++) {
  122.     htype[i].ht_minpos = -1;
  123.     htype[i].ht_maxpos = 0;
  124.     }
  125.     in_header = SOME_LINE;
  126.     first_one = FALSE;
  127. #ifdef ASYNC_PARSE
  128.     parsed_art = artnum;
  129. #endif
  130. }
  131.  
  132. bool
  133. parseline(art_buf,newhide,oldhide)
  134. char *art_buf;
  135. int newhide, oldhide;
  136. {
  137.     if (*art_buf == ' ' || *art_buf == '\t')
  138.                     /* header continuation line? */
  139.     return oldhide;
  140.     else {                /* maybe another header line */
  141.     char *s;
  142.  
  143.     if (first_one) {        /* did we just pass 1st occurance? */
  144.         first_one = FALSE;
  145.         htype[in_header].ht_maxpos = artpos;
  146.                     /* remember where line left off */
  147.     }
  148.     s = index(art_buf,':');
  149.     if (s == Nullch) {
  150.                 /* is it the end of the header? */
  151.         htype[PAST_HEADER].ht_minpos =
  152.         (*art_buf == '\n') ? ftell(artfp) : artpos;
  153.                 /* remember where body starts */
  154.         in_header = PAST_HEADER;
  155.     }
  156.     else {    /* it is a new header line */
  157.         in_header = set_line_type(art_buf,s);
  158.         first_one = (htype[in_header].ht_minpos < 0);
  159.         if (first_one)
  160.         htype[in_header].ht_minpos = artpos;
  161. #ifdef DEBUGGING
  162.         if (debug & DEB_HEADER)
  163.         dumpheader(art_buf);
  164. #endif
  165.         if (htype[in_header].ht_flags & HT_HIDE)
  166.         return newhide;
  167.     }
  168.     }
  169.     return FALSE;            /* don't hide this line */
  170. }
  171.  
  172. #ifdef ASYNC_PARSE
  173. int
  174. parse_maybe(artnum)
  175. ART_NUM artnum;
  176. {
  177.     char tmpbuf[LBUFLEN];
  178.  
  179.     if (parsed_art == artnum)
  180.     return 0;
  181.     /* no maybe about it now */
  182. #ifdef SERVER
  183.     if (nntpopen(artnum,HEAD) == Nullfp) {
  184. #else
  185.     if (artopen(artnum) == Nullfp) {
  186. #endif
  187.     return -1;
  188.     }
  189.     start_header(artnum);
  190.     while (in_header) {
  191.     artpos = ftell(artfp);
  192.     if (fgets(tmpbuf,LBUFLEN,artfp) == Nullch)
  193.         break;
  194.     parseline(tmpbuf,FALSE,FALSE);
  195.     }
  196.     in_header = PAST_HEADER;
  197.     return 0;
  198. }
  199. #endif
  200.  
  201. /* get the subject line for an article */
  202.  
  203. char *
  204. fetchsubj(artnum,current_subject,copy)
  205. ART_NUM artnum;                /* article to get subject from */
  206. bool current_subject;            /* is it in a parsed header? */
  207. bool copy;                /* do you want it savestr()ed? */
  208. {
  209.     char *s = Nullch, *t;
  210. #ifdef SERVER
  211.     static int xhdr = 1;        /* Can we use xhdr command? */
  212.     int eoo;                /* End of server output */
  213.     char ser_line[256];
  214. #endif SERVER
  215.  
  216. #ifdef CACHESUBJ
  217.     if (!subj_list) {
  218.     register ART_NUM i;
  219.     
  220.  
  221. #ifndef lint
  222.     subj_list =
  223.       (char**)safemalloc((MEM_SIZE)((OFFSET(lastart)+2)*sizeof(char *)));
  224. #endif lint
  225.     for (i=0; i<=OFFSET(lastart); i++)
  226.         subj_list[i] = Nullch;
  227.     }
  228.     if (!artnum || artnum > lastart)
  229.     s = nullstr;
  230.     else
  231.     s = subj_list[OFFSET(artnum)];
  232. #endif
  233.     if (s == Nullch) {
  234.     if (current_subject) {
  235.         s = fetchlines(artnum,SUBJ_LINE);
  236. #ifdef CACHESUBJ
  237.         subj_list[OFFSET(artnum)] = s;
  238. #endif
  239.     }
  240.     else {
  241.         s = safemalloc((MEM_SIZE)256);
  242.         *s = '\0';
  243. #ifdef SERVER
  244.         if (xhdr) {
  245.             sprintf(ser_line, "XHDR subject %ld", artnum);
  246.             put_server(ser_line);
  247.         if (get_server(ser_line, sizeof (ser_line)) >= 0) {
  248.             if (ser_line[0] == CHAR_FATAL) {
  249.                 xhdr = 0;
  250.             } else {
  251.                 while (get_server(ser_line, sizeof (ser_line)) >= 0) {
  252.                 if (ser_line[0] == '.')
  253.                     break;
  254.                 else {
  255.                     t = index(ser_line, ' ');
  256.                     if (t++) {
  257.                     strcpy(s, t);
  258.                     if (t = index(s, '\r'))
  259.                         *t = '\0';
  260.                     }
  261.                 }
  262.                 }
  263.             }
  264.         } else {
  265.             fprintf(stderr,
  266.             "rrn: Unexpected close of server socket.\n");
  267.             finalize(1);
  268.         }
  269.         }
  270.  
  271.         if (!xhdr) {
  272.         sprintf(ser_line, "HEAD %ld", artnum);
  273.         put_server(ser_line);
  274.         eoo = 0;
  275.         if (get_server(ser_line, 256) >= 0 && ser_line[0] == CHAR_OK) {
  276.             do {
  277.             if (get_server(s, 256) < 0 || (*s == '.')) {
  278.             strcpy(s, "Title: \n");
  279.             eoo = 1;
  280.                 }
  281.             } while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8));
  282.  
  283.             if (!eoo)
  284.             while (get_server(ser_line, sizeof (ser_line)) >= 0 &&
  285.                 ser_line[0] != '.');
  286.             t = index(s,':')+1;
  287.             while (*t == ' ') t++;
  288.             strcpy(s, t);
  289.             }
  290.         }
  291. #else not SERVER
  292.         if (artopen(artnum) != Nullfp) {
  293.         do {
  294.             if (fgets(s,256,artfp) == Nullch)
  295.             strcpy(s, "Title: \n");
  296.         } while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8));
  297.  
  298.         s[strlen(s)-1] = '\0';
  299.         t = index(s,':')+1;
  300.         while (*t == ' ') t++;
  301.         strcpy(s, t);
  302.         }
  303. #endif
  304.         s = saferealloc(s, (MEM_SIZE)strlen(s)+1);
  305. #ifdef CACHESUBJ
  306.         subj_list[OFFSET(artnum)] = s;
  307. #endif 
  308.     }
  309.     }
  310. #ifdef CACHESUBJ
  311.     if (copy) {
  312.     t = savestr(s);
  313.     return t;
  314.     }
  315.     else
  316.     return s;
  317. #else
  318.     if (copy)
  319.     return s;
  320.     else {
  321.     safecpy(cmd_buf,s,CBUFLEN);    /* hope this is okay--we're */
  322.     free(s);
  323.     return cmd_buf;            /* really scraping for space here */
  324.     }
  325. #endif
  326. }
  327.  
  328. /* get header lines from an article */
  329.  
  330. char *
  331. fetchlines(artnum,which_line)
  332. ART_NUM artnum;                /* article to get line from */
  333. int which_line;                /* type of line desired */
  334. {
  335.     char *newbuf, *t, tmp_buf[LBUFLEN];
  336.     register ART_POS curpos;
  337.     int size;
  338.     register ART_POS firstpos;
  339.     register ART_POS lastpos;
  340.     
  341. #ifdef ASYNC_PARSE
  342.     if (parse_maybe(artnum))
  343.     artnum = 0;
  344. #endif
  345.     firstpos = htype[which_line].ht_minpos;
  346.     lastpos = htype[which_line].ht_maxpos;
  347. #ifdef SERVER
  348.     if (!artnum || firstpos < 0 || nntpopen(artnum,HEAD) == Nullfp) {
  349. #else
  350.     if (!artnum || firstpos < 0 || artopen(artnum) == Nullfp) {
  351. #endif
  352.     newbuf = safemalloc((unsigned int)1);
  353.     *newbuf = '\0';
  354.     return newbuf;
  355.     }
  356. #ifndef lint
  357.     size = lastpos - firstpos + 1;
  358. #else
  359.     size = Null(int);
  360. #endif lint
  361. #ifdef DEBUGGING
  362.     if (debug && (size < 1 || size > 1000)) {
  363.     printf("Firstpos = %ld, lastpos = %ld\n",(long)firstpos,(long)lastpos);
  364.     gets(tmp_buf);
  365.     }
  366. #endif
  367.     newbuf = safemalloc((unsigned int)size);
  368.     *newbuf = '\0';
  369.     fseek(artfp,firstpos,0);
  370.     for (curpos = firstpos; curpos < lastpos; curpos = ftell(artfp)) {
  371.     if (fgets(tmp_buf,LBUFLEN,artfp) == Nullch)
  372.         break;
  373.     if (*tmp_buf == ' ' || *tmp_buf == '\t')
  374.         t = tmp_buf;
  375.     else
  376.         t = index(tmp_buf,':')+1;
  377.     if (t == Nullch)
  378.         break;
  379.     else {
  380.         while (*t == ' ' || *t == '\t') t++;
  381.         safecat(newbuf,t,size);
  382.     }
  383.     }
  384.     return newbuf;
  385. }
  386.  
  387.