home *** CD-ROM | disk | FTP | other *** search
/ Tutto per Internet / Internet.iso / soft95 / News / souper95 / reply.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-17  |  6.9 KB  |  328 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. /* Pipe a message to the specified delivery agent. */
  69.  
  70. static void
  71. sendPipe (FILE *fd, size_t bytes, const char *agent)
  72. {
  73. #if defined(__WATCOMC__)
  74.     fprintf(stderr, "Watcom C++ does not support popen\n");
  75. #else
  76.     FILE *pfd;
  77.     unsigned char c;
  78.  
  79.     /* Open pipe to agent */
  80.     if ((pfd = popen(agent, "w")) == NULL) {
  81.     fprintf(stderr, "%s: can't open reply pipe\n", progname);
  82.     while (bytes--)
  83.         fgetc(fd);
  84.     return;
  85.     }
  86.  
  87.     /* Send message to pipe */
  88.     while (bytes--) {
  89.     c = fgetc(fd);
  90.     fputc(c, pfd);
  91.     }
  92.  
  93.     pclose(pfd);
  94. #endif
  95. }
  96.  
  97. static void
  98. sendMail (FILE *inf, size_t bytes)
  99. {
  100.     if (mailer) {
  101.     char *to = getHeader(inf, "To");
  102.     if (to) {
  103.         printf("%s: mailing to %s\n", progname, to);
  104.         free(to);
  105.     }
  106.  
  107.     /* Pipe message to delivery agent */
  108.     sendPipe(inf, bytes, mailer);
  109.  
  110.     } else if (!smtpMail(smtpSock, inf, bytes)) {
  111.     exit(EXIT_FAILURE);
  112.     }
  113. }
  114.  
  115. static void
  116. sendNews (FILE *inf, size_t bytes)
  117. {
  118.     if (poster) {
  119.     /* Pipe message to delivery agent */
  120.     sendPipe(inf, bytes, poster);
  121.  
  122.     } else if (!nntpPost(nntpSock, inf, bytes)) {
  123.     exit(EXIT_FAILURE);
  124.     }
  125. }
  126.  
  127. /* Process a mail reply file, usenet type */
  128.  
  129. static void
  130. sendMailu (const char *fn)
  131. {
  132.     char buf[BUFSIZ];
  133.     FILE *fd;
  134.     int bytes;
  135.     char *to, *addr;
  136.  
  137.     /* Open the reply file */
  138.     if ((fd = fopen (fn, "rb")) == NULL) {
  139.     fprintf(stderr, "%s: can't open %s\n", progname, fn);
  140.     return;
  141.     }
  142.  
  143.     /* Read through it */
  144.     while (fgets(buf, sizeof(buf), fd)) {
  145.     if (strncmp (buf, "#! rnews ", 9)) {
  146.         fprintf(stderr, "%s: malformed reply file\n", progname);
  147.         fclose(fd);
  148.         return;
  149.     }
  150.  
  151.     /* Get byte count */
  152.     sscanf(buf+9, "%d", &bytes);
  153.  
  154.     sendMail(fd, bytes);
  155.     }
  156.  
  157.     fclose(fd);
  158. }
  159.  
  160. /* Process a news reply file, usenet type */
  161.  
  162. static void
  163. sendNewsu (const char *fn)
  164. {
  165.     char buf[BUFSIZ];
  166.     FILE *fd;
  167.     int bytes;
  168.     char *grp;
  169.  
  170.     /* Open the reply file */
  171.     if ((fd = fopen (fn, "rb")) == NULL) {
  172.     fprintf (stderr, "%s: can't open %s\n", progname, fn);
  173.     return;
  174.     }
  175.  
  176.     /* Read through it */
  177.     while (fgets(buf, sizeof(buf), fd)) {
  178.     if (strncmp (buf, "#! rnews ", 9)) {
  179.         fprintf(stderr, "%s: malformed reply file\n", progname);
  180.         break;
  181.     }
  182.  
  183.     grp = getHeader(fd, "Newsgroups");
  184.     printf("%s: Posting article to %s\n", progname, grp);
  185.     free(grp);
  186.  
  187.     sscanf(buf+9, "%d", &bytes);
  188.     sendNews(fd, bytes);
  189.     }
  190.     fclose(fd);
  191. }
  192.  
  193. /* Process a mail reply file, binary type */
  194.  
  195. static void
  196. sendMailb (const char *fn)
  197. {
  198.     char buf[BUFSIZ];
  199.     unsigned char count[4];
  200.     FILE *fd;
  201.     int bytes;
  202.     char *to, *addr;
  203.  
  204.     /* Open the reply file */
  205.     if ((fd = fopen(fn, "rb")) == NULL) {
  206.     fprintf(stderr, "%s: can't open %s\n", progname, fn);
  207.     return;
  208.     }
  209.  
  210.     /* Read through it */
  211.     while (fread(count, sizeof(char), 4, fd) == 4) {
  212.     /* Get byte count */
  213.     bytes = ((count[0]*256 + count[1])*256 + count[2])*256 + count[3];
  214.     sendMail(fd, bytes);
  215.     }
  216.  
  217.     fclose(fd);
  218. }
  219.  
  220. /* Process a news reply file, binary type */
  221.  
  222. static void
  223. sendNewsb (const char *fn)
  224. {
  225.     char buf[BUFSIZ];
  226.     unsigned char count[4];
  227.     FILE *fd;
  228.     int bytes;
  229.     char *grp;
  230.  
  231.     /* Open the reply file */
  232.     if ((fd = fopen (fn, "rb")) == NULL) {
  233.     fprintf(stderr, "%s: can't open %s\n", progname, fn);
  234.     return;
  235.     }
  236.  
  237.     /* Read through it */
  238.     while (fread(count, sizeof(char), 4, fd) == 4) {
  239.     grp = getHeader(fd, "Newsgroups");
  240.     printf("%s: Posting article to %s\n", progname, grp);
  241.     free(grp);
  242.  
  243.     bytes = ((count[0]*256 + count[1])*256 + count[2])*256 + count[3];
  244.     sendNews(fd, bytes);
  245.     }
  246.     fclose(fd);
  247. }
  248.  
  249. /* Process a reply packet. */
  250.  
  251. void
  252. sendReply (void)
  253. {
  254.     FILE *rep_fd;
  255.     char buf[BUFSIZ], repFile[FILENAME_MAX];
  256.     char fname[FILENAME_MAX], kind[FILENAME_MAX], type[FILENAME_MAX];
  257.  
  258.     /* Open the packet */
  259.     strcpy(repFile, "REPLIES");
  260.     if ((rep_fd = fopen(repFile, "rb")) == NULL) {
  261.     fprintf(stderr, "%s: can't open %s\n", progname, repFile);
  262.     return;
  263.     }
  264.  
  265.     /* Look through lines in REPLIES file */
  266.     smtpSock = nntpSock = -1;
  267.     while (fgets(buf, sizeof(buf), rep_fd)) {
  268.     if (sscanf(buf, "%s %s %s", fname, kind, type) != 3) {
  269.         fprintf(stderr, "%s: malformed REPLIES line\n", progname);
  270.         break;
  271.     }
  272.  
  273.     /* Check reply type */
  274.     if (type[0] != 'u' && type[0] != 'b' && type[0] != 'B') {
  275.         fprintf(stderr, "%s: reply type %c not supported\n", progname,
  276.         type[0]);
  277.         continue;
  278.     }
  279.  
  280.     /* Look for mail or news */
  281.     if (strcmp(kind, "mail") == 0) {
  282.         mailer = getenv("MAILER");
  283.         if (!mailer && smtpSock == -1)
  284.         if ((smtpSock = smtpConnect()) < 0)
  285.             exit(EXIT_FAILURE);
  286.     } else if (strcmp(kind, "news") == 0) {
  287.         poster = getenv("POSTER");
  288.         if (!poster && nntpSock == -1)
  289.         if ((nntpSock = nntpConnect()) < 0)
  290.             exit(EXIT_FAILURE);
  291.     } else {
  292.         fprintf (stderr, "%s: bad reply kind: %s\n", progname, kind);
  293.         continue;
  294.     }
  295.  
  296.     /* Make file name */
  297.     strcat(fname, ".MSG");
  298.  
  299.     /* Process it */
  300.     switch (type[0]) {
  301.     case 'u':
  302.         if (strcmp(kind, "mail") == 0) sendMailu(fname);
  303.         if (strcmp(kind, "news") == 0) sendNewsu(fname);
  304.         break;
  305.     case 'b':
  306.     case 'B':
  307.         if (strcmp(kind, "mail") == 0) sendMailb(fname);
  308.         if (strcmp(kind, "news") == 0) sendNewsb(fname);
  309.         break;
  310.     }
  311.  
  312.     /* Delete it */
  313.     if (!readOnly)
  314.         remove(fname);
  315.     }
  316.  
  317.     if (smtpSock >= 0)
  318.     smtpClose(smtpSock);
  319.     if (nntpSock >= 0)
  320.     nntpClose(nntpSock);
  321.  
  322.     fclose(rep_fd);
  323.  
  324.     if (!readOnly)
  325.     remove(repFile);
  326. }
  327.  
  328.