]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/tools/bsmtp.c
Replace explicit checks for "/" with calls to IsPathSeparator, strchr with first_path...
[bacula/bacula] / bacula / src / tools / bsmtp.c
index cb994bdf20545330d2aa89fe7c4cbff58234a403..9cccc49c29051eb2f0ffe15492d97b72c1e9bab1 100644 (file)
 
  */
 
-#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"
 
+#if defined(HAVE_WIN32)
+#include <lmcons.h>
 #endif
 
 /* Dummy functions */
@@ -80,6 +70,9 @@ static void get_response(void)
         if (len > 0) {
            buf[len-1] = 0;
         }
+        if (debug_level >= 10) {
+            fprintf(stderr, "%s <-- %s\n", mailhost, buf);
+        }
         Dmsg2(10, "%s --> %s\n", mailhost, buf);
         if (!isdigit((int)buf[0]) || buf[0] > '3') {
             Pmsg2(0, _("Fatal malformed reply from %s: %s\n"), mailhost, buf);
@@ -89,6 +82,9 @@ static void get_response(void)
             break;
         }
     }
+    if (ferror(rfp)) {
+        fprintf(stderr, _("Fatal fgets error: ERR=%s\n"), strerror(errno));
+    }
     return;
 }
 
@@ -125,6 +121,8 @@ _("\n"
 "       -f          set the From: field\n"
 "       -h          use mailhost:port as the SMTP server\n"
 "       -s          set the Subject: field\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);
 
@@ -141,8 +139,14 @@ int main (int argc, char *argv[])
     char buf[MAXSTRING];
     struct sockaddr_in sin;
     struct hostent *hp;
-    int s, r, i, ch;
+    int i, ch;
+    unsigned long maxlines, lines;
+#if defined(HAVE_WIN32)
+    SOCKET s;
+#else
+    int s, r;
     struct passwd *pwd;
+#endif
     char *cp, *p;
     time_t now = time(NULL);
     struct tm tm;
@@ -152,8 +156,9 @@ int main (int argc, char *argv[])
    textdomain("bacula");
 
    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':
          Dmsg1(20, "cc=%s\n", optarg);
@@ -191,6 +196,11 @@ int main (int argc, char *argv[])
          reply_addr = optarg;
          break;
 
+      case 'l':
+         Dmsg1(20, "maxlines=%s\n", optarg);
+         maxlines = (unsigned long) atol(optarg);
+         break;
+
       case '?':
       default:
          usage();
@@ -206,6 +216,10 @@ int main (int argc, char *argv[])
       exit(1);
    }
 
+#if defined(HAVE_WIN32)
+   _setmode(0, _O_BINARY);
+#endif
+
    /*
     *  Determine SMTP server
     */
@@ -217,6 +231,12 @@ int main (int argc, char *argv[])
       }
    }
 
+#if defined(HAVE_WIN32)
+   WSADATA  wsaData;
+
+   WSAStartup(MAKEWORD(2,2), &wsaData);
+#endif
+
    /*
     *  Find out my own host name for HELO;
     *  if possible, get the fully qualified domain name
@@ -237,11 +257,22 @@ int main (int argc, char *argv[])
     *  Determine from address.
     */
    if (from_addr == NULL) {
+#if defined(HAVE_WIN32)
+      DWORD dwSize = UNLEN + 1;
+      LPSTR lpszBuffer = (LPSTR)alloca(dwSize);
+
+      if (GetUserName(lpszBuffer, &dwSize)) {
+         sprintf(buf, "%s@%s", lpszBuffer, my_hostname);
+      } else {
+         sprintf(buf, "unknown-user@%s", my_hostname);
+      }
+#else
       if ((pwd = getpwuid(getuid())) == 0) {
          sprintf(buf, "userid-%d@%s", (int)getuid(), my_hostname);
       } else {
          sprintf(buf, "%s@%s", pwd->pw_name, my_hostname);
       }
+#endif
       from_addr = bstrdup(buf);
    }
    Dmsg1(20, "From addr=%s\n", from_addr);
@@ -269,15 +300,41 @@ hp:
    memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length);
    sin.sin_family = hp->h_addrtype;
    sin.sin_port = htons(mailport);
+#if defined(HAVE_WIN32)
+   if ((s = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, 0)) < 0) {
+      Pmsg1(0, _("Fatal socket error: ERR=%s\n"), strerror(errno));
+      exit(1);
+   }
+#else
    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
       Pmsg1(0, _("Fatal socket error: ERR=%s\n"), strerror(errno));
       exit(1);
    }
+#endif
    if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
       Pmsg2(0, _("Fatal connect error to %s: ERR=%s\n"), mailhost, strerror(errno));
       exit(1);
    }
    Dmsg0(20, "Connected\n");
+
+#if defined(HAVE_WIN32)
+   int fdSocket = _open_osfhandle(s, _O_RDWR | _O_BINARY);
+   if (fdSocket == -1) {
+      Pmsg1(0, _("Fatal _open_osfhandle error: ERR=%s\n"), strerror(errno));
+      exit(1);
+   }
+
+   int fdSocket2 = dup(fdSocket);
+
+   if ((sfp = fdopen(fdSocket, "wb")) == NULL) {
+      Pmsg1(0, _("Fatal fdopen error: ERR=%s\n"), strerror(errno));
+      exit(1);
+   }
+   if ((rfp = fdopen(fdSocket2, "rb")) == NULL) {
+      Pmsg1(0, _("Fatal fdopen error: ERR=%s\n"), strerror(errno));
+      exit(1);
+   }
+#else
    if ((r = dup(s)) < 0) {
       Pmsg1(0, _("Fatal dup error: ERR=%s\n"), strerror(errno));
       exit(1);
@@ -290,6 +347,7 @@ hp:
       Pmsg1(0, _("Fatal fdopen error: ERR=%s\n"), strerror(errno));
       exit(1);
    }
+#endif
 
    /*
     *  Send SMTP headers
@@ -326,6 +384,19 @@ hp:
       fprintf(sfp, "Errors-To: %s\r\n", err_addr);
       Dmsg1(10, "Errors-To: %s\r\n", err_addr);
    }
+
+#if defined(HAVE_WIN32)
+   DWORD dwSize = UNLEN + 1;
+   LPSTR lpszBuffer = (LPSTR)alloca(dwSize);
+
+   if (GetUserName(lpszBuffer, &dwSize)) {
+      fprintf(sfp, "Sender: %s@%s\r\n", lpszBuffer, my_hostname);
+      Dmsg2(10, "Sender: %s@%s\r\n", lpszBuffer, my_hostname);
+   } else {
+      fprintf(sfp, "Sender: unknown-user@%s\r\n", my_hostname);
+      Dmsg1(10, "Sender: unknown-user@%s\r\n", my_hostname);
+   }
+#else
    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);
@@ -333,6 +404,7 @@ hp:
       fprintf(sfp, "Sender: %s@%s\r\n", pwd->pw_name, my_hostname);
       Dmsg2(10, "Sender: %s@%s\r\n", pwd->pw_name, my_hostname);
    }
+#endif
 
    fprintf(sfp, "To: %s", argv[0]);
    Dmsg1(10, "To: %s", argv[0]);
@@ -349,8 +421,24 @@ hp:
    }
 
    /* Add RFC822 date */
-   localtime_r(&now, &tm);
+   (void)localtime_r(&now, &tm);
+#if defined(HAVE_WIN32)
+#if defined(HAVE_MINGW)
+__MINGW_IMPORT long    _dstbias;
+#endif
+   long tzoffset = 0;
+
+   _tzset();
+
+   tzoffset = _timezone;
+   tzoffset += _dstbias;
+   tzoffset /= 60;
+
+   size_t length = strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S", &tm);
+   sprintf(&buf[length], " %+2.2ld%2.2u", -tzoffset / 60, abs(tzoffset) % 60);
+#else
    strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S %z", &tm);
+#endif
    fprintf(sfp, "Date: %s\r\n", buf);
    Dmsg1(10, "Date: %s\r\n", buf);
 
@@ -359,15 +447,27 @@ hp:
    /*
     *  Send message body
     */
+   lines = 0;
    while (fgets(buf, sizeof(buf), stdin)) {
-      buf[strlen(buf)-1] = 0;
-      if (strcmp(buf, ".") == 0) { /* quote lone dots */
-         fprintf(sfp, "..\r\n");
+      if (maxlines > 0 && ++lines > maxlines) {
+         Dmsg1(20, "skip line because of maxlines limit: %lu\n", maxlines);
+         break;
+      }
+      buf[sizeof(buf)-1] = '\0';
+      buf[strlen(buf)-1] = '\0';
+      if (buf[0] == '.' && buf[1] == '\0') { /* quote lone dots */
+         fputs("..\r\n", sfp);
       } else {                     /* pass body through unchanged */
-         fprintf(sfp, "%s\r\n", buf);
+         fputs(buf, sfp);
+         fputs("\r\n", sfp);
       }
    }
 
+   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
     */