home *** CD-ROM | disk | FTP | other *** search
/ The Best of Windows 95.com 1996 September / WIN95_09964.iso / unix / SOUPER95.ZIP / source / reply.c < prev    next >
C/C++ Source or Header  |  1996-03-20  |  7KB  |  332 lines

  1. /* $Id: reply.c 1.2 1995/06/25 16:39:27 cthuang Exp $
  2.  *
  3.  * Send reply packet.
  4.  */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include "souper.h"
  9. #include "smtp.h"
  10. #include "nntpcl.h"
  11.  
  12. #ifdef __WIN32__
  13. #define popen _popen
  14. #define pclose _pclose
  15. #endif
  16.  
  17. static int smtpSock;
  18. static int nntpSock;
  19.  
  20. static char *mailer;
  21. static char *poster;
  22.  
  23. /* Return TRUE if the line begins with this header. */
  24.  
  25. int
  26. isHeader (const char *buf, const char *header, size_t len)
  27. {
  28.     return strnicmp(buf, header, len) == 0 && buf[len] == ':' &&
  29.        (buf[len+1] == ' ' || buf[len+1] == '\t');
  30. }
  31.  
  32. /* Get the value for the message header.
  33.  * Return pointer to an allocated buffer containing the header value.
  34.  */
  35. char *
  36. getHeader (FILE *fd, const char *header)
  37. {
  38.     char buf[BUFSIZ], *result;
  39.     long offset;
  40.     int headerLen, n;
  41.  
  42.     /* Remember file position */
  43.     offset = ftell(fd);
  44.  
  45.     headerLen = strlen(header);
  46.  
  47.     /* Look through header */
  48.     while (fgets(buf, sizeof(buf), fd)) {
  49.     if (buf[0] == '\n')
  50.         break;
  51.  
  52.     if (isHeader(buf, header, headerLen)) {
  53.         fseek(fd, offset, SEEK_SET);
  54.         n = strlen(buf + headerLen + 2);
  55.         result = (char *)xmalloc(n + 1);
  56.         strcpy(result, buf + headerLen + 2);
  57.         if (result[n-1] == '\n')
  58.         result[n-1] = '\0';
  59.         return result;
  60.     }
  61.     }       
  62.  
  63.     /* Reposition file */
  64.     fseek(fd, offset, SEEK_SET);
  65.     return NULL;
  66. }
  67.  
  68. #ifndef __WATCOMC__
  69. /* Pipe a message to the specified delivery agent. */
  70.  
  71. static void
  72. sendPipe (FILE *fd, size_t bytes, const char *agent)
  73. {
  74.     FILE *pfd;
  75.     unsigned char c;
  76.  
  77.     /* Open pipe to agent */
  78.     if ((pfd = popen(agent, "w")) == NULL) {
  79.     fprintf(stderr, "%s: can't open reply pipe\n", progname);
  80.     while (bytes--)
  81.         fgetc(fd);
  82.     return;
  83.     }
  84.  
  85.     /* Send message to pipe */
  86.     while (bytes--) {
  87.     c = fgetc(fd);
  88.     fputc(c, pfd);
  89.     }
  90.  
  91.     pclose(pfd);
  92. }
  93. #endif
  94.  
  95. static void
  96. sendMail (FILE *inf, size_t bytes)
  97. {
  98. #ifndef __WATCOMC__
  99.     if (mailer) {
  100.     char *to = getHeader(inf, "To");
  101.     if (to) {
  102.         printf("%s: mailing to %s\n", progname, to);
  103.         free(to);
  104.     }
  105.  
  106.     /* Pipe message to delivery agent */
  107.     sendPipe(inf, bytes, mailer);
  108.  
  109.     } else
  110. #endif
  111.     if (!smtpMail(smtpSock, inf, bytes)) {
  112.     exit(EXIT_FAILURE);
  113.     }
  114. }
  115.  
  116. static void
  117. sendNews (FILE *inf, size_t bytes)
  118. {
  119. #ifndef __WATCOMC__
  120.     if (poster) {
  121.     /* Pipe message to delivery agent */
  122.     sendPipe(inf, bytes, poster);
  123.  
  124.     } else
  125. #endif
  126.     if (!nntpPost(nntpSock, inf, bytes)) {
  127.     exit(EXIT_FAILURE);
  128.     }
  129. }
  130.  
  131. /* Process a mail reply file, usenet type */
  132.  
  133. static void
  134. sendMailu (const char *fn)
  135. {
  136.     char buf[BUFSIZ];
  137.     FILE *fd;
  138.     int bytes;
  139.     char *to, *addr;
  140.  
  141.     /* Open the reply file */
  142.     if ((fd = fopen (fn, "rb")) == NULL) {
  143.     fprintf(stderr, "%s: can't open %s\n", progname, fn);
  144.     return;
  145.     }
  146.  
  147.     /* Read through it */
  148.     while (fgets(buf, sizeof(buf), fd)) {
  149.     if (strncmp (buf, "#! rnews ", 9)) {
  150.         fprintf(stderr, "%s: malformed reply file\n", progname);
  151.         fclose(fd);
  152.         return;
  153.     }
  154.  
  155.     /* Get byte count */
  156.     sscanf(buf+9, "%d", &bytes);
  157.  
  158.     sendMail(fd, bytes);
  159.     }
  160.  
  161.     fclose(fd);
  162. }
  163.  
  164. /* Process a news reply file, usenet type */
  165.  
  166. static void
  167. sendNewsu (const char *fn)
  168. {
  169.     char buf[BUFSIZ];
  170.     FILE *fd;
  171.     int bytes;
  172.     char *grp;
  173.  
  174.     /* Open the reply file */
  175.     if ((fd = fopen (fn, "rb")) == NULL) {
  176.     fprintf (stderr, "%s: can't open %s\n", progname, fn);
  177.     return;
  178.     }
  179.  
  180.     /* Read through it */
  181.     while (fgets(buf, sizeof(buf), fd)) {
  182.     if (strncmp (buf, "#! rnews ", 9)) {
  183.         fprintf(stderr, "%s: malformed reply file\n", progname);
  184.         break;
  185.     }
  186.  
  187.     grp = getHeader(fd, "Newsgroups");
  188.     printf("%s: Posting article to %s\n", progname, grp);
  189.     free(grp);
  190.  
  191.     sscanf(buf+9, "%d", &bytes);
  192.     sendNews(fd, bytes);
  193.     }
  194.     fclose(fd);
  195. }
  196.  
  197. /* Process a mail reply file, binary type */
  198.  
  199. static void
  200. sendMailb (const char *fn)
  201. {
  202.     char buf[BUFSIZ];
  203.     unsigned char count[4];
  204.     FILE *fd;
  205.     int bytes;
  206.     char *to, *addr;
  207.  
  208.     /* Open the reply file */
  209.     if ((fd = fopen(fn, "rb")) == NULL) {
  210.     fprintf(stderr, "%s: can't open %s\n", progname, fn);
  211.     return;
  212.     }
  213.  
  214.     /* Read through it */
  215.     while (fread(count, sizeof(char), 4, fd) == 4) {
  216.     /* Get byte count */
  217.     bytes = ((count[0]*256 + count[1])*256 + count[2])*256 + count[3];
  218.     sendMail(fd, bytes);
  219.     }
  220.  
  221.     fclose(fd);
  222. }
  223.  
  224. /* Process a news reply file, binary type */
  225.  
  226. static void
  227. sendNewsb (const char *fn)
  228. {
  229.     char buf[BUFSIZ];
  230.     unsigned char count[4];
  231.     FILE *fd;
  232.     int bytes;
  233.     char *grp;
  234.  
  235.     /* Open the reply file */
  236.     if ((fd = fopen (fn, "rb")) == NULL) {
  237.     fprintf(stderr, "%s: can't open %s\n", progname, fn);
  238.     return;
  239.     }
  240.  
  241.     /* Read through it */
  242.     while (fread(count, sizeof(char), 4, fd) == 4) {
  243.     grp = getHeader(fd, "Newsgroups");
  244.     printf("%s: Posting article to %s\n", progname, grp);
  245.     free(grp);
  246.  
  247.     bytes = ((count[0]*256 + count[1])*256 + count[2])*256 + count[3];
  248.     sendNews(fd, bytes);
  249.     }
  250.     fclose(fd);
  251. }
  252.  
  253. /* Process a reply packet. */
  254.  
  255. void
  256. sendReply (void)
  257. {
  258.     FILE *rep_fd;
  259.     char buf[BUFSIZ], repFile[FILENAME_MAX];
  260.     char fname[FILENAME_MAX], kind[FILENAME_MAX], type[FILENAME_MAX];
  261.  
  262.     /* Open the packet */
  263.     strcpy(repFile, "REPLIES");
  264.     if ((rep_fd = fopen(repFile, "rb")) == NULL) {
  265.     fprintf(stderr, "%s: can't open %s\n", progname, repFile);
  266.     return;
  267.     }
  268.  
  269.     /* Look through lines in REPLIES file */
  270.     smtpSock = nntpSock = -1;
  271.     while (fgets(buf, sizeof(buf), rep_fd)) {
  272.     if (sscanf(buf, "%s %s %s", fname, kind, type) != 3) {
  273.         fprintf(stderr, "%s: malformed REPLIES line\n", progname);
  274.         break;
  275.     }
  276.  
  277.     /* Check reply type */
  278.     if (type[0] != 'u' && type[0] != 'b' && type[0] != 'B') {
  279.         fprintf(stderr, "%s: reply type %c not supported\n", progname,
  280.         type[0]);
  281.         continue;
  282.     }
  283.  
  284.     /* Look for mail or news */
  285.     if (strcmp(kind, "mail") == 0) {
  286.         mailer = getenv("MAILER");
  287.         if (!mailer && smtpSock == -1)
  288.         if ((smtpSock = smtpConnect()) < 0)
  289.             exit(EXIT_FAILURE);
  290.     } else if (strcmp(kind, "news") == 0) {
  291.         poster = getenv("POSTER");
  292.         if (!poster && nntpSock == -1)
  293.         if ((nntpSock = nntpConnect()) < 0)
  294.             exit(EXIT_FAILURE);
  295.     } else {
  296.         fprintf (stderr, "%s: bad reply kind: %s\n", progname, kind);
  297.         continue;
  298.     }
  299.  
  300.     /* Make file name */
  301.     strcat(fname, ".MSG");
  302.  
  303.     /* Process it */
  304.     switch (type[0]) {
  305.     case 'u':
  306.         if (strcmp(kind, "mail") == 0) sendMailu(fname);
  307.         if (strcmp(kind, "news") == 0) sendNewsu(fname);
  308.         break;
  309.     case 'b':
  310.     case 'B':
  311.         if (strcmp(kind, "mail") == 0) sendMailb(fname);
  312.         if (strcmp(kind, "news") == 0) sendNewsb(fname);
  313.         break;
  314.     }
  315.  
  316.     /* Delete it */
  317.     if (!readOnly)
  318.         remove(fname);
  319.     }
  320.  
  321.     if (smtpSock >= 0)
  322.     smtpClose(smtpSock);
  323.     if (nntpSock >= 0)
  324.     nntpClose(nntpSock);
  325.  
  326.     fclose(rep_fd);
  327.  
  328.     if (!readOnly)
  329.     remove(repFile);
  330. }
  331.  
  332.