home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume13 / vn.jan.88 / part04 / digest.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-01-30  |  5.6 KB  |  304 lines

  1. /*
  2. ** vn news reader.
  3. **
  4. ** digest.c - digest unpacking routines
  5. **
  6. ** see copyright disclaimer / history in vn.c source file
  7. */
  8.  
  9. #include <stdio.h>
  10. #include "config.h"
  11. #include "head.h"
  12. #include "tune.h"
  13. #include "node.h"
  14. #include "page.h"
  15.  
  16. extern int Digest;
  17. extern int L_allow;
  18. extern int C_allow;
  19. extern PAGE Page;
  20.  
  21. extern FILE *vns_aopen();
  22.  
  23. static char *Ext_pool = NULL;
  24. static char *Show[3];
  25.  
  26. static char *Dhead = "Date: ";
  27. static char *Fhead = "From: ";
  28. static char *Lhead = "Lines: ";
  29. static char *Thead = "Subject: ";
  30.  
  31. #define THDLEN 9
  32. #define LHDLEN 7
  33. #define FHDLEN 6
  34. #define DHDLEN 6
  35.  
  36. digest_page (idx,skip)
  37. int idx;
  38. {
  39.     char name[24];
  40.     FILE *fp;
  41.     int i,len,hl;
  42.     char subj[RECLEN],date[RECLEN],from[RECLEN],junk[RECLEN],*str_store();
  43.     long pos;
  44.     ARTHEADER hdr;
  45.  
  46.     Digest = Page.b[idx].art_id;
  47.  
  48.     if ((fp = vns_aopen(Digest,&hdr)) == NULL)
  49.         return (-1);
  50.  
  51.     subj[0] = date[0] = from[0] = junk[0] = '\0';
  52.  
  53.     /* skip over some articles if requested to */
  54.     for (i=skip; i > 0; --i)
  55.     {
  56.         if (dig_advance(fp,from,subj,date,junk,&pos,&hl) < 0)
  57.             return (-1);
  58.     }
  59.  
  60.     for (i=0; i < L_allow &&
  61.             (len = dig_advance(fp,from,subj,date,junk,&pos,&hl)) >= 0; ++i)
  62.     {
  63.         Page.b[i].art_id = i+1+skip;
  64.         Page.b[i].art_mark = ' ';
  65.         subj [C_allow] = '\0';
  66.         from [C_allow] = '\0';
  67.         sprintf (name,"%d",len);
  68.         form_title (date,subj,name,from,100);
  69.         strcpy (Page.b[i].art_t,date);
  70.     }
  71.  
  72.     vns_aclose (fp);
  73.  
  74.     if (i == 0)
  75.         return (-1);
  76.  
  77.     Page.h.artnum = i;
  78.     return (i);
  79. }
  80.  
  81. /*
  82.     returns name of file containing "article", NULL for failure
  83. */
  84. char * digest_extract (s,art,hdr,start)
  85. char *s;
  86. int art;
  87. ARTHEADER *hdr;
  88. long *start;
  89. {
  90.     FILE *fout,*fin;
  91.     long pos;
  92.     int lines,hl;
  93.     char subj[RECLEN],date[RECLEN],from[RECLEN],bufr[RECLEN];
  94.     char extra[RECLEN];
  95.     char *index();
  96.     long ftell();
  97.     char *str_tpool(), *str_tstore();
  98.  
  99.     if (Ext_pool != NULL)
  100.         str_tfree(Ext_pool);
  101.     Ext_pool = str_tpool(3);
  102.  
  103.     if ((fin = vns_aopen(Digest,hdr)) == NULL)
  104.         return (NULL);
  105.  
  106.     for ( ; art > 0; --art)
  107.     {
  108.         from[0] = subj[0] = date[0] = '\0';
  109.         if ((lines = dig_advance(fin,from,subj,date,extra,&pos,&hl)) < 0)
  110.         {
  111.             vns_aclose(fin);
  112.             return (NULL);
  113.         }
  114.     }
  115.  
  116.     tmpnam(s);
  117.  
  118.     if ((fout = fopen(s,"w")) == NULL)
  119.     {
  120.         vns_aclose(fin);
  121.         unlink (s);
  122.         return (NULL);
  123.     }
  124.  
  125.     fseek(fin,0L,0);
  126.  
  127.     hdr->show_num = 0;
  128.     hdr->show = Show;
  129.     hdr->lines = lines;
  130.     hdr->hlines = hl;
  131.     if (subj[0] != '\0')
  132.     {
  133.         sprintf (bufr,"%s%s",Thead,subj);
  134.         Show[hdr->show_num] = str_tstore(Ext_pool,bufr);
  135.         ++(hdr->show_num);
  136.     }
  137.     if (from[0] != '\0')
  138.     {
  139.         sprintf (bufr,"%s%s",Fhead,from);
  140.         Show[hdr->show_num] = str_tstore(Ext_pool,bufr);
  141.         ++(hdr->show_num);
  142.     }
  143.     if (date[0] != '\0')
  144.     {
  145.         sprintf (bufr,"%s%s",Dhead,date);
  146.         Show[hdr->show_num] = str_tstore(Ext_pool,bufr);
  147.         ++(hdr->show_num);
  148.     }
  149.  
  150.     while (fgets(bufr,RECLEN-1,fin) != NULL && bufr[0] != '\n')
  151.     {
  152.         if (strncmp(bufr,Fhead,FHDLEN) == 0)
  153.         {
  154.             fprintf (fout,"%s%s\n",Fhead,from);
  155.             continue;
  156.         }
  157.         if (strncmp(bufr,Thead,THDLEN) == 0)
  158.         {
  159.             fprintf (fout,"%s%s\n",Thead,subj);
  160.             continue;
  161.         }
  162.         if (strncmp(bufr,Dhead,DHDLEN) == 0)
  163.         {
  164.             fprintf (fout,"%s%s\n",Dhead,date);
  165.             continue;
  166.         }
  167.         /* defer line count header - it comes last */
  168.         if (strncmp(bufr,Lhead,LHDLEN) == 0)
  169.             continue;
  170.         fprintf (fout,"%s",bufr);
  171.     }
  172.  
  173.     /* toss in extra header lines, line count header, extra newline */
  174.     fprintf (fout,"%s%s%d\n\n",extra,Lhead,lines);
  175.     *start = ftell(fout);
  176.  
  177.     fseek (fin,pos,0);
  178.  
  179.     while (fgets(bufr,RECLEN-1,fin) != NULL && strncmp(bufr,"--------",8) != 0)
  180.         fprintf(fout,"%s",bufr);
  181.  
  182.     vns_aclose (fin);
  183.     fclose (fout);
  184.     return (s);
  185. }
  186.  
  187. dig_list (s)
  188. char *s;
  189. {
  190.     char *ptr,*out,*new,ns[L_tmpnam],tmp[RECLEN],*strtok();
  191.     ARTHEADER hdr;
  192.     long pos;
  193.     int i;
  194.  
  195.     prinfo ("Extracting articles .....");
  196.     strcpy (tmp,s);
  197.     out = s;
  198.  
  199.     for (ptr = strtok(tmp," "); ptr != NULL; ptr = strtok(NULL," "))
  200.     {
  201.         i = atoi(ptr);
  202.         if ((new = digest_extract(ns,i,&hdr,&pos)) != NULL)
  203.         {
  204.             sprintf (out,"%s ",new);
  205.             out += strlen(new) + 1;
  206.         }
  207.     }
  208.  
  209.     *out = '\0';
  210.  
  211.     if (*s == '\0')
  212.         strcpy (s,"NULLDIGEST");
  213. }
  214.  
  215. dig_ulist (s)
  216. char *s;
  217. {
  218.     char *strtok();
  219.     for (s = strtok(s," "); s != NULL; s = strtok(NULL," "))
  220.         unlink (s);
  221. }
  222.  
  223. /*
  224.     returns # lines in article, -1 for failure
  225.     scans past article, returns position of start.
  226.     also returns "extra" header lines encountered, WITH newlines.
  227.     and counts total header lines.
  228. */
  229. static dig_advance (fp,from,subj,date,extra,pos,hcount)
  230. FILE *fp;
  231. char *from,*subj,*date,*extra;
  232. long *pos;
  233. int *hcount;
  234. {
  235.     char buf[RECLEN];
  236.     char *ptr, *index();
  237.     int len,state,lcount;
  238.  
  239.     *hcount = lcount = state = 0;
  240.     *extra = '\0';
  241.  
  242.     while (fgets(buf,RECLEN-1,fp) != NULL)
  243.     {
  244.         buf[(len = strlen(buf) - 1)] = '\0';
  245.         for (--len ; len >= 0 && buf[len] == ' ' || buf[len] == '\t'; --len)
  246.             buf[len] = '\0';
  247.         ++len;
  248.  
  249.         switch(state)
  250.         {
  251.         case 0:
  252.             /* skip blank lines before header */
  253.             if (len == 0)
  254.                 break;
  255.             state = 1;    /* fall through */
  256.         case 1:
  257.             ++(*hcount);
  258.             if (strncmp(buf,Fhead,FHDLEN) == 0)
  259.             {
  260.                 strcpy (from,buf+FHDLEN);
  261.                 break;
  262.             }
  263.             if (strncmp(buf,Thead,THDLEN) == 0)
  264.             {
  265.                 strcpy (subj,buf+THDLEN);
  266.                 break;
  267.             }
  268.             if (strncmp(buf,Dhead,DHDLEN) == 0)
  269.             {
  270.                 strcpy (date,buf+DHDLEN);
  271.                 break;
  272.             }
  273.             /* put wierd header lines in extra */
  274.             if ((ptr = index(buf,':')) != NULL)
  275.             {
  276.                 *ptr = '\0';
  277.                 if (index(buf, ' ') == NULL)
  278.                 {
  279.                     *ptr = ':';
  280.                     sprintf(extra,"%s\n",buf);
  281.                     extra += strlen(extra);
  282.                     break;
  283.                 }
  284.                 *ptr = ':';
  285.             }
  286.             state = 2;
  287.             --(*hcount);
  288.  
  289.             /* remember the newline we lopped off */
  290.             *pos = ftell(fp)-strlen(buf)-1;    /* fall through */
  291.         case 2:
  292.             ++lcount;
  293.             if (strncmp("--------",buf,8) == 0)
  294.             {
  295.                 --lcount;
  296.                 return (lcount);
  297.             }
  298.             break;
  299.         }
  300.     }
  301.  
  302.     return (-1);
  303. }
  304.