home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume25 / trn / part03 / head.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-02  |  8.7 KB  |  397 lines

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