home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume23 / trn / part10 / head.c next >
C/C++ Source or Header  |  1991-08-22  |  9KB  |  399 lines

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