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 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 /* ----------------------------------------------------------------- Private */
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