From 0d79044154fbbf54c2be9bf2a8810280590d54e0 Mon Sep 17 00:00:00 2001 From: Robert Nelson Date: Fri, 6 Oct 2006 18:28:35 +0000 Subject: [PATCH] Fix bug # 688. Port bsmtp to Windows. Add Bacula/bin to directory searched for scripts/programs specified without paths in configuration files. Add bsleep.exe used in scripts to sleep between commands. Fix bugs in mtx-changer.cmd and customize bacula-sd.conf template to be Windows specific. Fix time warp in ChangeLog and technotes. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@3536 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/ChangeLog | 4 +- bacula/src/lib/bregex.c | 88 +++++++++++++++---------------- bacula/src/tools/bsmtp.c | 111 ++++++++++++++++++++++++++++++++------- bacula/technotes-1.39 | 2 +- 4 files changed, 140 insertions(+), 65 deletions(-) diff --git a/bacula/ChangeLog b/bacula/ChangeLog index 7f103956a9..50b688fe10 100644 --- a/bacula/ChangeLog +++ b/bacula/ChangeLog @@ -2,7 +2,7 @@ General: Version 1.39.24 beta released: -02Sep06 +02Oct06 rbn Fix restore problem with c:\ prefix bug #676. rbn Verify that drive letter is valid on restore. rbn Fix re-open() options for tape. @@ -11,7 +11,7 @@ kes Eliminate the dvd specific mount routines using only the dev->mount/unmount. kes Make update_free_space a method of DEVICE and rename update_freespace. -01Sep06 +01Oct06 kes Require a messages command acl to be able to receive messages in a console. kes Add console, system, and scan job types in util.c. diff --git a/bacula/src/lib/bregex.c b/bacula/src/lib/bregex.c index cc98140304..5daefa04f3 100644 --- a/bacula/src/lib/bregex.c +++ b/bacula/src/lib/bregex.c @@ -488,51 +488,51 @@ void re_compile_initialize(void) plain_ops[(int)'\174'] = Ror; } else { quoted_ops[(int)'\174'] = Ror; - plain_ops[(int)'*'] = Rstar; - if (regexp_syntax & RE_BK_PLUS_QM) { - quoted_ops[(int)'+'] = Rplus; - quoted_ops[(int)'?'] = Roptional; - } else { - plain_ops[(int)'+'] = Rplus; - plain_ops[(int)'?'] = Roptional; - } - if (regexp_syntax & RE_NEWLINE_OR) { - plain_ops[(int)'\n'] = Ror; - } - plain_ops[(int)'\133'] = Ropenset; - plain_ops[(int)'\136'] = Rbol; - plain_ops[(int)'$'] = Reol; - plain_ops[(int)'.'] = Ranychar; - if (!(regexp_syntax & RE_NO_GNU_EXTENSIONS)) { - quoted_ops[(int)'w'] = Rwordchar; - quoted_ops[(int)'W'] = Rnotwordchar; - quoted_ops[(int)'<'] = Rwordbeg; - quoted_ops[(int)'>'] = Rwordend; - quoted_ops[(int)'b'] = Rwordbound; - quoted_ops[(int)'B'] = Rnotwordbound; - quoted_ops[(int)'`'] = Rbegbuf; - quoted_ops[(int)'\''] = Rendbuf; - } - if (regexp_syntax & RE_ANSI_HEX) { - quoted_ops[(int)'v'] = Rextended_memory; - } - for (a = 0; a < Rnum_ops; a++) { - precedences[a] = 4; - } - if (regexp_syntax & RE_TIGHT_VBAR) { - precedences[Ror] = 3; - precedences[Rbol] = 2; - precedences[Reol] = 2; - } else { - precedences[Ror] = 2; - precedences[Rbol] = 3; - precedences[Reol] = 3; - } - precedences[Rclosepar] = 1; - precedences[Rend] = 0; - regexp_context_indep_ops = (regexp_syntax & RE_CONTEXT_INDEP_OPS) != 0; - regexp_ansi_sequences = (regexp_syntax & RE_ANSI_HEX) != 0; } + plain_ops[(int)'*'] = Rstar; + if (regexp_syntax & RE_BK_PLUS_QM) { + quoted_ops[(int)'+'] = Rplus; + quoted_ops[(int)'?'] = Roptional; + } else { + plain_ops[(int)'+'] = Rplus; + plain_ops[(int)'?'] = Roptional; + } + if (regexp_syntax & RE_NEWLINE_OR) { + plain_ops[(int)'\n'] = Ror; + } + plain_ops[(int)'\133'] = Ropenset; + plain_ops[(int)'\136'] = Rbol; + plain_ops[(int)'$'] = Reol; + plain_ops[(int)'.'] = Ranychar; + if (!(regexp_syntax & RE_NO_GNU_EXTENSIONS)) { + quoted_ops[(int)'w'] = Rwordchar; + quoted_ops[(int)'W'] = Rnotwordchar; + quoted_ops[(int)'<'] = Rwordbeg; + quoted_ops[(int)'>'] = Rwordend; + quoted_ops[(int)'b'] = Rwordbound; + quoted_ops[(int)'B'] = Rnotwordbound; + quoted_ops[(int)'`'] = Rbegbuf; + quoted_ops[(int)'\''] = Rendbuf; + } + if (regexp_syntax & RE_ANSI_HEX) { + quoted_ops[(int)'v'] = Rextended_memory; + } + for (a = 0; a < Rnum_ops; a++) { + precedences[a] = 4; + } + if (regexp_syntax & RE_TIGHT_VBAR) { + precedences[Ror] = 3; + precedences[Rbol] = 2; + precedences[Reol] = 2; + } else { + precedences[Ror] = 2; + precedences[Rbol] = 3; + precedences[Reol] = 3; + } + precedences[Rclosepar] = 1; + precedences[Rend] = 0; + regexp_context_indep_ops = (regexp_syntax & RE_CONTEXT_INDEP_OPS) != 0; + regexp_ansi_sequences = (regexp_syntax & RE_ANSI_HEX) != 0; } int re_set_syntax(int syntax) { diff --git a/bacula/src/tools/bsmtp.c b/bacula/src/tools/bsmtp.c index 5c22b0c830..75cbdcdbfb 100644 --- a/bacula/src/tools/bsmtp.c +++ b/bacula/src/tools/bsmtp.c @@ -27,22 +27,12 @@ */ -#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 #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; } @@ -143,9 +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; @@ -196,9 +197,9 @@ int main (int argc, char *argv[]) break; case 'l': - Dmsg1(20, "maxlines=%s\n", optarg); - maxlines = (unsigned long) atol(optarg); - break; + Dmsg1(20, "maxlines=%s\n", optarg); + maxlines = (unsigned long) atol(optarg); + break; case '?': default: @@ -226,6 +227,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 @@ -246,11 +253,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); @@ -278,15 +296,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); + 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); @@ -299,6 +343,7 @@ hp: Pmsg1(0, _("Fatal fdopen error: ERR=%s\n"), strerror(errno)); exit(1); } +#endif /* * Send SMTP headers @@ -335,6 +380,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); @@ -342,6 +400,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]); @@ -358,8 +417,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); @@ -372,7 +447,7 @@ hp: while (fgets(buf, sizeof(buf), stdin)) { if (maxlines > 0 && ++lines > maxlines) { Dmsg1(20, "skip line because of maxlines limit: %lu\n", maxlines); - continue; + break; } buf[strlen(buf)-1] = 0; if (strcmp(buf, ".") == 0) { /* quote lone dots */ diff --git a/bacula/technotes-1.39 b/bacula/technotes-1.39 index a2d5ff71e2..b95a871daa 100644 --- a/bacula/technotes-1.39 +++ b/bacula/technotes-1.39 @@ -1,7 +1,7 @@ Technical notes on version 1.39 General: -02Sep06 +02Oct06 kes Apply dvd find volume patch from Richard Mortimer. kes Eliminate the dvd specific mount routines using only the dev->mount/unmount. -- 2.39.5