home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / trn_12.zip / src / head.c < prev    next >
C/C++ Source or Header  |  1993-12-04  |  11KB  |  429 lines

  1. /* $Id: head.c,v 4.4.4.1 1992/02/23 21:25:39 sob PATCH_4 sob $
  2.  *
  3.  * $Log: head.c,v $
  4.  * Revision 4.4.4.1  1992/02/23  21:25:39  sob
  5.  * Patch level 4
  6.  *
  7.  * Revision 4.4.3.1  1992/02/01  03:09:32  sob
  8.  * Release 4.4 Patchlevel 3
  9.  *
  10.  * Revision 4.4  1991/09/09  20:18:23  sob
  11.  * release 4.4
  12.  *
  13.  *
  14.  * 
  15.  */
  16. /* This software is Copyright 1991 by Stan Barber. 
  17.  *
  18.  * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  19.  * use this software as long as: there is no monetary profit gained
  20.  * specifically from the use or reproduction of this software, it is not
  21.  * sold, rented, traded or otherwise marketed, and this copyright notice is
  22.  * included prominently in any copy made. 
  23.  *
  24.  * The author make no claims as to the fitness or correctness of this software
  25.  * for any use whatsoever, and it is provided as is. Any use of this software
  26.  * is at the user's own risk. 
  27.  */
  28.  
  29. #include "EXTERN.h"
  30. #include "common.h"
  31. #include "artio.h"
  32. #include "bits.h"
  33. #ifdef SERVER
  34. #include "server.h"
  35. #endif
  36. #include "util.h"
  37. #include "INTERN.h"
  38. #include "head.h"
  39.  
  40. bool first_one;        /* is this the 1st occurance of this header line? */
  41.  
  42. static char htypeix[26] =
  43.     {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};
  44.  
  45. void
  46. head_init()
  47. {
  48.     register int i;
  49.  
  50.     for (i=HEAD_FIRST+1; i<HEAD_LAST; i++)
  51.     htypeix[*htype[i].ht_name - 'a'] = i;
  52. }
  53.  
  54. #ifdef DEBUGGING
  55. void
  56. dumpheader(where)
  57. char *where;
  58. {
  59.     register int i;
  60.  
  61.     printf("header: %d %s", parsed_art, where);
  62.  
  63.     for (i=0; i<HEAD_LAST; i++) {
  64.     printf("%15s %4d %4d %03o\n",htype[i].ht_name,
  65.         htype[i].ht_minpos,
  66.         htype[i].ht_maxpos,
  67.         htype[i].ht_flags) ; FLUSH;
  68.     }
  69. }
  70. #endif
  71.  
  72. int
  73. set_line_type(bufptr,colon)
  74. char *bufptr;
  75. register char *colon;
  76. {
  77.     char lc[LONGKEY+3];
  78.     register char *t, *f;
  79.     register int i, len;
  80.  
  81.     if (colon-bufptr > LONGKEY+2)
  82.     return SOME_LINE;
  83.  
  84.     for (t=lc,f=bufptr; f<colon; f++, t++) {
  85.     if (isspace(*f))
  86.     /* guard against space before : */
  87.         break;
  88.     *t = isupper(*f) ? tolower(*f) : *f;
  89.     }
  90.     *t = '\0';
  91.     f = lc;                /* get lc into register */
  92.     len = t - f;
  93.  
  94.     /* now scan the headtype table, backwards so we don't have to supply an
  95.      * extra terminating value, using first letter as index, and length as
  96.      * optimization to avoid calling subroutine strEQ unnecessarily.  Hauls.
  97.      */
  98.     
  99.     if (islower(*f)) {
  100.     for (i = htypeix[*f - 'a']; *htype[i].ht_name == *f; --i) {
  101.         if (len == htype[i].ht_length && strEQ(f, htype[i].ht_name)) {
  102.         return i;
  103.         }
  104.     }
  105.     }
  106.     return SOME_LINE;
  107. }
  108.  
  109. void
  110. start_header(artnum)
  111. ART_NUM artnum;
  112. {
  113.     register int i;
  114.  
  115. #ifdef DEBUGGING
  116.     if (debug & 4)
  117.     dumpheader("start_header\n");
  118. #endif
  119.     for (i=0; i<HEAD_LAST; i++) {
  120.     htype[i].ht_minpos = -1;
  121.     htype[i].ht_maxpos = 0;
  122.     }
  123.     in_header = SOME_LINE;
  124.     first_one = FALSE;
  125. #ifdef ASYNC_PARSE
  126.     parsed_art = artnum;
  127. #endif
  128. }
  129.  
  130. bool
  131. parseline(art_buf,newhide,oldhide)
  132. char *art_buf;
  133. int newhide, oldhide;
  134. {
  135.     if (*art_buf == ' ' || *art_buf == '\t')
  136.                     /* header continuation line? */
  137.     return oldhide;
  138.     else {                /* maybe another header line */
  139.     char *s;
  140.  
  141.     if (first_one) {        /* did we just pass 1st occurance? */
  142.         first_one = FALSE;
  143.         htype[in_header].ht_maxpos = artpos;
  144.                     /* remember where line left off */
  145.     }
  146.     s = index(art_buf,':');
  147.     if (s == Nullch) {
  148.                 /* is it the end of the header? */
  149.         htype[PAST_HEADER].ht_minpos =
  150.         (*art_buf == '\n') ? ftell(artfp) : artpos;
  151.                 /* remember where body starts */
  152.         in_header = PAST_HEADER;
  153.     }
  154.     else {    /* it is a new header line */
  155.         in_header = set_line_type(art_buf,s);
  156.         first_one = (htype[in_header].ht_minpos < 0);
  157.         if (first_one)
  158.         htype[in_header].ht_minpos = artpos;
  159. #ifdef DEBUGGING
  160.         if (debug & 4)
  161.         dumpheader(art_buf);
  162. #endif
  163.         if (htype[in_header].ht_flags & HT_HIDE)
  164.         return newhide;
  165.     }
  166.     }
  167.     return FALSE;            /* don't hide this line */
  168. }
  169.  
  170. #ifdef ASYNC_PARSE
  171. int
  172. parse_maybe(artnum)
  173. ART_NUM artnum;
  174. {
  175.     char tmpbuf[LBUFLEN];
  176.  
  177.     if (parsed_art == artnum)
  178.     return 0;
  179.     if (artnum > lastart)
  180.     return -1;
  181.     /* no maybe about it now */
  182. #ifdef SERVER
  183.     if (nntpopen(artnum,GET_HEADER) == 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_int current_subject;        /* is it in a parsed header? */
  207. bool_int copy;                /* do you want it savestr()ed? */
  208. {
  209.     char *s = Nullch, *t;
  210.     int counter;         /*** OS2: License to kill CTRL-M ... */
  211. #ifdef SERVER
  212.     static int xhdr = 1;        /* Can we use xhdr command? */
  213.     int eoo;                /* End of server output */
  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 < absfirst || 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)LBUFLEN);
  242.         *s = '\0';
  243. #ifdef SERVER
  244.         if (xhdr) {
  245.             sprintf(ser_line, "XHDR subject %ld", artnum);
  246.             put_server(ser_line);
  247. #ifdef DEBUGGING
  248.         if (debug & DEB_NNTP)
  249.             printf(">%s\n", ser_line) ; FLUSH;
  250. #endif
  251.         if (nntp_get(ser_line, sizeof (ser_line)) >= 0) {
  252. #ifdef DEBUGGING
  253.             if (debug & DEB_NNTP)
  254.                 printf("<%s\n", ser_line) ; FLUSH;
  255. #endif
  256.             if (ser_line[0] == CHAR_FATAL) {
  257.                 fprintf(stderr,"\nrrn: %s\n",ser_line);
  258.                 finalize(1);
  259. /*                xhdr = 0; */
  260.             } else {
  261.                 while (nntp_get(ser_line, sizeof (ser_line)) >= 0) {
  262. #ifdef DEBUGGING
  263.                 if (debug & DEB_NNTP)
  264.                     printf("<%s\n", ser_line) ; FLUSH;
  265. #endif
  266.                 if (ser_line[0] == '.')
  267.                     break;
  268.                 else {
  269.                     t = index(ser_line, ' ');
  270.                     if (t++) {
  271.                     strcpy(s, t);
  272.                     if (t = index(s, '\r'))
  273.                         *t = '\0';
  274.                     }
  275.                 }
  276.                 }
  277.             }
  278.         } else {
  279.             fprintf(stderr,
  280.             "\nrrn: Unexpected close of server socket.\n");
  281.             finalize(1);
  282.         }
  283.         }
  284.  
  285.         if (!xhdr) {
  286.         sprintf(ser_line, "HEAD %ld", artnum);
  287.         put_server(ser_line);
  288. #ifdef DEBUGGING
  289.         if (debug & DEB_NNTP)
  290.             printf(">%s\n", ser_line) ; FLUSH;
  291. #endif
  292.         eoo = 0;
  293.         if (nntp_get(ser_line, sizeof (ser_line)) >= 0 && 
  294.             ser_line[0] == CHAR_OK) {
  295.             do {
  296.             if (nntp_get(s, LBUFLEN) < 0 || (*s == '.')) {
  297.             strcpy(s, "Title: \n");
  298.             eoo = 1;
  299.                 }
  300.             } while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8));
  301.  
  302.             if (!eoo)
  303.             while (nntp_get(ser_line, sizeof (ser_line)) >= 0 &&
  304.                 ser_line[0] != '.');
  305.             t = index(s,':')+1;
  306.             while (*t == ' ') t++;
  307.             strcpy(s, t);
  308.             }
  309.         }
  310. #else /* not SERVER */
  311.         if (artopen(artnum) != Nullfp) {
  312.         do {
  313.             if (fgets(s,LBUFLEN,artfp) == Nullch)
  314.             strcpy(s, "Title: \n");
  315.         } while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8));
  316.  
  317. /*** OS2: We need another CTRL-M-Killer. Please fix, when fseek works
  318.           fine with text files ***/
  319.  
  320.             for (counter = 0; counter <= strlen(s); counter++)
  321.                 if ((s[counter] == '\r') &&
  322.                     (s[counter+1] == '\n')) {
  323.                     for (; s[counter] != '\0'; counter++)
  324.                         s[counter] = s[counter+1];
  325.                 }
  326.  
  327.         s[strlen(s)-1] = '\0';
  328.         t = index(s,':')+1;
  329.         while (*t == ' ') t++;
  330.         strcpy(s, t);
  331.         }
  332. #endif
  333.         s = saferealloc(s, (MEM_SIZE)strlen(s)+1);
  334. #ifdef CACHESUBJ
  335.         subj_list[OFFSET(artnum)] = s;
  336. #endif 
  337.     }
  338.     }
  339. #ifdef CACHESUBJ
  340.     if (copy) {
  341.     t = savestr(s);
  342.     return t;
  343.     }
  344.     else
  345.     return s;
  346. #else
  347.     if (copy)
  348.     return s;
  349.     else {
  350.     safecpy(cmd_buf,s,CBUFLEN);    /* hope this is okay--we're */
  351.     free(s);
  352.     return cmd_buf;            /* really scraping for space here */
  353.     }
  354. #endif
  355. }
  356.  
  357. /* get header lines from an article */
  358.  
  359. char *
  360. fetchlines(artnum,which_line)
  361. ART_NUM artnum;                /* article to get line from */
  362. int which_line;                /* type of line desired */
  363. {
  364.     char *newbuf, *t, tmp_buf[LBUFLEN];
  365.     register ART_POS curpos;
  366.     int size;
  367.     register ART_POS firstpos;
  368.     register ART_POS lastpos;
  369.     
  370.     int counter;         /*** OS2: License to kill CTRL-M ... */
  371.  
  372. #ifdef ASYNC_PARSE
  373.     if (parse_maybe(artnum))
  374.     artnum = 0;
  375. #endif
  376.     firstpos = htype[which_line].ht_minpos;
  377.     lastpos = htype[which_line].ht_maxpos;
  378. #ifdef SERVER
  379.     if (!artnum || firstpos < 0 || nntpopen(artnum,GET_HEADER) == Nullfp) {
  380. #else
  381.     if (!artnum || firstpos < 0 || artopen(artnum) == Nullfp) {
  382. #endif
  383.     newbuf = safemalloc((unsigned int)1);
  384.     *newbuf = '\0';
  385.     return newbuf;
  386.     }
  387. #ifndef lint
  388.     size = lastpos - firstpos + 1;
  389. #else
  390.     size = Null(int);
  391. #endif /* lint */
  392. #ifdef DEBUGGING
  393.     if (debug && (size < 1 || size > 1000)) {
  394.     printf("Firstpos = %ld, lastpos = %ld\n",(long)firstpos,(long)lastpos);
  395.     gets(tmp_buf);
  396.     }
  397. #endif
  398.     newbuf = safemalloc((unsigned int)size);
  399.     *newbuf = '\0';
  400.     fseek(artfp,firstpos,0);
  401.     for (curpos = firstpos; curpos < lastpos; curpos = ftell(artfp)) {
  402.     if (fgets(tmp_buf,LBUFLEN,artfp) == Nullch)
  403.         break;
  404.  
  405. /*** OS2: We need another CTRL-M-Killer. Please fix, when fseek works
  406.           fine with text files ***/
  407.  
  408.             for (counter = 0; counter <= strlen(tmp_buf); counter++)
  409.                 if ((tmp_buf[counter] == '\r') &&
  410.                     (tmp_buf[counter+1] == '\n')) {
  411.                     for (; tmp_buf[counter] != '\0'; counter++)
  412.                         tmp_buf[counter] = tmp_buf[counter+1];
  413.                 }
  414.  
  415.     if (*tmp_buf == ' ' || *tmp_buf == '\t')
  416.         t = tmp_buf;
  417.     else {
  418.         t = index(tmp_buf,':');
  419.         if (t == Nullch)
  420.         break;
  421.         t++;
  422.     }
  423.     while (*t == ' ' || *t == '\t') t++;
  424.     safecat(newbuf,t,size);
  425.     }
  426.     return newbuf;
  427. }
  428.  
  429.