]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/tools/bsmtp.c
This commit was manufactured by cvs2svn to create tag
[bacula/bacula] / bacula / src / tools / bsmtp.c
index f851582e585872b481198c127abae81b752dfa17..5c22b0c830a0833f6fdec6906f31d11180ab85bf 100644 (file)
@@ -1,23 +1,17 @@
 /*
-   Copyright (C) 2000-2003 Kern Sibbald and John Walker
+  Copyright (C) 2001-2006 Kern Sibbald
 
    This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2 of
-   the License, or (at your option) any later version.
+   modify it under the terms of the GNU General Public License
+   version 2 as amended with additional clauses defined in the
+   file LICENSE in the main source directory.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-   General Public License for more details.
-
-   You should have received a copy of the GNU General Public
-   License along with this program; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-   MA 02111-1307, USA.
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
+   the file LICENSE for additional details.
 
  */
-
 /*
    Derived from a SMTPclient:
 
        www.engelschall.com
 
    Kern Sibbald, July 2001
-  
+
    Version $Id$
-    
+
  */
 
+#ifdef APCUPSD
+
+#include "apc.h"
+#undef main
+#define my_name_is(x)
+#define bstrdup(x) strdup(x)
+UPSINFO myUPS;
+UPSINFO *core_ups = &myUPS;
+#define MY_NAME "smtp"
+
+#else
+
 #include "bacula.h"
 #include "jcr.h"
+#define MY_NAME "bsmtp"
+
+#endif
+
+/* Dummy functions */
+int generate_daemon_event(JCR *jcr, const char *event) 
+   { return 1; }
 
 #ifndef MAXSTRING
 #define MAXSTRING 254
@@ -47,30 +60,34 @@ static char *from_addr = NULL;
 static char *cc_addr = NULL;
 static char *subject = NULL;
 static char *err_addr = NULL;
-static char *mailhost = NULL;
+static const char *mailhost = NULL;
 static char *reply_addr = NULL;
 static int mailport = 25;
 static char my_hostname[MAXSTRING];
 
 
 /*
- *  examine message from server 
+ *  examine message from server
  */
 static void get_response(void)
 {
     char buf[MAXSTRING];
 
     Dmsg0(50, "Calling fgets on read socket rfp.\n");
+    buf[3] = 0;
     while (fgets(buf, sizeof(buf), rfp)) {
-       buf[strlen(buf)-1] = 0;
+        int len = strlen(buf);
+        if (len > 0) {
+           buf[len-1] = 0;
+        }
         Dmsg2(10, "%s --> %s\n", mailhost, buf);
         if (!isdigit((int)buf[0]) || buf[0] > '3') {
-            Dmsg1(10, "Fatal malformed reply: %s\n", buf);
-           exit(1);
-       }
-        if (buf[4] != '-') {
-           break;
-       }
+            Pmsg2(0, _("Fatal malformed reply from %s: %s\n"), mailhost, buf);
+            exit(1);
+        }
+        if (buf[3] != '-') {
+            break;
+        }
     }
     return;
 }
@@ -78,18 +95,18 @@ static void get_response(void)
 /*
  *  say something to server and check the response
  */
-static void chat(char *fmt, ...)
+static void chat(const char *fmt, ...)
 {
     va_list ap;
 
     va_start(ap, fmt);
     vfprintf(sfp, fmt, ap);
     if (debug_level >= 10) {
-       fprintf(stdout, "%s --> ", my_hostname); 
+       fprintf(stdout, "%s --> ", my_hostname);
        vfprintf(stdout, fmt, ap);
     }
     va_end(ap);
-  
+
     fflush(sfp);
     if (debug_level >= 10) {
        fflush(stdout);
@@ -101,15 +118,17 @@ static void chat(char *fmt, ...)
 static void usage()
 {
    fprintf(stderr,
-"\n"
-"Usage: smtp [-f from] [-h mailhost] [-s subject] [-c copy] [recepient ...]\n"
+_("\n"
+"Usage: %s [-f from] [-h mailhost] [-s subject] [-c copy] [recipient ...]\n"
 "       -c          set the Cc: field\n"
 "       -dnn        set debug level to nn\n"
 "       -f          set the From: field\n"
 "       -h          use mailhost:port as the SMTP server\n"
 "       -s          set the Subject: field\n"
-"       -?          print this message.\n"  
-"\n");
+"       -r          set the Reply-To: field\n"
+"       -l          set the maximum number of lines that should be sent (default: unlimited)\n"
+"       -?          print this message.\n"
+"\n"), MY_NAME);
 
    exit(1);
 }
@@ -125,60 +144,73 @@ int main (int argc, char *argv[])
     struct sockaddr_in sin;
     struct hostent *hp;
     int s, r, i, ch;
+    unsigned long maxlines, lines;
     struct passwd *pwd;
     char *cp, *p;
+    time_t now = time(NULL);
+    struct tm tm;
+    
+   setlocale(LC_ALL, "en_US");
+   bindtextdomain("bacula", LOCALEDIR);
+   textdomain("bacula");
 
-   my_name_is(argc, argv, "smtp");
+   my_name_is(argc, argv, "bsmtp");
+   maxlines = 0;
 
-   while ((ch = getopt(argc, argv, "c:d:f:h:r:s:?")) != -1) {
+   while ((ch = getopt(argc, argv, "c:d:f:h:r:s:l:?")) != -1) {
       switch (ch) {
-      case 'c':                    
+      case 'c':
          Dmsg1(20, "cc=%s\n", optarg);
-        cc_addr = optarg;
-        break;
+         cc_addr = optarg;
+         break;
 
       case 'd':                    /* set debug level */
-        debug_level = atoi(optarg);
-        if (debug_level <= 0) {
-           debug_level = 1; 
-        }
+         debug_level = atoi(optarg);
+         if (debug_level <= 0) {
+            debug_level = 1;
+         }
          Dmsg1(20, "Debug level = %d\n", debug_level);
-        break;
+         break;
 
       case 'f':                    /* from */
-        from_addr = optarg;
-        break;
+         from_addr = optarg;
+         break;
 
       case 'h':                    /* smtp host */
          Dmsg1(20, "host=%s\n", optarg);
          p = strchr(optarg, ':');
-        if (p) {
-           *p++ = 0;
-           mailport = atoi(p);
-        }
-        mailhost = optarg;
-        break;
+         if (p) {
+            *p++ = 0;
+            mailport = atoi(p);
+         }
+         mailhost = optarg;
+         break;
 
       case 's':                    /* subject */
          Dmsg1(20, "subject=%s\n", optarg);
-        subject = optarg;
-        break;
+         subject = optarg;
+         break;
 
       case 'r':                    /* reply address */
-        reply_addr = optarg;
+         reply_addr = optarg;
+         break;
+
+      case 'l':
+        Dmsg1(20, "maxlines=%s\n", optarg);
+        maxlines = (unsigned long) atol(optarg);
         break;
 
       case '?':
       default:
-        usage();
+         usage();
 
-      }  
+      }
    }
    argc -= optind;
    argv += optind;
 
    if (argc < 1) {
-      Dmsg0(0, "Fatal error: no recipient given.\n");
+      Pmsg0(0, _("Fatal error: no recipient given.\n"));
       usage();
       exit(1);
    }
@@ -188,23 +220,23 @@ int main (int argc, char *argv[])
     */
    if (mailhost == NULL) {
       if ((cp = getenv("SMTPSERVER")) != NULL) {
-        mailhost = cp;
+         mailhost = cp;
       } else {
          mailhost = "localhost";
       }
    }
 
    /*
-    *  Find out my own host name for HELO; 
+    *  Find out my own host name for HELO;
     *  if possible, get the fully qualified domain name
     */
    if (gethostname(my_hostname, sizeof(my_hostname) - 1) < 0) {
-      Dmsg1(0, "Fatal gethostname error: ERR=%s\n", strerror(errno));
+      Pmsg1(0, _("Fatal gethostname error: ERR=%s\n"), strerror(errno));
       exit(1);
    }
    if ((hp = gethostbyname(my_hostname)) == NULL) {
-      Dmsg2(0, "Fatal gethostbyname for myself failed \"%s\": ERR=%s\n", my_hostname,
-        strerror(errno));
+      Pmsg2(0, _("Fatal gethostbyname for myself failed \"%s\": ERR=%s\n"), my_hostname,
+         strerror(errno));
       exit(1);
    }
    strcpy(my_hostname, hp->h_name);
@@ -228,18 +260,18 @@ int main (int argc, char *argv[])
     */
 hp:
    if ((hp = gethostbyname(mailhost)) == NULL) {
-      Dmsg2(0, "Error unknown mail host \"%s\": ERR=%s\n", mailhost,
-        strerror(errno));
+      Pmsg2(0, _("Error unknown mail host \"%s\": ERR=%s\n"), mailhost,
+         strerror(errno));
       if (strcasecmp(mailhost, "localhost") != 0) {
-         Dmsg0(0, "Retrying connection using \"localhost\".\n");
+         Pmsg0(0, _("Retrying connection using \"localhost\".\n"));
          mailhost = "localhost";
-        goto hp;
+         goto hp;
       }
       exit(1);
    }
 
    if (hp->h_addrtype != AF_INET) {
-      Dmsg1(0, "Fatal error: Unknown address family for smtp host: %d\n", hp->h_addrtype);
+      Pmsg1(0, _("Fatal error: Unknown address family for smtp host: %d\n"), hp->h_addrtype);
       exit(1);
    }
    memset((char *)&sin, 0, sizeof(sin));
@@ -247,95 +279,121 @@ hp:
    sin.sin_family = hp->h_addrtype;
    sin.sin_port = htons(mailport);
    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-      Dmsg1(0, "Fatal socket error: ERR=%s\n", strerror(errno));
+      Pmsg1(0, _("Fatal socket error: ERR=%s\n"), strerror(errno));
       exit(1);
    }
    if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
-      Dmsg1(0, "Fatal connect error: ERR=%s\n", strerror(errno));
+      Pmsg2(0, _("Fatal connect error to %s: ERR=%s\n"), mailhost, strerror(errno));
       exit(1);
    }
    Dmsg0(20, "Connected\n");
    if ((r = dup(s)) < 0) {
-      Dmsg1(0, "Fatal dup error: ERR=%s\n", strerror(errno));
+      Pmsg1(0, _("Fatal dup error: ERR=%s\n"), strerror(errno));
       exit(1);
    }
    if ((sfp = fdopen(s, "w")) == 0) {
-      Dmsg1(0, "Fatal fdopen error: ERR=%s\n", strerror(errno));
+      Pmsg1(0, _("Fatal fdopen error: ERR=%s\n"), strerror(errno));
       exit(1);
    }
    if ((rfp = fdopen(r, "r")) == 0) {
-      Dmsg1(0, "Fatal fdopen error: ERR=%s\n", strerror(errno));
+      Pmsg1(0, _("Fatal fdopen error: ERR=%s\n"), strerror(errno));
       exit(1);
    }
 
-   /* 
+   /*
     *  Send SMTP headers
     */
    get_response(); /* banner */
    chat("helo %s\r\n", my_hostname);
-   chat("mail from: <%s>\r\n", from_addr);
+   chat("mail from:<%s>\r\n", from_addr);
 
    for (i = 0; i < argc; i++) {
       Dmsg1(20, "rcpt to: %s\n", argv[i]);
-      chat("rcpt to: <%s>\r\n", argv[i]);
+      chat("rcpt to:<%s>\r\n", argv[i]);
    }
 
    if (cc_addr) {
-      chat("rcpt to: <%s>\r\n", cc_addr);
+      chat("rcpt to:<%s>\r\n", cc_addr);
    }
    Dmsg0(20, "Data\n");
    chat("data\r\n");
 
-   /* 
+   /*
     *  Send message header
     */
    fprintf(sfp, "From: %s\r\n", from_addr);
+   Dmsg1(10, "From: %s\r\n", from_addr);
    if (subject) {
       fprintf(sfp, "Subject: %s\r\n", subject);
+      Dmsg1(10, "Subject: %s\r\n", subject);
    }
    if (reply_addr) {
       fprintf(sfp, "Reply-To: %s\r\n", reply_addr);
+      Dmsg1(10, "Reply-To: %s\r\n", reply_addr);
    }
    if (err_addr) {
       fprintf(sfp, "Errors-To: %s\r\n", err_addr);
+      Dmsg1(10, "Errors-To: %s\r\n", err_addr);
    }
    if ((pwd = getpwuid(getuid())) == 0) {
       fprintf(sfp, "Sender: userid-%d@%s\r\n", (int)getuid(), my_hostname);
+      Dmsg2(10, "Sender: userid-%d@%s\r\n", (int)getuid(), my_hostname);
    } else {
       fprintf(sfp, "Sender: %s@%s\r\n", pwd->pw_name, my_hostname);
+      Dmsg2(10, "Sender: %s@%s\r\n", pwd->pw_name, my_hostname);
    }
 
    fprintf(sfp, "To: %s", argv[0]);
+   Dmsg1(10, "To: %s", argv[0]);
    for (i = 1; i < argc; i++) {
       fprintf(sfp, ",%s", argv[i]);
+      Dmsg1(10, ",%s", argv[i]);
    }
 
    fprintf(sfp, "\r\n");
+   Dmsg0(10, "\r\n");
    if (cc_addr) {
       fprintf(sfp, "Cc: %s\r\n", cc_addr);
+      Dmsg1(10, "Cc: %s\r\n", cc_addr);
    }
 
+   /* Add RFC822 date */
+   localtime_r(&now, &tm);
+   strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S %z", &tm);
+   fprintf(sfp, "Date: %s\r\n", buf);
+   Dmsg1(10, "Date: %s\r\n", buf);
+
    fprintf(sfp, "\r\n");
 
-   /* 
-    *  Send message body 
+   /*
+    *  Send message body
     */
+   lines = 0;
    while (fgets(buf, sizeof(buf), stdin)) {
+      if (maxlines > 0 && ++lines > maxlines) {
+         Dmsg1(20, "skip line because of maxlines limit: %lu\n", maxlines);
+        continue;
+      }
       buf[strlen(buf)-1] = 0;
       if (strcmp(buf, ".") == 0) { /* quote lone dots */
          fprintf(sfp, "..\r\n");
-      } else {                    /* pass body through unchanged */
+      } else {                     /* pass body through unchanged */
          fprintf(sfp, "%s\r\n", buf);
       }
    }
 
-   /* 
+   if (lines > maxlines) {
+      Dmsg1(10, "hit maxlines limit: %lu\n", maxlines);
+      fprintf(sfp, "\r\n[maximum of %lu lines exceeded, skipped %lu lines of output]\r\n", maxlines, lines-maxlines);
+   }
+
+   /*
     *  Send SMTP quit command
     */
    chat(".\r\n");
    chat("quit\r\n");
 
-   /* 
+   /*
     *  Go away gracefully ...
     */
    exit(0);