sendmail.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C), 2000-2002 by Contributors to the monit codebase. 
00003  * All Rights Reserved.
00004  *
00005  * This program is free software; you can redistribute it and/or
00006  * modify it under the terms of the GNU General Public License as
00007  * published by the Free Software Foundation; either version 2 of the
00008  * License, or (at your option) any later version.
00009  *
00010  * This program is distributed in the hope that it will be useful, but
00011  * WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * General Public License for more details.
00014  * 
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software Foundation,
00017  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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 /* Private variables */
00049 static int  mysocket;
00050 static char *server;
00051 static sigjmp_buf die;
00052 
00053 /* Private prototypes */
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 /* ------------------------------------------------------------------ Public */
00072 
00073 
00078 void sendmail(Mail_T mail) {
00079 
00080   Mail_T m;
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(m= mail; m; m= m->next) { 
00101     
00102     do_send("MAIL FROM: <%s>\r\n", m->from);
00103     do_status();
00104     do_send("RCPT TO: <%s>\r\n", m->to);
00105     do_status();
00106     do_send("DATA\r\n");
00107     do_status();
00108     do_send("From: %s\r\n", m->from);
00109     do_send("To: %s\r\n", m->to);
00110     do_send("Subject: %s\r\n", m->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", m->message);
00118     if(m->opt_message)
00119     do_send("%s\r\n", m->opt_message);
00120     do_send(".\r\n");
00121     do_status();
00122 
00123     alarm(SMTP_TIMEOUT);
00124 
00125   }
00126 
00127   do_send("QUIT\r\n");
00128   
00129   exit:
00130   free(now);
00131   free(localhost);
00132   finalize_server();
00133   
00134 }
00135 
00136 
00137 /* ----------------------------------------------------------------- Private */
00138 
00139 
00140 static int initialize_server() {
00141   
00142   struct sigaction sa;
00143   
00144   if((server= Run.mailserver) == NULL) {
00145     
00146     server= LOCALHOST;
00147     
00148   }
00149   
00150   sa.sa_handler= do_timeout;
00151   sa.sa_flags= 0;
00152   sigemptyset(&sa.sa_mask);
00153   sigaction(SIGALRM, &sa, NULL);
00154   alarm(SMTP_TIMEOUT);
00155 
00156   if((mysocket= create_socket(server, SMTP_PORT, SOCK_STREAM)) <0) {
00157 
00158     log("Cannot open a connection to the mailserver '%s' -- %s\n",
00159     server, STRERROR);
00160     
00161     return FALSE;
00162     
00163   }
00164   
00165   return TRUE;
00166   
00167 }
00168 
00169 
00170 static void finalize_server() {
00171   
00172   alarm(0);
00173   
00174   if(mysocket && !close_socket(mysocket)) {
00175     
00176     log("Error shutting down socket connection to mailserver %s -- %s\n",
00177     server, STRERROR);
00178     
00179   }
00180   
00181 }
00182 
00183 
00184 static void do_timeout(int sig) {
00185   
00186   log("Sendmail: Connection to mailserver timed out\n");
00187   siglongjmp(die, TRUE);
00188   
00189 }
00190 
00191 
00192 void do_send(const char *format, ...) {
00193   
00194   char msg[2048];
00195   va_list ap;
00196   
00197   va_start(ap,format);
00198   vsnprintf(msg, 2048, format, ap);
00199   va_end(ap);
00200   
00201   if(sock_send(mysocket, msg, strlen(msg), 0) <= 0) {
00202     
00203     log("Sendmail: error sending data to the server '%s' -- %s\n",
00204       server, STRERROR);
00205     siglongjmp(die, TRUE);
00206     
00207   }
00208   
00209 }
00210 
00211 
00212 static void do_status() {
00213   
00214   int  status;
00215   char buf[STRLEN];
00216   
00217   if(sock_recv(mysocket, buf, sizeof(buf), 0) <= 0) {
00218     
00219     log("Sendmail: error receiving data from the mailserver '%s' -- %s\n",
00220     server, STRERROR);
00221     siglongjmp(die, TRUE);
00222     
00223   }
00224   
00225   chomp(buf);
00226   
00227   sscanf(buf, "%d", &status);
00228   if(status >= 400) {
00229     
00230     log("Sendmail error: %s\n", buf);
00231     siglongjmp(die, TRUE);
00232     
00233   }
00234   
00235 }
00236 
00237