home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume3 / sm-smtp / converse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-03  |  4.8 KB  |  192 lines

  1. /*
  2.  * Do the necessary commands for a smtp transfer.  Start by waiting for the
  3.  * connection to open, then send HELO, MAIL, RCPT, and DATA.  Check the
  4.  * reply codes and give up if needed.
  5.  * 
  6.  * This code modified from the MIT UNIX TCP implementation:
  7.  * Copyright 1984 Massachusetts Institute of Technology
  8.  * 
  9.  * Permission to use, copy, modify, and distribute this file
  10.  * for any purpose and without fee is hereby granted, provided
  11.  * that this copyright and permission notice appear on all copies
  12.  * and supporting documentation, the name of M.I.T. not be used
  13.  * in advertising or publicity pertaining to distribution of the
  14.  * program without specific prior permission, and notice be given
  15.  * in supporting documentation that copying and distribution is
  16.  * by permission of M.I.T.  M.I.T. makes no representations about
  17.  * the suitability of this software for any purpose.  It is provided
  18.  * "as is" without express or implied warranty.
  19.  */
  20.  
  21. #include "smtp.h"
  22. #include <signal.h>
  23.  
  24. #define    MAXTIME        (60 * 5)        /* way too long - die */
  25.  
  26. int success, termcode;
  27.  
  28. int gethostname();
  29. extern int death();
  30. char *strcat(), *strcpy();
  31. extern char hostname[], hostdomain[];
  32.  
  33. converse(from, rcpt, sfi, sfo, mlfd)
  34. char    *from;                /* from address */
  35. char    *rcpt;                /* to address */
  36. FILE    *sfi;                /* smtp input */
  37. FILE    *sfo;                /* smtp output */
  38. FILE    *mlfd;                /* mail file descriptor */
  39. {
  40.     extern expect();
  41.     extern char *sendhost;
  42.     char buf[MAXSTR];
  43.     char host[64];
  44.  
  45.     (void) signal(SIGALRM, TYPESIG death);
  46.     (void) alarm(MAXTIME);        /* make sure we eventually go away */
  47.  
  48.     expect(220, sfi, sfo);            /* expect a service ready msg */
  49. /*    (void) gethostname(host, sizeof host); */
  50.  
  51.     if (sendhost == NULL)
  52.         (void) sprintf(buf, "HELO %s.%s\n", hostdomain);
  53.     else
  54.         (void) sprintf(buf, "HELO %s\n", sendhost);
  55.     tputs(buf, sfo);
  56.     expect(250, sfi, sfo);            /* expect an OK */
  57.  
  58.     (void) strcpy(buf, "MAIL FROM:<");
  59.     (void) strcat(buf, from);
  60.     (void) strcat(buf, ">\n");
  61.     tputs(buf, sfo);
  62.     expect(250, sfi, sfo);            /* expect OK */
  63.  
  64.     (void) strcpy(buf, "RCPT TO:<");
  65.     (void) strcat(buf, rcpt);
  66.     (void) strcat(buf, ">\n");
  67.     tputs(buf, sfo);
  68.     expect(250, sfi, sfo);            /* expect OK */
  69.  
  70.     tputs("DATA\n", sfo);
  71.     expect(354, sfi, sfo);
  72.     do_data(mlfd, sfo);
  73.     expect(250, sfi, sfo);            /* hope data is OK */
  74.     success = TRUE;
  75.  
  76.     tputs("QUIT\n", sfo);
  77.     /*expect(221, sfi, sfo);*/    /* who cares? */
  78. }
  79.  
  80.  
  81. /*
  82.  * Send the data from the specified mail file out on the current smtp
  83.  * connection.  Do the appropriate netascii conversion and starting '.'
  84.  * padding.  Send the <CRLF>.<CRLF> at completion.
  85.  */
  86. do_data(fd, sfo)
  87. register FILE    *fd;            /* mail file descriptor */
  88. FILE *sfo;                /* smtp files */
  89. {
  90.     register int c;        /* current character */
  91.     int nlseen = FALSE;        /* newline */
  92.     extern int debug;
  93.  
  94.     if (debug)
  95.         (void) printf("in do_data\n");
  96.     while ((c = getc(fd)) != EOF) {
  97.         if (nlseen) {
  98.             nlseen = FALSE;
  99.             if (c == '.')
  100.                 (void) putc('.', sfo);
  101.         }
  102.         if (c == '\n') {
  103.             (void) putc('\r', sfo);
  104.             nlseen = TRUE;
  105.         }
  106.         (void) putc(c, sfo);
  107. #ifdef what_the_fuck_is_all_this_about
  108.         if (c == '\r')
  109.             (void) putc('\0', sfo);
  110. #endif
  111.     }
  112.     if (!nlseen) {
  113.         (void) putc('\r', sfo);
  114.         (void) putc('\n', sfo);
  115.     }
  116. #ifdef this_is_bullshit_too
  117.     (void) putc('\n', sfo);    /* TODO: why is this line needed? */
  118. #endif
  119.     (void) putc('.', sfo);
  120.     (void) putc('\r', sfo);
  121.     (void) putc('\n', sfo);
  122.     (void) fflush(sfo);
  123.     if (ferror(sfo)) {
  124.         perror("write error in smtp");
  125.         bomb(E_IOERR);
  126.     }
  127.     if (debug)
  128.         (void) printf("leaving do_data\n");
  129. }
  130.  
  131.  
  132. /*
  133.  * Expect a reply message with the specified code.  If the specified code
  134.  * is received return TRUE; otherwise print the error message out on the
  135.  * standard output and give up.  Note that the reply can be a multiline
  136.  * message.
  137.  */
  138. expect(code, sfi, sfo)
  139. int    code;
  140. FILE    *sfi, *sfo;
  141. {
  142.     int retcd;
  143.     char cmdbuf[MAXSTR], termbuf[MAXSTR];
  144.     extern int debug;
  145.  
  146.     if (debug)
  147.         (void) fprintf(stderr, "expect %d ", code);
  148.     for (;;) {            /* get whole reply */
  149.         if (tgets(cmdbuf, sizeof cmdbuf, sfi) > 0) {    /* get input line */
  150.             if (cmdbuf[3] == '-') /* continuation line? */
  151.                 continue;
  152.                         /* no, last line */
  153.             if (sscanf(cmdbuf, "%d", &retcd) !=1 ){
  154.                 (void) fprintf(stderr,
  155.                     "non-numeric command reply!\n");
  156.                 bomb(E_IOERR);
  157.             }
  158.             if (retcd == code) {
  159.                 if (debug)
  160.                     (void) fprintf(stderr," got it\n");
  161.                 return;
  162.             }
  163.             else {
  164.                 if (debug)
  165.                     (void) fprintf(stderr,
  166.                         " FAIL (got %d)\n", retcd);
  167.                 /* return the error line */
  168.                 (void) strcpy(termbuf, cmdbuf);
  169.                 tputs ("QUIT\n", sfo);
  170.                 break;
  171.             }
  172.         } 
  173.         else if (success)
  174.             (void) strcpy(termbuf, "250 OK\n");
  175.         else {
  176.             (void) perror("smtp");
  177.             bomb(451);
  178.         }
  179.     }
  180.     termcode = !success;            /* error return */
  181.     if (debug)
  182.         (void) fprintf(stderr, " FALLOUT\n");
  183.     bomb(retcd);        /* map smtp errors to mailsys errors */
  184. }
  185.  
  186. /* Maximum time to live elapsed.  Die right now. */
  187. death()
  188. {
  189.     (void) fprintf(stderr, "Max transfer length timeout.\n");
  190.     (void) exit(1);
  191. }
  192.