00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include <stdio.h>
00024
00025 #ifdef HAVE_SYS_TYPES_H
00026 #include <sys/types.h>
00027 #endif
00028
00029 #include <sys/socket.h>
00030 #include <signal.h>
00031 #include <stdarg.h>
00032 #include <errno.h>
00033 #include <setjmp.h>
00034 #include <stdlib.h>
00035
00036 #ifdef HAVE_UNISTD_H
00037 #include <unistd.h>
00038 #endif
00039
00040 #ifdef HAVE_STRING_H
00041 #include <string.h>
00042 #endif
00043
00044
00045 #include "monitor.h"
00046 #include "net.h"
00047
00048
00049 static int mysocket;
00050 static char *server;
00051 static sigjmp_buf die;
00052
00053
00054 static void do_status();
00055 static void do_timeout(int);
00056 static void finalize_server();
00057 static int initialize_server();
00058 static void do_send(const char *, ...);
00059
00071
00072
00073
00078 void sendmail(Mail_T mail) {
00079
00080 Mail_T p;
00081 char *now = get_RFC1123date(NULL);
00082 char *localhost= get_localhostname();
00083
00084 if ( !initialize_server() ) {
00085
00086 goto exit;
00087
00088 }
00089
00090 if ( sigsetjmp(die, TRUE) ) {
00091
00092 goto exit;
00093
00094 }
00095
00096 do_status();
00097 do_send("HELO %s\r\n", localhost);
00098 do_status();
00099
00100 for(p= mail; p; p= p->next) {
00101
00102 do_send("MAIL FROM: <%s>\r\n", p->from);
00103 do_status();
00104 do_send("RCPT TO: <%s>\r\n", p->to);
00105 do_status();
00106 do_send("DATA\r\n");
00107 do_status();
00108 do_send("From: %s\r\n", p->from);
00109 do_send("To: %s\r\n", p->to);
00110 do_send("Subject: %s\r\n", p->subject);
00111 do_send("Date: %s\r\n", now);
00112 do_send("X-Mailer: %s %s\r\n", prog, VERSION);
00113 do_send("Mime-Version: 1.0\r\n");
00114 do_send("Content-Type: text/plain; charset=\"iso-8859-1\"\r\n");
00115 do_send("Content-Transfer-Encoding: quoted-printable\r\n");
00116 do_send("\r\n");
00117 do_send("%s\r\n", p->message);
00118 if(p->opt_message) do_send("%s\r\n", p->opt_message);
00119 do_send(".\r\n");
00120 do_status();
00121
00122 alarm(SMTP_TIMEOUT);
00123
00124 }
00125
00126 do_send("QUIT\r\n");
00127
00128 exit:
00129 free(now);
00130 free(localhost);
00131 finalize_server();
00132
00133 }
00134
00135
00136
00137
00138
00139 static int initialize_server() {
00140
00141 struct sigaction sa;
00142
00143 if ( (server= Run.mailserver) == NULL ) {
00144
00145 server= LOCALHOST;
00146
00147 }
00148
00149 sa.sa_handler= do_timeout;
00150 sa.sa_flags= 0;
00151 sigemptyset(&sa.sa_mask);
00152 sigaction(SIGALRM, &sa, NULL);
00153 alarm(SMTP_TIMEOUT);
00154
00155 if ( (mysocket= create_socket(server, SMTP_PORT, SOCK_STREAM)) <0 ) {
00156
00157 log("Cannot open a connection to the mailserver '%s' -- %s\n",
00158 server, STRERROR);
00159
00160 return FALSE;
00161
00162 }
00163
00164 return TRUE;
00165
00166 }
00167
00168
00169 static void finalize_server() {
00170
00171 alarm(0);
00172
00173 if ( mysocket && !close_socket(mysocket) ) {
00174
00175 log("Error shutting down socket connection to mailserver %s -- %s\n",
00176 server, STRERROR);
00177
00178 }
00179
00180 }
00181
00182
00183 static void do_timeout(int sig) {
00184
00185 log("Sendmail: Connection to mailserver timed out\n");
00186 siglongjmp(die, TRUE);
00187
00188 }
00189
00190
00191 void do_send(const char *format, ...) {
00192
00193 char msg[2048];
00194 va_list ap;
00195 va_start(ap,format);
00196 vsnprintf(msg, 2048, format, ap);
00197 va_end(ap);
00198
00199 if ( sock_send(mysocket, msg, strlen(msg), 0) <= 0 ) {
00200
00201 log("Sendmail: error sending data to the server '%s' -- %s\n",
00202 server, STRERROR);
00203 siglongjmp(die, TRUE);
00204
00205 }
00206
00207 }
00208
00209
00210 static void do_status() {
00211
00212 int status;
00213 char buf[STRLEN];
00214
00215 if ( sock_recv(mysocket, buf, sizeof(buf), 0) <= 0 ) {
00216
00217 log("Sendmail: error receiving data from the mailserver '%s' -- %s\n",
00218 server, STRERROR);
00219 siglongjmp(die, TRUE);
00220
00221 }
00222
00223 chomp(buf);
00224
00225 sscanf(buf, "%d", &status);
00226 if ( status >= 400 ) {
00227
00228 log("Sendmail error: %s\n", buf);
00229 siglongjmp(die, TRUE);
00230
00231 }
00232
00233 }
00234
00235