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

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <string.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include "uqwk.h"
  7. /*
  8.  *  Process a reply packet
  9.  */
  10.  
  11. DoReply ()
  12. {
  13.     int n, rep_cnt;
  14.     char bbs[PATH_LEN];
  15.  
  16.     /* Check for ZipNews reply */
  17.     if (zip_mode)
  18.     {
  19.         DoZipReplies();
  20.         return (0);
  21.     }
  22.  
  23.     rep_cnt = 0;
  24.  
  25.     /* Open the packet */
  26.     if (NULL == (rep_fd = fopen (rep_file, "r")))
  27.     {
  28.         fprintf (stderr, "%s: can't open %s\n", progname, rep_file);
  29.         return (0);
  30.     }
  31.  
  32.     /* Handle SLNP reply */
  33.     if (slnp_mode)
  34.     {
  35.         SLNPReply ();
  36.         fclose (rep_fd);
  37.         return (0);
  38.     }
  39.  
  40.     /* Get the first block, the BBS ID */
  41.     if (1 != fread (buf, 128, 1, rep_fd))
  42.     {
  43.         fprintf (stderr, "%s: reply packet read error\n", progname);
  44.         fclose (rep_fd);
  45.         return (0);
  46.     }
  47.  
  48.     /* Extract bbs id and check */
  49.     sscanf (bbs_id, "%*d,%s", bbs);
  50.     n = strlen (bbs);
  51.     buf[n] = 0;
  52.     if (strcmp (bbs, buf))
  53.     {
  54.         fprintf (stderr, "%s: reply BBS ID mismatch: %s != %s\n",
  55.             progname, buf, bbs);
  56.         fclose (rep_fd);
  57.         return (0);
  58.     }
  59.  
  60.     /* Read the .newsrc file; we will need the list of conferences */
  61.     ReadNewsrc();
  62.  
  63.     /* Read the next message header and process it */
  64.     while (1 == fread (&rep_hdr, 128, 1, rep_fd))
  65.     {
  66.         SendReply ();
  67.         rep_cnt++;
  68.     }
  69.  
  70.     fclose (rep_fd);
  71.     printf ("%s: sent %d replies\n", progname, rep_cnt);
  72.  
  73.     return (1);
  74. }
  75.  
  76. SendReply ()
  77. /*
  78.  *  Pipe a reply to the mailer or inews
  79.  */
  80. {
  81.     FILE *pfd;
  82.     unsigned char c, to[PATH_LEN], subject[PATH_LEN], group[PATH_LEN];
  83.     int i, n, blocks, bytes, conf;
  84.     struct nrc_ent *np;
  85.  
  86.     /* Extract recipient */
  87.     strncpy (buf, rep_hdr.to, 25);
  88.     buf[25] = 0;
  89.     sscanf (buf, "%s", to);
  90.  
  91.     /* Extract conference number */
  92.     strncpy (buf, rep_hdr.number, 7);
  93.     buf[7] = 0;
  94.     sscanf (buf, "%d", &conf);
  95.  
  96.     /* Extract subject */
  97.     strncpy (buf, rep_hdr.subject, 25);
  98.     buf[25] = 0;
  99.     strcpy (subject, buf);
  100.  
  101.     /* Get rid of single quotes in subject */
  102.     n = strlen (subject);
  103.     for (i=0; i<n; i++) if (subject[i] == '\'') subject[i] = '`';
  104.  
  105.     /* Find newsgroup with this conference number */
  106.     np = nrc_list;
  107.     while (np != NULL)
  108.     {
  109.         if (np->conf == conf) break;
  110.         np = np->next;
  111.     }
  112.  
  113.     /* Get newsgroup name */
  114.     if (np == NULL)
  115.     {
  116.         /* Bet this generates lots of email for "ALL" */
  117.         rep_hdr.status = QWK_PRIVATE;
  118.     }
  119.     else
  120.     {
  121.         strcpy (group, np->name);
  122.     }
  123.  
  124.     /* Extract block count */
  125.     strncpy (buf, rep_hdr.blocks, 6);
  126.     buf[6] = 0;
  127.     sscanf (buf, "%d", &blocks);
  128.     blocks -= 1;
  129.     bytes = 128 * blocks;
  130.  
  131.     /* Check for off-line command message */
  132.     if ( (!strcmp (to, "uqwk")) || (!strcmp (to, "UQWK")) )
  133.     {
  134.         QWKOffLine (bytes, rep_fd);
  135.         return (0);
  136.     }
  137.  
  138.     /* Check for a configuration message intended for some
  139.        other QWK "door" */
  140.     if ( (!strcmp (to, "MARKMAIL")) || (!strcmp (to, "QMAIL"))   ||
  141.          (!strcmp (to, "markmail")) || (!strcmp (to, "qmail"))   ||
  142.          (!strcmp (to, "ROSEMAIL")) || (!strcmp (to, "KMAIL"))   ||
  143.          (!strcmp (to, "rosemail")) || (!strcmp (to, "kmail"))   ||
  144.          (!strcmp (to, "MAINMAIL")) || (!strcmp (to, "CMPMAIL")) ||
  145.          (!strcmp (to, "mainmail")) || (!strcmp (to, "cmpmail")) ||
  146.          (!strcmp (to, "ULTRABBS")) || (!strcmp (to, "BGQWK"))   ||
  147.          (!strcmp (to, "ultrabbs")) || (!strcmp (to, "bgqwk"))   ||
  148.          (!strcmp (to, "CAM-MAIL")) || (!strcmp (to, "TRIMAIL")) ||
  149.          (!strcmp (to, "cam-mail")) || (!strcmp (to, "trimail")) ||
  150.          (!strcmp (to, "QSO")) || (!strcmp (to, "qso")) )
  151.     {
  152.         /* Send warning to user */
  153.         SendWarning (to);
  154.  
  155.         /* Skip the rest of the message */
  156.         while (bytes--) fread (&c, 1, 1, rep_fd);
  157.  
  158.         return (0);
  159.     }
  160.  
  161.     /* Check for a "To: " line in the body of the message */
  162.     CheckTo (to, bytes);
  163.  
  164.     /* Open pipe to proper program */
  165.     pfd = NULL;
  166.  
  167.     if ( (rep_hdr.status == QWK_PUBLIC) ||
  168.          (rep_hdr.status == QWK_PUBLIC2) )
  169.     {
  170.         /* Public message, open pipe to inews */
  171.         if (xprt_mode)
  172.         {
  173.             sprintf (buf, "%s", XPRT_INEWS);
  174.         }
  175.         else
  176. #ifdef SERVER
  177.         {
  178.             sprintf (buf, "%s", INEWS_PATH);
  179.         }
  180. #else
  181.         {
  182.             sprintf (buf, "%s -t '%s' -n '%s'",
  183.                 INEWS_PATH, subject, group);
  184.         }
  185. #endif
  186.         printf ("%s: Posting to %s\n", progname, group);
  187.         if (NULL == (pfd = popen (buf, "w")))
  188.         {
  189.             fprintf (stderr, "%s: can't popen() inews\n",
  190.                     progname);
  191.         }
  192. #ifdef SERVER
  193.         if (!xprt_mode && (pfd != NULL) )
  194.         {
  195.             fprintf (pfd, "Newsgroups: %s\nSubject: %s\n\n",
  196.                 group, subject);
  197.         }
  198. #endif
  199.     }
  200.     else if ( (rep_hdr.status == QWK_PRIVATE) ||
  201.               (rep_hdr.status == QWK_PRIVATE2) )
  202.     {
  203.         /* Open pipe to mail */
  204.         if (xprt_mode)
  205.         {
  206.             sprintf (buf, "%s", XPRT_MAILER);
  207.         }
  208.         else
  209.         {
  210.             sprintf (buf, "%s -s '%s' '%s'",
  211.                 MAILER_PATH, subject, to);
  212.         }
  213.         printf ("%s: Mailing to %s\n", progname, to);
  214.         if (NULL == (pfd = popen (buf, "w")))
  215.         {
  216.             fprintf (stderr, "%s: can't popen() mail\n", progname);
  217.         }
  218.     }
  219.  
  220.     /* Read and send all bytes of message */
  221.     for (i=0; i<bytes; i++)
  222.     {
  223.         fread (&c, 1, 1, rep_fd);
  224.         if (c == QWK_EOL) c = 012;
  225.         if (pfd != NULL) fwrite (&c, 1, 1, pfd);
  226.     }
  227.  
  228.     if (pfd != NULL) pclose (pfd);
  229.     return (1);
  230. }
  231.  
  232. SendWarning (to)
  233. char *to;
  234. /*
  235.  *  Mail a warning to the user if the reply packet
  236.  *  contains a message apparently for some other QWK
  237.  *  "door" program.
  238.  */
  239. {
  240.     FILE *pfd;
  241.  
  242.     /* Open pipe to mailer */
  243.     sprintf (buf, "%s -s 'UQWK Error Message' %s",
  244.             MAILER_PATH, user_name);
  245.     if (NULL == (pfd = popen (buf, "w")))
  246.     {
  247.         fprintf (stderr, "%s: can't popen() mail\n", progname);
  248.         return (0);
  249.     }
  250.  
  251.     /* Send the message */
  252.  
  253.     fprintf (pfd,
  254. "Hello. You sent a message to the username %s, presumably to\n", to);
  255.     fprintf (pfd,
  256. "perform some sort of offline configuration. This QWK processor,\n");
  257.     fprintf (pfd,
  258. "called UQWK, cannot process this message. To perform offline\n");
  259.     fprintf (pfd,
  260. "configuration using UQWK, you must send a message to the username\n");
  261.     fprintf (pfd,
  262. "UQWK. Commands are to be included in the body of the message.\n");
  263.     fprintf (pfd,
  264. "For a list of commands, send a message to UQWK with the word\n");
  265.     fprintf (pfd,
  266. "HELP in the body of the message (not the subject). Thanks!\n");
  267.  
  268.     pclose (pfd);
  269.     return (1);
  270. }
  271.  
  272. CheckTo (to, bytes)
  273. char *to;
  274. int bytes;
  275. /*
  276.  *  Check the first line of the body of the message for a To: line.
  277.  *  This is the only way to send to addresses over 25 characters.
  278.  *
  279.  *  Whether we find a To: line or not, we have to leave the file
  280.  *  positioned right where it is.
  281.  */
  282. {
  283.     long offset;
  284.     unsigned char c;
  285.     int i;
  286.  
  287.     /* Sanity check */
  288.     if (bytes < 5) return (0);
  289.  
  290.     offset = ftell (rep_fd);
  291.  
  292.     /* Check first four bytes */
  293.     fread (buf, 4, 1, rep_fd);
  294.     bytes -= 4;
  295.     if (strncmp (buf, "To: ", 4))
  296.     {
  297.         /* Doesn't match */
  298.         fseek (rep_fd, offset, 0);
  299.         return (0);
  300.     }
  301.  
  302.     /* Copy in the rest of the line until white space, EOL,
  303.        or run out of bytes */
  304.     i = 0;
  305.     fread (&c, 1, 1, rep_fd);
  306.     bytes--;
  307.  
  308.     while ( (bytes >= 0) && (c != QWK_EOL) &&
  309.             (c != 9) && (c != ' ') )
  310.     {
  311.         to[i++] = c;
  312.  
  313.         fread (&c, 1, 1, rep_fd);
  314.         bytes--;
  315.     }
  316.     to[i] = 0;
  317.  
  318.     /* Done! */
  319.     fseek (rep_fd, offset, 0);
  320.     return (1);
  321. }
  322.  
  323. SLNPReply ()
  324. /*
  325.  *  Process an SLNP reply packet
  326.  */
  327. {
  328.     char fname[PATH_LEN], kind[PATH_LEN], type[PATH_LEN];
  329.  
  330.     /* Look through lines in REPLIES file */
  331.     while (Fgets (buf, BUF_LEN, rep_fd))
  332.     {
  333.         if (3 != sscanf (buf, "%s %s %s", fname, kind, type))
  334.         {
  335.             fprintf (stderr, "%s: malformed REPLIES line\n",
  336.                     progname);
  337.             return (0);
  338.         }
  339.  
  340.         /* Look for mail or news */
  341.         if (strcmp(kind,"mail") && strcmp(kind,"news"))
  342.         {
  343.             fprintf (stderr, "%s: bad reply kind: %s\n",
  344.                     progname, kind);
  345.         }
  346.  
  347.         /* Check reply type */
  348.         else if ( (type[0] != 'u') &&
  349.               (type[0] != 'b') &&
  350.               (type[0] != 'B') )
  351.         {
  352.             fprintf (stderr, "%s: reply type %c not supported\n",
  353.                     progname, type[0]);
  354.         }
  355.  
  356.         else
  357.         {
  358.             /* Make file name */
  359.             strcat (fname, ".MSG");
  360.  
  361.             /* Process it */
  362.             switch (type[0])
  363.             {
  364.             case 'u':
  365.                 if (!strcmp (kind, "mail")) SLuMail (fname);
  366.                 if (!strcmp (kind, "news")) SLuNews (fname);
  367.                 break;
  368.  
  369.             case 'b':
  370.             case 'B':
  371.                 if (!strcmp (kind, "mail")) SLbMail (fname);
  372.                 if (!strcmp (kind, "news")) SLbNews (fname);
  373.                 break;
  374.             }
  375.  
  376.             /* Delete it */
  377.             if (!read_only) unlink (fname);
  378.         }
  379.     }
  380.     return (0);
  381. }
  382.  
  383. SLuMail (fn)
  384. char *fn;
  385. /*
  386.  *  Process a SLNP mail reply file, usenet type
  387.  */
  388. {
  389.     FILE *fd;
  390.     int bytes;
  391.     char *to, *addr, cmd[PATH_LEN];
  392.     long offset;
  393.  
  394.     /* Get space for To: */
  395.     if (NULL == (to = (char *) malloc (BUF_LEN))) OutOfMemory();
  396.  
  397.     /* Open the reply file */
  398.     if (NULL == (fd = fopen (fn, "r")))
  399.     {
  400.         fprintf (stderr, "%s: can't open %s\n", progname, fn);
  401.         free (to);
  402.         return (0);
  403.     }
  404.  
  405.     /* Read through it */
  406.     while (NULL != Fgets (buf, BUF_LEN, fd))
  407.     {
  408.         if (strncmp (buf, "#! rnews ", 9))
  409.         {
  410.             fprintf (stderr, "%s: malformed reply file\n",
  411.                     progname);
  412.             fclose (fd);
  413.             free (to);
  414.             return (0);
  415.         }
  416.  
  417.         /* Get byte count */
  418.         sscanf (&buf[8], "%d", &bytes);
  419.  
  420.         /* Remember file position */
  421.         offset = ftell (fd);
  422.  
  423.         /* Look for To: */
  424.         GetHdr (fd, to, bytes, "To: ");
  425.  
  426.         /* Check for offline command */
  427.         if (!strcmp (to, "uqwk") || !strcmp (to, "UQWK"))
  428.         {
  429.             OffLine (fd, bytes);
  430.             continue;
  431.         }
  432.  
  433.         /* Construct delivery line */
  434.         sprintf (cmd, "%s", SLNP_MAILER);
  435.  
  436.         printf ("%s: Mailing to %s\n", progname, to);
  437.  
  438.         /* Pipe message to delivery agent */
  439.         SLPipe (fd, bytes, cmd);
  440.     }
  441.     free (to);
  442.  
  443.     fclose (fd);
  444.     return (0);
  445. }
  446.  
  447. SLuNews (fn)
  448. char *fn;
  449. /*
  450.  *  Process a SLNP news reply file, usenet type
  451.  */
  452. {
  453.     FILE *fd;
  454.     int bytes;
  455.     char *grp;
  456.  
  457.     /* Get space for newsgroup name */
  458.     if (NULL == (grp = (char *) malloc (BUF_LEN)))
  459.     {
  460.         OutOfMemory();
  461.         return (0);
  462.     }
  463.  
  464.     /* Open the reply file */
  465.     if (NULL == (fd = fopen (fn, "r")))
  466.     {
  467.         fprintf (stderr, "%s: can't open %s\n", progname, fn);
  468.         return (0);
  469.     }
  470.  
  471.     /* Read through it */
  472.     while (NULL != Fgets (buf, BUF_LEN, fd))
  473.     {
  474.         if (strncmp (buf, "#! rnews ", 9))
  475.         {
  476.             fprintf (stderr, "%s: mailformed reply file\n",
  477.                     progname);
  478.             fclose (fd);
  479.             return (0);
  480.         }
  481.  
  482.         /* Get byte count */
  483.         sscanf (&buf[8], "%d", &bytes);
  484.  
  485.         if (GetHdr (fd, grp, bytes, "Newsgroups: "))
  486.         {
  487.             printf ("%s: Posting article to %s\n", progname, grp);
  488.         }
  489.  
  490.         /* Pipe message to delivery agent */
  491.         SLPipe (fd, bytes, SLNP_INEWS);
  492.     }
  493.     free (grp);
  494.     fclose (fd);
  495.     return (0);
  496. }
  497.  
  498. SLbMail (fn)
  499. char *fn;
  500. /*
  501.  *  Process a SLNP mail reply file, binary type
  502.  */
  503. {
  504.     FILE *fd;
  505.     int bytes;
  506.     char *to, *addr, cmd[PATH_LEN];
  507.     long offset;
  508.  
  509.     /* Get space for To: */
  510.     if (NULL == (to = (char *) malloc (BUF_LEN))) return (0);
  511.  
  512.     /* Open the reply file */
  513.     if (NULL == (fd = fopen (fn, "r")))
  514.     {
  515.         fprintf (stderr, "%s: can't open %s\n", progname, fn);
  516.         free (to);
  517.         return (0);
  518.     }
  519.  
  520.     /* Read through it */
  521.     while (0 != fread (buf, 4, 1, fd))
  522.     {
  523.         /* Get byte count */
  524.         bytes = (buf[0] * 256 * 256 * 256) +
  525.             (buf[1] * 256 * 256) +
  526.             (buf[2] * 256) +
  527.             (buf[3]);
  528.  
  529.         /* Remember file position */
  530.         offset = ftell (fd);
  531.  
  532.         /* Find the To: line */
  533.         GetHdr (fd, to, bytes, "To: ");
  534.  
  535.         /* Check for offline command */
  536.         if (!strcmp (to, "uqwk") || !strcmp (to, "UQWK"))
  537.         {
  538.             OffLine (fd, bytes);
  539.             continue;
  540.         }
  541.  
  542.         /* Construct delivery line */
  543.         sprintf (cmd, "%s", SLNP_MAILER);
  544.  
  545.         printf ("%s: Mailing to %s\n", progname, to);
  546.  
  547.         /* Pipe message to delivery agent */
  548.         SLPipe (fd, bytes, cmd);
  549.     }
  550.     free (to);
  551.  
  552.     fclose (fd);
  553.     return (0);
  554. }
  555.  
  556. SLbNews (fn)
  557. char *fn;
  558. /*
  559.  *  Process a SLNP news reply file, binary type
  560.  */
  561. {
  562.     FILE *fd;
  563.     int bytes;
  564.     char *grp;
  565.  
  566.     /* Get space for newsgroup name */
  567.     if (NULL == (grp = (char *) malloc (BUF_LEN)))
  568.     {
  569.         OutOfMemory();
  570.         return (0);
  571.     }
  572.  
  573.     /* Open the reply file */
  574.     if (NULL == (fd = fopen (fn, "r")))
  575.     {
  576.         fprintf (stderr, "%s: can't open %s\n", progname, fn);
  577.         return (0);
  578.     }
  579.  
  580.     /* Read through it */
  581.     while (0 != fread (buf, 4, 1, fd))
  582.     {
  583.         /* Get byte count */
  584.         bytes = (buf[0] * 256 * 256 * 256) +
  585.             (buf[1] * 256 * 256) +
  586.             (buf[2] * 256) +
  587.             (buf[3]);
  588.  
  589.         if (GetHdr (fd, grp, bytes, "Newsgroups: "))
  590.         {
  591.             printf ("%s: Posting article to %s\n", progname, grp);
  592.         }
  593.  
  594.         /* Pipe message to delivery agent */
  595.         SLPipe (fd, bytes, SLNP_INEWS);
  596.     }
  597.     free (grp);
  598.     fclose (fd);
  599.     return (0);
  600. }
  601.  
  602. SLPipe (fd, bytes, agent)
  603. FILE *fd;
  604. int bytes;
  605. char *agent;
  606. /*
  607.  *  Pipe a SLNP reply to the specified delivery agent
  608.  */
  609. {
  610.     FILE *pfd;
  611.     unsigned char c;
  612.  
  613.     /* Open pipe to agent */
  614.     if (NULL == (pfd = popen (agent, "w")))
  615.     {
  616.         fprintf (stderr, "%s: can't open reply pipe\n", progname);
  617.         while (bytes--) fgetc (fd);
  618.         return (0);
  619.     }
  620.  
  621.     /* Send message to pipe */
  622.     while (bytes--)
  623.     {
  624.         c = 0xff & fgetc (fd);
  625.         fputc (c, pfd);
  626.     }
  627.  
  628.     pclose (pfd);
  629.     return (0);
  630. }
  631.  
  632. int GetHdr (fd, cc, bytes, hdr)
  633. FILE *fd;
  634. char *cc, *hdr;
  635. int bytes;
  636. /*
  637.  *  Find given header line
  638.  */
  639. {
  640.     int offset, n, cnt;
  641.     char *rc;
  642.  
  643.     cnt = strlen (hdr);
  644.  
  645.     /* Remember file position */
  646.     offset = ftell (fd);
  647.  
  648.     /* Look through header */
  649.     rc = Fgets (buf, BUF_LEN, fd);
  650.     n = strlen (buf);
  651.     while ( (rc != NULL) && (bytes > 0) && (n > 0) )
  652.     {
  653.         /* Right line? */
  654.         if (!strncmp (buf, hdr, cnt))
  655.         {
  656.             strcpy (cc, &buf[cnt]);
  657.             fseek (fd, offset, 0);
  658.             return (1);
  659.         }
  660.  
  661.         /* Get next line */
  662.         bytes -= n;
  663.         rc = Fgets (buf, BUF_LEN, fd);
  664.         if (rc != NULL) n = strlen (buf);
  665.     }    
  666.  
  667.     /* Reposition file */
  668.     fseek (fd, offset, 0);
  669.     return (0);
  670. }
  671.  
  672.  
  673. DoZipReplies ()
  674. /*
  675.  *  Process replies in a Zip packet
  676.  */
  677. {
  678.     int n;
  679.     char fn[PATH_LEN];
  680.  
  681.     if (!ZipId()) return (0);
  682.  
  683.     /* Loop through possible mail files.  This is a little kludgy,
  684.        but readdir() seems to have problems on some systems,
  685.        including Esix, which is the system I use. */
  686.     for (n=0; n<100; n++)
  687.     {
  688.         /* Construct file name */
  689.         sprintf (fn, "%s/%s.m%02d", rep_file, user_name, n);
  690.  
  691.         /* Process it */
  692.         ZipMail (fn);
  693.     }
  694.  
  695.     /* Loop through possible news files */
  696.     for (n=0; n<100; n++)
  697.     {
  698.         /* Construct file name */
  699.         sprintf (fn, "%s/%s.n%02d", rep_file, user_name, n);
  700.  
  701.         /* Process it */
  702.         ZipNews (fn);
  703.     }
  704.     return (1);
  705. }
  706.  
  707. char ZZZ[PATH_LEN];
  708.  
  709. ZipId ()
  710. {
  711.     char fn[PATH_LEN],zzz[PATH_LEN],zzZ[256],*zZz,ZzZ[PATH_LEN],
  712.     ZZz[PATH_LEN];FILE *zz;int zZ,zZZ=0,Zzz,z=0;
  713.  
  714.     sprintf (fn, "%s/%s.id", rep_file, user_name);
  715.     if (NULL == (zz = fopen (fn, "r")))
  716.     {
  717.         fprintf (stderr, "%s: can't open %s\n", progname, fn);
  718.         return (0);
  719.     }
  720.  
  721.     strcpy(zzz,"Vrth#glfp#YjsMftp-#Kllqbz-");Zzz=strlen(zzz);
  722.     for(zZz=(&zzz[0]);*zZz;zZz++)*zZz^=3;zZz=(&zzz[0]);zZ=fgetc(zz);
  723.     while(zZ!=EOF){zzZ[z]=zZ^*(zZz+zZZ)^(*zZz*zZZ);*(zZz+zZZ)+=
  724.     (zZZ<(Zzz+1))?*(zZz+zZZ+1):*zZz;if(!*(zZz+zZZ))(*(zZz+zZZ))++;
  725.     if(++zZZ>=Zzz)zZZ=0;z++;zZ=fgetc(zz);}zzZ[z]=0;for(z=0;z<9;z++)
  726.     zzZ[z]^=3;fclose(zz);if(strncmp(zzZ,"YMQ(VRTH#",9))return(0);
  727.     zZz=(&zzZ[0]);z=0;zZz=strtok(zZz+9,"\n");zZz=strtok(NULL,"\n");
  728.     strcpy(ZZz,zZz);zZz=strtok(NULL,"\n");strcpy(ZzZ,zZz);strcat
  729.     (ZzZ,"\100");strcat(ZzZ,host_name);for(zZz=(&ZzZ[0]);*zZz;zZz++)
  730.     *zZz^=3;for(zZz=(&ZZz[0]);*zZz;zZz++)if((*zZz>='A')&&(*zZz<='Z'))
  731.     *zZz=tolower(*zZz);z=0;while(ZZz[z]){if(z==0)ZZz[z]=toupper(ZZz[z]);
  732.     if((ZZz[z]==' ')||(ZZz[z]=='-')||(ZZz[z]==0x27))ZZz[z+1]=toupper
  733.     (ZZz[z+1]);z++;}for(zZz=(&ZZz[0]);*zZz;zZz++)*zZz^=3;sprintf(ZZZ,
  734.     "Eqln9#%s#+%s*",ZzZ,ZZz);for(zZz=(&ZZZ[0]);*zZz;zZz++)*zZz^=3;
  735.  
  736.     return (1);
  737. }
  738.  
  739. ZipMail (fn)
  740. char *fn;
  741. /*
  742.  *  Process ZipNews mail reply
  743.  */
  744. {
  745.     FILE *fd, *pfd;
  746.     struct stat stat_buf;
  747.     int c, have_cc;
  748.     char *to, *cc, *addr;
  749.  
  750.     /* Get space for To: and Cc: */
  751.     if (NULL == (to = (char *) malloc (BUF_LEN))) return (0);
  752.     if (NULL == (cc = (char *) malloc (BUF_LEN))) return (0);
  753.  
  754.     /* Try to stat() it */
  755.     if (0 != stat (fn, &stat_buf)) return (0);
  756.  
  757.     /* Try to open it */
  758.     if (NULL == (fd = fopen (fn, "r"))) return (0);
  759.  
  760.     /* Get To: and Cc: */
  761.     GetHdr (fd, to, stat_buf.st_size, "To: ");
  762.     have_cc = GetHdr (fd, cc, stat_buf.st_size, "Cc: ");
  763.  
  764.     /* Check for offline command */
  765.     if (!strcmp (to, "uqwk") || !strcmp (to, "UQWK"))
  766.     {
  767.         OffLine (fd, stat_buf.st_size);
  768.         free (cc); free (to);
  769.         fclose (fd);
  770.         if (!read_only) unlink (fn);
  771.         return (0);
  772.     }
  773.  
  774.     /* Make mailer command line */
  775.     sprintf (buf, "%s '%s'", ZIP_MAILER, to);
  776.  
  777.     printf ("%s: Mailing to %s\n", progname, to);
  778.  
  779.     /* Open pipe to mailer */
  780.     if (NULL == (pfd = popen (buf, "w")))
  781.     {
  782.         fprintf (stderr, "%s: can't popen() mailer\n", progname);
  783.         free (cc); free (to);
  784.         fclose (fd);
  785.         return (0);
  786.     }
  787.  
  788.     fprintf (pfd, "%s\n", ZZZ);
  789.  
  790.     /* Send bytes of message */
  791.     while (EOF != (c = fgetc (fd)))
  792.     {
  793.         if (c != '\r') fputc ((0xff & c), pfd);
  794.     }
  795.  
  796.     /* Done */
  797.     pclose (pfd);
  798.  
  799.     /* Now do Cc: addresses */
  800.     if (have_cc)
  801.     {
  802.         addr = strtok (cc, ", \t");
  803.  
  804.         while (addr != NULL)
  805.         {
  806.             /* Rewind file */
  807.             fseek (fd, 0, 0);
  808.  
  809.             /* Make mailer command line */
  810.             sprintf (buf, "%s '%s'", ZIP_MAILER, addr);
  811.  
  812.             printf ("%s:  Cc'ing to %s\n", progname, addr);
  813.  
  814.             /* Open pipe to mailer */
  815.             if (NULL == (pfd = popen (buf, "w")))
  816.             {
  817.                 fprintf (stderr, "%s: can't popen() mailer\n",
  818.                         progname);
  819.                 fclose (fd);
  820.                 return (0);
  821.             }
  822.  
  823.             fprintf (pfd, "%s\n", ZZZ);
  824.  
  825.             /* Send bytes of message */
  826.             while (EOF != (c = fgetc (fd)))
  827.             {
  828.                 if (c != '\r') fputc ((0xff & c), pfd);
  829.             }
  830.  
  831.             /* Done */
  832.             pclose (pfd);
  833.  
  834.             addr = strtok (NULL, ", \t");
  835.         }
  836.     }
  837.     free (cc); free (to);
  838.  
  839.     fclose (fd);
  840.     if (!read_only) unlink (fn);
  841.  
  842.     return (1);
  843. }
  844.  
  845. ZipNews (fn)
  846. char *fn;
  847. /*
  848.  *  Process ZipNews news reply
  849.  */
  850. {
  851.     FILE *fd, *pfd;
  852.     struct stat stat_buf;
  853.     int c;
  854.  
  855.     /* Try to stat() it */
  856.     if (0 != stat (fn, &stat_buf)) return (0);
  857.  
  858.     /* Try to open it */
  859.     if (NULL == (fd = fopen (fn, "r"))) return (0);
  860.  
  861.     printf ("%s: Posting article...\n", progname);
  862.  
  863.     /* Open pipe to inews */
  864.     if (NULL == (pfd = popen (ZIP_INEWS, "w")))
  865.     {
  866.         fprintf (stderr, "%s: can't popen() inews\n", progname);
  867.         fclose (fd);
  868.         return (0);
  869.     }
  870.  
  871.     fprintf (pfd, "%s\n", ZZZ);
  872.  
  873.     /* Send bytes of message */
  874.     while (EOF != (c = fgetc (fd)))
  875.     {
  876.         if (c != '\r') fputc ((0xff & c), pfd);
  877.     }
  878.  
  879.     /* Done */
  880.     pclose (pfd);
  881.     fclose (fd);
  882.     if (!read_only) unlink (fn);
  883.  
  884.     return (1);
  885. }
  886.  
  887.