home *** CD-ROM | disk | FTP | other *** search
- /*
- * Do the necessary commands for a smtp transfer. Start by waiting for the
- * connection to open, then send HELO, MAIL, RCPT, and DATA. Check the
- * reply codes and give up if needed.
- *
- * This code modified from the MIT UNIX TCP implementation:
- * Copyright 1984 Massachusetts Institute of Technology
- *
- * Permission to use, copy, modify, and distribute this file
- * for any purpose and without fee is hereby granted, provided
- * that this copyright and permission notice appear on all copies
- * and supporting documentation, the name of M.I.T. not be used
- * in advertising or publicity pertaining to distribution of the
- * program without specific prior permission, and notice be given
- * in supporting documentation that copying and distribution is
- * by permission of M.I.T. M.I.T. makes no representations about
- * the suitability of this software for any purpose. It is provided
- * "as is" without express or implied warranty.
- */
-
- #include "smtp.h"
- #include <signal.h>
-
- #define MAXTIME (60 * 5) /* way too long - die */
-
- int success, termcode;
-
- int gethostname();
- extern int death();
- char *strcat(), *strcpy();
- extern char hostname[], hostdomain[];
-
- converse(from, rcpt, sfi, sfo, mlfd)
- char *from; /* from address */
- char *rcpt; /* to address */
- FILE *sfi; /* smtp input */
- FILE *sfo; /* smtp output */
- FILE *mlfd; /* mail file descriptor */
- {
- extern expect();
- extern char *sendhost;
- char buf[MAXSTR];
- char host[64];
-
- (void) signal(SIGALRM, TYPESIG death);
- (void) alarm(MAXTIME); /* make sure we eventually go away */
-
- expect(220, sfi, sfo); /* expect a service ready msg */
- /* (void) gethostname(host, sizeof host); */
-
- if (sendhost == NULL)
- (void) sprintf(buf, "HELO %s.%s\n", hostdomain);
- else
- (void) sprintf(buf, "HELO %s\n", sendhost);
- tputs(buf, sfo);
- expect(250, sfi, sfo); /* expect an OK */
-
- (void) strcpy(buf, "MAIL FROM:<");
- (void) strcat(buf, from);
- (void) strcat(buf, ">\n");
- tputs(buf, sfo);
- expect(250, sfi, sfo); /* expect OK */
-
- (void) strcpy(buf, "RCPT TO:<");
- (void) strcat(buf, rcpt);
- (void) strcat(buf, ">\n");
- tputs(buf, sfo);
- expect(250, sfi, sfo); /* expect OK */
-
- tputs("DATA\n", sfo);
- expect(354, sfi, sfo);
- do_data(mlfd, sfo);
- expect(250, sfi, sfo); /* hope data is OK */
- success = TRUE;
-
- tputs("QUIT\n", sfo);
- /*expect(221, sfi, sfo);*/ /* who cares? */
- }
-
-
- /*
- * Send the data from the specified mail file out on the current smtp
- * connection. Do the appropriate netascii conversion and starting '.'
- * padding. Send the <CRLF>.<CRLF> at completion.
- */
- do_data(fd, sfo)
- register FILE *fd; /* mail file descriptor */
- FILE *sfo; /* smtp files */
- {
- register int c; /* current character */
- int nlseen = FALSE; /* newline */
- extern int debug;
-
- if (debug)
- (void) printf("in do_data\n");
- while ((c = getc(fd)) != EOF) {
- if (nlseen) {
- nlseen = FALSE;
- if (c == '.')
- (void) putc('.', sfo);
- }
- if (c == '\n') {
- (void) putc('\r', sfo);
- nlseen = TRUE;
- }
- (void) putc(c, sfo);
- #ifdef what_the_fuck_is_all_this_about
- if (c == '\r')
- (void) putc('\0', sfo);
- #endif
- }
- if (!nlseen) {
- (void) putc('\r', sfo);
- (void) putc('\n', sfo);
- }
- #ifdef this_is_bullshit_too
- (void) putc('\n', sfo); /* TODO: why is this line needed? */
- #endif
- (void) putc('.', sfo);
- (void) putc('\r', sfo);
- (void) putc('\n', sfo);
- (void) fflush(sfo);
- if (ferror(sfo)) {
- perror("write error in smtp");
- bomb(E_IOERR);
- }
- if (debug)
- (void) printf("leaving do_data\n");
- }
-
-
- /*
- * Expect a reply message with the specified code. If the specified code
- * is received return TRUE; otherwise print the error message out on the
- * standard output and give up. Note that the reply can be a multiline
- * message.
- */
- expect(code, sfi, sfo)
- int code;
- FILE *sfi, *sfo;
- {
- int retcd;
- char cmdbuf[MAXSTR], termbuf[MAXSTR];
- extern int debug;
-
- if (debug)
- (void) fprintf(stderr, "expect %d ", code);
- for (;;) { /* get whole reply */
- if (tgets(cmdbuf, sizeof cmdbuf, sfi) > 0) { /* get input line */
- if (cmdbuf[3] == '-') /* continuation line? */
- continue;
- /* no, last line */
- if (sscanf(cmdbuf, "%d", &retcd) !=1 ){
- (void) fprintf(stderr,
- "non-numeric command reply!\n");
- bomb(E_IOERR);
- }
- if (retcd == code) {
- if (debug)
- (void) fprintf(stderr," got it\n");
- return;
- }
- else {
- if (debug)
- (void) fprintf(stderr,
- " FAIL (got %d)\n", retcd);
- /* return the error line */
- (void) strcpy(termbuf, cmdbuf);
- tputs ("QUIT\n", sfo);
- break;
- }
- }
- else if (success)
- (void) strcpy(termbuf, "250 OK\n");
- else {
- (void) perror("smtp");
- bomb(451);
- }
- }
- termcode = !success; /* error return */
- if (debug)
- (void) fprintf(stderr, " FALLOUT\n");
- bomb(retcd); /* map smtp errors to mailsys errors */
- }
-
- /* Maximum time to live elapsed. Die right now. */
- death()
- {
- (void) fprintf(stderr, "Max transfer length timeout.\n");
- (void) exit(1);
- }
-