home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume36 / uqwk / part01 / news.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-11  |  6.1 KB  |  335 lines

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4. #include <string.h>
  5. #include "uqwk.h"
  6. /*
  7.  *  All sorts of stuff to do news processing
  8.  */
  9.  
  10. DoNews ()
  11. /*
  12.  *  Collect unread news into QWK packet
  13.  */
  14. {
  15.     struct act_ent *ap;
  16.     struct nrc_ent *np;
  17.  
  18.     /* Read .newsrc file */
  19.     if (!ReadNewsrc()) return (0);
  20.  
  21.     /* And active file */
  22.     if (!ReadActive()) return (0);
  23.  
  24.     /* Look through the newsrc file */
  25.     np = nrc_list;
  26.     while (np != NULL)
  27.     {
  28.         /* Check if too many blocks already */
  29.         if ( (blk_cnt >= max_blks) && (max_blks > 0) )
  30.         {
  31.             return (0);
  32.         }
  33.  
  34.         if ( (np->subscribed) &&
  35.              (NULL != (ap = FindActive (np->name))) )
  36.         {
  37.             /* Do this group */
  38.             DoGroup (np, ap);
  39.         }
  40.         np = np->next;
  41.     }
  42. }
  43.  
  44. int ReadNewsrc()
  45. /*
  46.  *  Read the .newsrc file
  47.  */
  48. {
  49.     char group_name[PATH_LEN];
  50.     struct nrc_ent *np;
  51.     int n, c;
  52.  
  53.     /* Don't bother if we've alread read it */
  54.     if (nrc_list != NULL) return (1);
  55.  
  56.     /* Open it */
  57.     if (NULL == (nrc_fd = fopen (nrc_file, "r")))
  58.     {
  59.         fprintf (stderr, "%s: can't open %s\n", progname, nrc_file);
  60.         return (0);
  61.     }
  62.  
  63.     /* Read through */
  64.     while (NULL != Fgets (buf, BUF_LEN, nrc_fd))
  65.     {
  66.         /* Allocate a new nrc entry */
  67.         np = (struct nrc_ent *) malloc (sizeof (struct nrc_ent));
  68.         if (np == NULL) OutOfMemory();
  69.  
  70.         /* Parse group name */
  71.         sscanf (buf, "%s", group_name);
  72.         n = strlen (group_name);
  73.  
  74.         if (group_name[n-1] == ':')
  75.         {
  76.             np->subscribed = 1;
  77.         }
  78.         else
  79.         {
  80.             np->subscribed = 0;
  81.         }
  82.  
  83.         group_name[n-1] = 0;
  84.         np->name = (char *) malloc (n);
  85.         if (np->name == NULL) OutOfMemory();
  86.         strcpy (np->name, group_name);
  87.  
  88.         /* Hi article number */
  89.         np->hi = LastInt (buf);
  90.  
  91.         /* Add to nrc list */
  92.         np->next = nrc_list;
  93.         nrc_list = np;
  94.     }
  95.  
  96.     /* Walk through the nrc list, assign conference numbers */
  97.     np = nrc_list;
  98.     c = 0;
  99.     while (np != NULL)
  100.     {
  101.         np->conf = c;
  102.         c++;
  103.         np = np->next;
  104.     }
  105.  
  106.     fclose (nrc_fd);
  107.     return (1);
  108. }
  109.  
  110. int ReadActive()
  111. /*
  112.  *  Read active file
  113.  */
  114. {
  115.     char group_name[PATH_LEN];
  116.     struct act_ent *ap;
  117.     int n;
  118.  
  119.     /* Don't bother if it's already here */
  120.     if (act_list != NULL) return (1);
  121.  
  122.     /* Open the active file */
  123.     if (NULL == (act_fd = fopen (act_file, "r")))
  124.     {
  125.         fprintf (stderr, "%s: can't open %s\n", progname, act_file);
  126.         return (0);
  127.     }
  128.  
  129.     /* Read through it */
  130.     while (NULL != Fgets (buf, BUF_LEN, act_fd))
  131.     {
  132.         /* Get new act entry */
  133.         ap = (struct act_ent *) malloc (sizeof (struct act_ent));
  134.         if (ap == NULL) OutOfMemory();
  135.  
  136.         /* Parse name, message numbers */
  137.         sscanf (buf, "%s %d %d", group_name, &ap->hi, &ap->lo);
  138.         ap->name = (char *) malloc (1+strlen(group_name));
  139.         if (ap->name == NULL) OutOfMemory();
  140.         strcpy (ap->name, group_name);
  141.  
  142.         /* Add to list */
  143.         ap->next = act_list;
  144.         act_list = ap;
  145.     }
  146.  
  147.     fclose (act_fd);
  148.     return (1);
  149. }
  150.  
  151. struct act_ent *FindActive (c)
  152. char *c;
  153. /*
  154.  *  Look for group's active entry given group name
  155.  */
  156. {
  157.     struct act_ent *ap;
  158.  
  159.     ap = act_list;
  160.     while (NULL != ap)
  161.     {
  162.         if (!strcmp (c, ap->name)) return (ap);
  163.         ap = ap->next;
  164.     }
  165.     return (NULL);
  166. }
  167.  
  168. DoGroup (np, ap)
  169. struct nrc_ent *np;
  170. struct act_ent *ap;
  171. /*
  172.  *  Process given group
  173.  */
  174. {
  175.     char news_path[PATH_LEN];
  176.     char art_file[PATH_LEN];
  177.     int i, n;
  178.  
  179.     printf ("%s: %s\n", progname, np->name);
  180.  
  181.     /* Make a new conference with this name */
  182.     NewConference (np->name);
  183.  
  184.     /* Construct path name for articles in this group */
  185.     strcpy (news_path, news_dir);
  186.     strcat (news_path, "/");
  187.     strcat (news_path, np->name);
  188.     strcat (news_path, "/");
  189.     n = strlen (news_path);
  190.     for (i=0; i<n; i++) if (news_path[i] == '.') news_path[i] = '/';
  191.  
  192.     /* If highest read article is greater than highest available
  193.        article, assume group has been reset */
  194.     if (np->hi > ap->hi) np->hi = ap->lo;
  195.  
  196.     /* Look through unread articles */
  197.     for (i=np->hi+1; i<=ap->hi; i++)
  198.     {
  199.         /* Check max block count */
  200.         if ( (blk_cnt >= max_blks) && (max_blks > 0) )
  201.         {
  202.             fclose (ndx_fd);
  203.             np->hi = i;
  204.             return (0);
  205.         }
  206.  
  207.         /* Construct article's file name */
  208.         sprintf (art_file, "%s%d", news_path, i);
  209.  
  210.         /* Process this article */
  211.         DoArticle (art_file);
  212.     }
  213.     fclose (ndx_fd);
  214.  
  215.     /* Reset hi article number */
  216.     np->hi = ap->hi;
  217. }
  218.  
  219. DoArticle (art_file)
  220. char *art_file;
  221. {
  222.     struct qwk_hdr hdr;
  223.     struct stat stat_buf;
  224.     long txt_offset, end_offset;
  225.     int n, out_bytes;
  226.     char ndx[5], *eof, from[PATH_LEN];
  227.     FILE *art_fd;
  228.  
  229.     /* Forget it if we can't open the article */
  230.     if (NULL == (art_fd = fopen (art_file, "r"))) return (0);
  231.  
  232.     /* stat() the article to get file size */
  233.     if (0 != stat (art_file, &stat_buf))
  234.     {
  235.         fclose (art_fd);
  236.         return (0);
  237.     }
  238.     end_offset = stat_buf.st_size;
  239.  
  240.     /* Skip empty articles */
  241.     if (end_offset == 0)
  242.     {
  243.         fclose (art_fd);
  244.         return (0);
  245.     }
  246.  
  247.     /* Write the index file entry */
  248.     inttoms (blk_cnt, ndx);
  249.     ndx[4] = conf_cnt - 1;
  250.     fwrite (ndx, 5, 1, ndx_fd);
  251.  
  252.     Spaces (&hdr, 128);
  253.  
  254.     /* Fill in some header fields */
  255.     hdr.status = QWK_PUBLIC;
  256.     PadNum (msg_cnt, hdr.number, 7);
  257.     Spaces (hdr.password, 12);
  258.     Spaces (hdr.refer, 8);
  259.     hdr.flag = QWK_ACT_FLAG;
  260.     IntNum (conf_cnt-1, hdr.conference);
  261.     IntNum (msg_cnt+1, hdr.msg_num);
  262.     hdr.tag = ' ';
  263.     PadString ("ALL", hdr.to, 25);
  264.  
  265.     msg_cnt++;
  266.  
  267.     /* Process header lines */
  268.     eof = Fgets (buf, BUF_LEN, art_fd);
  269.     while ( (0 != strlen(buf)) && (eof != NULL) )
  270.     {
  271.         if (!strncmp (buf, "Date: ", 6))
  272.         {
  273.             ParseDate (&buf[6], &hdr);
  274.         }
  275.         else if (!strncmp (buf, "Subject: ", 9))
  276.         {
  277.             PadString (&buf[9], hdr.subject, 25);
  278.         }
  279.         else if (!strncmp (buf, "From: ", 6))
  280.         {
  281.             sscanf (&buf[6], "%s", from);
  282.             PadString (from, hdr.from, 25);
  283.         }
  284.  
  285.         eof = Fgets (buf, BUF_LEN, art_fd);
  286.     }
  287.  
  288.     txt_offset = ftell (art_fd);
  289.  
  290.     /* Compute block count */
  291.     if (inc_hdrs)
  292.     {
  293.         PadNum (2+end_offset/128, hdr.blocks, 6);
  294.         blk_cnt += 1+end_offset/128;
  295.     }
  296.     else
  297.     {
  298.         PadNum (2+(end_offset-txt_offset)/128, hdr.blocks, 6);
  299.         blk_cnt += 1+(end_offset-txt_offset)/128;
  300.     }
  301.  
  302.     /* Write the message header */
  303.     fwrite (&hdr, 128, 1, msg_fd);
  304.     blk_cnt++;
  305.  
  306.     /* Now write the article's text */
  307.     if (inc_hdrs) fseek (art_fd, 0, 0);
  308.     out_bytes = 0;
  309.  
  310.     while (NULL != Fgets (buf, BUF_LEN, art_fd))
  311.     {
  312.         n = strlen (buf);
  313.         fwrite (buf, n, 1, msg_fd);
  314.         out_bytes += n;
  315.  
  316.         if (n < BUF_LEN-1)
  317.         {
  318.             fputc (QWK_EOL, msg_fd);
  319.             out_bytes++;
  320.         }
  321.     }
  322.  
  323.     /* Pad block as necessary */
  324.     n = out_bytes % 128;
  325.     for (;n<128;n++) fputc (' ', msg_fd);
  326.  
  327.     fclose (art_fd);
  328. }
  329.  
  330. OutOfMemory()
  331. {
  332.     fprintf (stderr, "%s: out of memory\n", progname);
  333.     exit (0);
  334. }
  335.