home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / OFFLINE / UQWK18.ZIP / UQWK18.TAR / mail.c < prev    next >
C/C++ Source or Header  |  1994-02-01  |  6KB  |  331 lines

  1. #include <stdio.h>
  2. #include "uqwk.h"
  3.  
  4. /*
  5.  *  All sorts of stuff to do mail processing
  6.  */
  7.  
  8. FILE *mail_fd;            /* For mail spool */
  9. struct mail_ent *last_mp;    /* Points to last mail list entry */
  10.  
  11. DoMail ()
  12. /*
  13.  *  Process mail into QWK packet
  14.  */
  15. {
  16.     struct mail_ent *mailp;
  17.     struct conf_ent *cp;
  18.  
  19.     /* No mail in summary mode */
  20.     if (sum_mode) return (0);
  21.  
  22.     /* Open the mail spool */
  23.     if (NULL == (mail_fd = fopen (mail_file, "r")))
  24.     {
  25.         fprintf (stderr, "%s: can't open %s\n", progname, mail_file);
  26.         perror (progname);
  27.         return (0);
  28.     }
  29.  
  30.     /* Define the mail "conference" */
  31.     cp = NewConference (MAIL_CONF_NAME, conf_cnt);
  32.  
  33.     /* Construct the mail linked list */
  34.     MakeMailList ();
  35.  
  36.     /* Open ZipNews mail file */
  37.     if (zip_mode && (mail_list != NULL)) OpenZipMail();
  38.  
  39.     /* Walk through all the messages */
  40.     mailp = mail_list;
  41.  
  42.     while (mailp != NULL)
  43.     {
  44.         cp->count++;
  45.  
  46.         if (slnp_mode)
  47.         {
  48.             SLNPMessage (mailp);
  49.         }
  50.         else if (zip_mode)
  51.         {
  52.             ZipMessage (mailp);
  53.         }
  54.         else
  55.         {
  56.             DoMessage (mailp);
  57.         }
  58.  
  59.         mailp = mailp->next;
  60.     }
  61.  
  62.     fclose (mail_fd);
  63.     if (!slnp_mode && !zip_mode) fclose (ndx_fd);
  64.     if (slnp_mode) fclose (msg_fd);
  65.     if (zip_mode && (mail_list != NULL)) fclose (mai_fd);
  66.  
  67.     /* Now empty the mail box */
  68.     if (!read_only)
  69.     {
  70.         if (NULL == (mail_fd = fopen (mail_file, "w")))
  71.         {
  72.             fprintf (stderr, "%s: can't write %s\n", progname,
  73.                                 mail_file);
  74.         }
  75.         else
  76.         {
  77.             fclose (mail_fd);
  78.         }
  79.     }
  80.     return (1);
  81. }
  82.  
  83. MakeMailList ()
  84. /*
  85.  *  Construct linked list of pointers to individual messages in
  86.  *  the mail spool.
  87.  */
  88. {
  89.     long offset;
  90.  
  91.     last_mp = NULL;
  92.  
  93.     /* Read through, looking for "From" lines */
  94.     offset = ftell (mail_fd);
  95.     while (NULL != Fgets (buf, BUF_LEN, mail_fd))
  96.     {
  97.         if (!strncmp (buf, "From ",  5))
  98.         {
  99.             DoFromLine (offset);
  100.         }
  101.         offset = ftell (mail_fd);
  102.     }
  103.     if (last_mp != NULL) last_mp->end = offset;
  104. }
  105.  
  106. DoFromLine (offset)
  107. long offset;
  108. {
  109.     struct mail_ent *mp;
  110.  
  111.     /* Get space for new mail list entry */
  112.     if (NULL==(mp=(struct mail_ent *) malloc(sizeof(struct mail_ent))))
  113.     {
  114.         fprintf (stderr, "%s: out of memory\n", progname);
  115.         exit (0);
  116.     }
  117.  
  118.     /* Fill in offset */
  119.     mp->begin = offset;
  120.  
  121.     if (last_mp == NULL)
  122.     {
  123.         /* This is first message */
  124.         mail_list = mp;
  125.     }
  126.     else
  127.     {
  128.         /* Add to end of list */
  129.         last_mp->next = mp;
  130.         last_mp->end = offset;
  131.     }
  132.  
  133.     mp->next = NULL;
  134.     last_mp = mp;
  135. }
  136.  
  137. SLNPMessage (mp)
  138. struct mail_ent *mp;
  139. /*
  140.  *  Convert a message to SLNP format
  141.  */
  142. {
  143.     int bytes, c, b;
  144.  
  145.     /* Compute message size */
  146.     b = bytes = mp->end - mp->begin;
  147.  
  148.     /* Write byte count line */
  149.     for (c=3; c>=0; c--)
  150.     {
  151.         buf[c] = b % 256;
  152.         b = b / 256;
  153.     }
  154.     fwrite (buf, 4, 1, msg_fd);
  155.  
  156.     /* Seek to start of message */
  157.     fseek (mail_fd, mp->begin, 0);
  158.  
  159.     /* Copy bytes */
  160.     while (bytes--)
  161.     {
  162.         c = fgetc (mail_fd);
  163.         fputc ((0xff & c), msg_fd);
  164.     }
  165.     return (0);
  166. }
  167.  
  168. DoMessage (mp)
  169. struct mail_ent *mp;
  170. /*
  171.  *  Convert a message to QWK format
  172.  */
  173. {
  174.     struct qwk_hdr hdr;
  175.     char c[PATH_LEN], *eof, ndx[5];
  176.     int out_bytes, n, i;
  177.  
  178.     /* Write the ndx file entry */
  179.     inttoms (blk_cnt, ndx);
  180.     ndx[4] = conf_cnt;
  181.     fwrite (ndx, 5, 1, ndx_fd);
  182.  
  183.     Spaces (&hdr, 128);
  184.  
  185.     /* Fill in the header fields we can do now */
  186.     hdr.status = QWK_PRIVATE;
  187.     PadNum (msg_cnt, hdr.number, 7);
  188.     Spaces (hdr.password, 12);
  189.     Spaces (hdr.refer, 8);
  190.     hdr.flag = QWK_ACT_FLAG;
  191.     IntNum (conf_cnt, hdr.conference);
  192.     IntNum (msg_cnt+1, hdr.msg_num);
  193.     hdr.tag = ' ';
  194.  
  195.     msg_cnt++;
  196.  
  197.     /* Seek to start of message */
  198.     fseek (mail_fd, mp->begin, 0);
  199.  
  200.     /* Read the From line */
  201.     Fgets (buf, BUF_LEN, mail_fd);
  202.  
  203.     /* The second field of the From line is used as a first
  204.        guess for who sent the message */
  205.     sscanf (&buf[5], "%s", c);
  206.     PadString (c, hdr.from, 25);
  207.  
  208.     /* Now read through header lines, looking for ones we need */
  209.     eof = Fgets (buf, BUF_LEN, mail_fd);
  210.     while ( (0 != strlen(buf)) && (eof != NULL) )
  211.     {
  212.         if (!strncmp (buf, "Date: ", 6))
  213.         {
  214.             ParseDate (&buf[6], &hdr);
  215.         }
  216.         else if (!strncmp (buf, "To: ", 4))
  217.         {
  218.             PadString (&buf[4], hdr.to, 25);
  219.         }
  220.         else if (!strncmp (buf, "Subject: ", 9))
  221.         {
  222.             PadString (&buf[9], hdr.subject, 25);
  223.         }
  224.         else if (!strncmp (buf, "From: ", 6))
  225.         {
  226.             PadString (ParseFrom(&buf[6]), hdr.from, 25);
  227.         }
  228.  
  229.         eof = Fgets (buf, BUF_LEN, mail_fd);
  230.     }
  231.     mp->text = ftell (mail_fd);
  232.  
  233.     /* Fill in block count */
  234.     if (inc_hdrs)
  235.     {
  236.         PadNum (2+(mp->end-mp->begin)/128, hdr.blocks, 6);
  237.         blk_cnt += (1+(mp->end - mp->begin)/128);
  238.     }
  239.     else
  240.     {
  241.         PadNum (2+(mp->end-mp->text)/128, hdr.blocks, 6);
  242.         blk_cnt += (1+(mp->end - mp->text)/128);
  243.     }
  244.  
  245.     /* Write out the message header */
  246.     fwrite (&hdr, 128, 1, msg_fd);
  247.     blk_cnt++;
  248.  
  249.     /* Now write the message text */
  250.     if (inc_hdrs) fseek (mail_fd, mp->begin, 0);
  251.     out_bytes = 0;
  252.  
  253.     eof = Fgets (buf, BUF_LEN, mail_fd);
  254.     do
  255.     {
  256.         n = strlen (buf);
  257.  
  258.         /* MMDF puts funny things in messages -- change to spaces */
  259.         for (i=0; i<n; i++)
  260.         {
  261.             if (buf[i] == 1) buf[i] = ' ';
  262.             if (buf[i] == 0) buf[i] = ' ';
  263.         }
  264.  
  265.         fwrite (buf, n, 1, msg_fd);
  266.         out_bytes += n;
  267.         if (n < BUF_LEN-1)
  268.         {
  269.             fputc (QWK_EOL, msg_fd);
  270.             out_bytes++;
  271.         }
  272.         eof = Fgets (buf, BUF_LEN, mail_fd);
  273.     } while ( (strncmp(buf,"From ", 5)) && (NULL != eof) );
  274.  
  275.     /* Pad block as necessary */
  276.     n = out_bytes % 128;
  277.     for (;n<128;n++) fputc (' ', msg_fd);
  278. }
  279.  
  280. OpenZipMail ()
  281. /*
  282.  *  Open ZipNews mail file
  283.  */
  284. {
  285.     char fn[PATH_LEN];
  286.  
  287.     /* Make name */
  288.     sprintf (fn, "%s/%s.mai", home_dir, user_name);
  289.  
  290.     /* Open it */
  291.     if (NULL == (mai_fd = fopen (fn, "w")))
  292.     {
  293.         fprintf (stderr, "%s: can't open %s\n", progname, fn);
  294.         exit (0);
  295.     }
  296. }
  297.  
  298. ZipMessage (mp)
  299. struct mail_ent *mp;
  300. /*
  301.  *  Convert a message to Zip format
  302.  */
  303. {
  304.     int bytes, c;
  305.  
  306.     /* Compute message size */
  307.     bytes = mp->end - mp->begin;
  308.  
  309.     /* Write separator */
  310.     for (c=0; c<20; c++) fputc (1, mai_fd);
  311.     fprintf (mai_fd, "\r\n");
  312.  
  313.     /* Seek to start of message */
  314.     fseek (mail_fd, mp->begin, 0);
  315.  
  316.     /* Copy bytes */
  317.     while (bytes--)
  318.     {
  319.         c = fgetc (mail_fd);
  320.  
  321.         /* ZipNews doesn't like ^Z's */
  322.         if (c == 26) c = 32;
  323.  
  324.         /* Map LF to CRLF */
  325.         if (c == 10) fputc (13, mai_fd);
  326.  
  327.         fputc ((0xff & c), mai_fd);
  328.     }
  329.     return (0);
  330. }
  331.