]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/wx-console/console_thread.cpp
Update the Microsoft Visual Studio build to match the MinGW32 build.
[bacula/bacula] / bacula / src / wx-console / console_thread.cpp
index 46cce5379319954568dc7b6beb893edb11d1fb60..b580b9ee0969d09455c4ac6711553e9d2c502b77 100644 (file)
@@ -7,7 +7,7 @@
  *    Version $Id$
  */
 /*
-   Copyright (C) 2004-2005 Kern Sibbald
+   Copyright (C) 2004-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
 
 // http://66.102.9.104/search?q=cache:Djc1mPF3hRoJ:cvs.sourceforge.net/viewcvs.py/audacity/audacity-src/src/AudioIO.cpp%3Frev%3D1.102+macos+x+wxthread&hl=fr
 
+/* _("...") macro returns a wxChar*, so if we need a char*, we need to convert it with:
+ * wxString(_("...")).mb_str(*wxConvCurrent) */
+
+#undef _DEBUG
+
+#include "bacula.h"
+#include "console_conf.h"
+
 #include "console_thread.h" // class's header file
 
 #include <wx/wxprec.h>
 
 #include <wx/thread.h>
 #include <wx/file.h>
-#include <bacula.h>
-#include <jcr.h>
-
-#include "console_conf.h"
 
 #include "csprint.h"
 
 #ifdef HAVE_WIN32
-#include <windows.h>
 char OK_msg[]   = "2000 OK\n";
 char TERM_msg[] = "2999 Terminate\n";
 #endif
@@ -57,7 +60,7 @@ int numdir = 0;
  */
 static int tls_pem_callback(char *buf, int size, const void *userdata)
 {
-#ifdef HAVE_TLS
+#if defined(HAVE_TLS) && !defined(HAVE_WIN32)
    const char *prompt = (const char *) userdata;
    char *passwd;
 
@@ -90,24 +93,21 @@ static int check_resources()
          if (have_tls) {
             director->tls_enable = true;
          } else {
-            Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
+            Jmsg(NULL, M_FATAL, 0, wxString(_("TLS required but not configured in Bacula.\n")).mb_str(*wxConvCurrent));
             xOK = false;
             continue;
          }
       }
 
       if ((!director->tls_ca_certfile && !director->tls_ca_certdir) && director->tls_enable) {
-         Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
-                             " or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in config file.\n"
-                             " At least one CA certificate store is required.\n"),
+         Jmsg(NULL, M_FATAL, 0, wxString(_("Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for Director \"%s\" in config file.\nAt least one CA certificate store is required.\n")).mb_str(*wxConvCurrent),
                              director->hdr.name);
          xOK = false;
       }
    }
    
    if (numdir == 0) {
-      Jmsg(NULL, M_FATAL, 0, _("No Director resource defined in config file.\n"
-                          "Without that I don't how to speak to the Director :-(\n"));
+      Jmsg(NULL, M_FATAL, 0, wxString(_("No Director resource defined in config file.\nWithout that I don't how to speak to the Director :-(\n")).mb_str(*wxConvCurrent));
       xOK = false;
    }
 
@@ -119,15 +119,14 @@ static int check_resources()
          if (have_tls) {
             cons->tls_enable = true;
          } else {
-            Jmsg(NULL, M_FATAL, 0, _("TLS required but not configured in Bacula.\n"));
+            Jmsg(NULL, M_FATAL, 0, wxString(_("TLS required but not configured in Bacula.\n")).mb_str(*wxConvCurrent));
             xOK = false;
             continue;
          }
       }
 
       if ((!cons->tls_ca_certfile && !cons->tls_ca_certdir) && cons->tls_enable) {
-         Jmsg(NULL, M_FATAL, 0, _("Neither \"TLS CA Certificate\""
-                             " or \"TLS CA Certificate Dir\" are defined for Console \"%s\" in config file.\n"),
+         Jmsg(NULL, M_FATAL, 0, wxString(_("Neither \"TLS CA Certificate\" or \"TLS CA Certificate Dir\" are defined for Console \"%s\" in config file.\n")).mb_str(*wxConvCurrent),
                              cons->hdr.name);
          xOK = false;
       }
@@ -146,7 +145,8 @@ void console_thread::SetWorkingDirectory(wxString w_dir) {
    }
 }
 
-void console_thread::InitLib() {
+void console_thread::InitLib() 
+{
    if (WSA_Init() != 0) {
       csprint(_("Error while initializing windows sockets...\n"));
       inited = false;
@@ -160,7 +160,8 @@ void console_thread::InitLib() {
    inited = true;
 }
 
-void console_thread::FreeLib() {
+void console_thread::FreeLib() 
+{
    if (inited) {
       if (WSACleanup() != 0) {
          csprint(_("Error while cleaning up windows sockets...\n"));
@@ -186,30 +187,31 @@ static void scan_err(const char *file, int line, LEX *lc, const char *msg, ...)
 
    if (lc->line_no > lc->begin_line_no) {
       bsnprintf(more, sizeof(more),
-                _("Problem probably begins at line %d.\n"), lc->begin_line_no);
+                wxString(_("Problem probably begins at line %d.\n")).mb_str(*wxConvCurrent), lc->begin_line_no);
    } else {
       more[0] = 0;
    }
 
-   err.Format(wxT(_("Config error: %s\n            : line %d, col %d of file %s\n%s\n%s")),
+   err.Format(_("Config error: %s\n            : line %d, col %d of file %s\n%s\n%s"),
       buf, lc->line_no, lc->col_no, lc->fname, lc->line, more);
      
    errmsg << err; 
 }
 
-wxString console_thread::LoadConfig(wxString configfile) {
+wxString console_thread::LoadConfig(wxString configfile) 
+{
    if (!inited) {
       InitLib();
       if (!inited)
-         return wxT(_("Error while initializing library."));
+         return _("Error while initializing library.");
    }
    
    free_config_resources();
    
-   MSGS* msgs = (MSGS *)malloc(sizeof(MSGS));
+   MSGS* msgs = (MSGS *)bmalloc(sizeof(MSGS));
    memset(msgs, 0, sizeof(MSGS));
    for (int i=1; i<=M_MAX; i++) {
-#ifndef WIN32
+#ifndef HAVE_WIN32
       add_msg_dest(msgs, MD_STDOUT, i, NULL, NULL);
 #endif
 //    add_msg_dest(msgs, MD_SYSLOG, i, NULL, NULL);
@@ -217,7 +219,7 @@ wxString console_thread::LoadConfig(wxString configfile) {
    }
    
    init_msg(NULL, msgs);
-   init_console_msg(console_thread::working_dir.mb_str(*wxConvCurrent));
+   //init_console_msg(console_thread::working_dir.mb_str(*wxConvCurrent));
 
    errmsg = wxT("");
    if (!parse_config(configfile.mb_str(*wxConvCurrent), &scan_err)) {
@@ -226,12 +228,12 @@ wxString console_thread::LoadConfig(wxString configfile) {
       return errmsg;
    }
    
-   if (init_tls() != 0) {
-      Jmsg(NULL, M_ERROR_TERM, 0, _("TLS library initialization failed.\n"));
+   if (init_crypto() != 0) {
+      Jmsg(NULL, M_ERROR_TERM, 0, wxString(_("Cryptographic library initialization failed.\n")).mb_str(*wxConvCurrent));
    }
 
    if (!check_resources()) {
-      Jmsg(NULL, M_ERROR_TERM, 0, _("Please correct configuration file.\n"));
+      Jmsg(NULL, M_ERROR_TERM, 0, wxString(_("Please correct configuration file.\n")).mb_str(*wxConvCurrent));
    }
 
    term_msg();
@@ -262,15 +264,24 @@ console_thread::~console_thread() {
  * Thread entry point
  */
 void* console_thread::Entry() {
+#ifndef HAVE_WIN32
+   /* It seems we must redefine the locale on each thread on wxGTK. 
+    * On Win32 it makes wx-console crash. */
+   wxLocale m_locale;
+   m_locale.Init();
+   m_locale.AddCatalog(wxT("bacula"));
+   wxLocale::AddCatalogLookupPathPrefix(wxT(LOCALEDIR));
+#endif
+
    DIRRES* dir;
    if (!inited) {
       csprint(_("Error : Library not initialized\n"));
       csprint(NULL, CS_END);
       csprint(NULL, CS_DISCONNECTED);
       csprint(NULL, CS_TERMINATED);
-      #ifdef HAVE_WIN32
-         Exit();
-      #endif
+#ifdef HAVE_WIN32
+      Exit();
+#endif
       return NULL;
    }
    
@@ -279,9 +290,9 @@ void* console_thread::Entry() {
       csprint(NULL, CS_END);
       csprint(NULL, CS_DISCONNECTED);
       csprint(NULL, CS_TERMINATED);
-      #ifdef HAVE_WIN32
-         Exit();
-      #endif
+#ifdef HAVE_WIN32
+      Exit();
+#endif
       return NULL;
    }
    
@@ -305,9 +316,9 @@ void* console_thread::Entry() {
       csprint(NULL, CS_END);
       csprint(NULL, CS_DISCONNECTED);
       csprint(NULL, CS_TERMINATED);
-      #ifdef HAVE_WIN32
-         Exit();
-      #endif
+#ifdef HAVE_WIN32
+      Exit();
+#endif
       return NULL;
    } else if (count == 1) {
       directorchoosen = 1;
@@ -322,7 +333,7 @@ void* console_thread::Entry() {
                csprint(wxString(wxT("   ")) <<  (i+1) << wxT(": ") << wxString(res[i]->hdr.name,*wxConvCurrent) << wxT("\n"));
             }
          }
-         csprint(wxString::Format(wxT(_("Please choose a director (1-%s): ")), count), CS_DATA);
+         csprint(wxString::Format(_("Please choose a director (1-%d): "), count), CS_DATA);
          csprint(NULL, CS_PROMPT);
          choosingdirector = true;
          directorchoosen = -1;
@@ -351,7 +362,7 @@ void* console_thread::Entry() {
    /* Initialize Console TLS context */
    if (cons && (cons->tls_enable || cons->tls_require)) {
       /* Generate passphrase prompt */
-      bsnprintf(buf, sizeof(buf), _("Passphrase for Console \"%s\" TLS private key: "), cons->hdr.name);
+      bsnprintf(buf, sizeof(buf), wxString(_("Passphrase for Console \"%s\" TLS private key: ")).mb_str(*wxConvCurrent), cons->hdr.name);
 
       /* Initialize TLS context:
        * Args: CA certfile, CA certdir, Certfile, Keyfile,
@@ -361,7 +372,7 @@ void* console_thread::Entry() {
          cons->tls_keyfile, tls_pem_callback, &buf, NULL, true);
 
       if (!cons->tls_ctx) {
-         bsnprintf(buf, sizeof(buf), _("Failed to initialize TLS context for Console \"%s\".\n"),
+         bsnprintf(buf, sizeof(buf), wxString(_("Failed to initialize TLS context for Console \"%s\".\n")).mb_str(*wxConvCurrent),
             dir->hdr.name);
          csprint(buf);
          return NULL;
@@ -372,7 +383,7 @@ void* console_thread::Entry() {
    /* Initialize Director TLS context */
    if (dir->tls_enable || dir->tls_require) {
       /* Generate passphrase prompt */
-      bsnprintf(buf, sizeof(buf), _("Passphrase for Director \"%s\" TLS private key: "), dir->hdr.name);
+      bsnprintf(buf, sizeof(buf), wxString(_("Passphrase for Director \"%s\" TLS private key: ")).mb_str(*wxConvCurrent), dir->hdr.name);
 
       /* Initialize TLS context:
        * Args: CA certfile, CA certdir, Certfile, Keyfile,
@@ -382,7 +393,7 @@ void* console_thread::Entry() {
          dir->tls_keyfile, tls_pem_callback, &buf, NULL, true);
 
       if (!dir->tls_ctx) {
-         bsnprintf(buf, sizeof(buf), _("Failed to initialize TLS context for Director \"%s\".\n"),
+         bsnprintf(buf, sizeof(buf), wxString(_("Failed to initialize TLS context for Director \"%s\".\n")).mb_str(*wxConvCurrent),
             dir->hdr.name);
          csprint(buf);
          return NULL;
@@ -390,7 +401,7 @@ void* console_thread::Entry() {
    }
 
 
-   UA_sock = bnet_connect(&jcr, 3, 3, _("Director daemon"),
+   UA_sock = bnet_connect(&jcr, 3, 3, wxString(_("Director daemon")).mb_str(*wxConvCurrent),
       dir->address, NULL, dir->DIRport, 0);
       
    if (UA_sock == NULL) {
@@ -398,9 +409,9 @@ void* console_thread::Entry() {
       csprint(NULL, CS_END);
       csprint(NULL, CS_DISCONNECTED);
       csprint(NULL, CS_TERMINATED);
-      #ifdef HAVE_WIN32
-         Exit();
-      #endif
+#ifdef HAVE_WIN32
+      Exit();
+#endif
       return NULL;
    }
 
@@ -413,35 +424,54 @@ void* console_thread::Entry() {
       csprint(NULL, CS_END);
       csprint(NULL, CS_DISCONNECTED);
       csprint(NULL, CS_TERMINATED);
-      #ifdef HAVE_WIN32
-         Exit();
-      #endif
+#ifdef HAVE_WIN32
+      Exit();
+#endif
       return NULL;
    }
    
    csprint(NULL, CS_CONNECTED);
    
+   Write("autodisplay on\n");
    Write(".messages\n");
 
    int stat;
 
+   int last_is_eod = 0; /* Last packet received is BNET_EOD */
+   int do_not_forward_eod = 0; /* Last packet received/sent is .messages, so don't forward EOD. (so wx-console don't show the prompt again) */
+
    /* main loop */
    while(!TestDestroy()) {   /* Tests if thread has been ended */
+      stat = bnet_wait_data(UA_sock, 10);
+      if (stat == 0) {
+         if (last_is_eod) {
+            Write(".messages\n");
+            do_not_forward_eod = 1;
+         }
+         continue;
+      }
+      
+      last_is_eod = 0;
       if ((stat = bnet_recv(UA_sock)) >= 0) {
+         if (do_not_forward_eod) { /* .messages got data: remove the prompt */
+            csprint(NULL, CS_REMOVEPROMPT);
+         }
          csprint(UA_sock->msg);
       }
       else if (stat == BNET_SIGNAL) {
          if (UA_sock->msglen == BNET_PROMPT) {
             csprint(NULL, CS_PROMPT);
-         }
-         else if (UA_sock->msglen == BNET_EOD) {
-            csprint(NULL, CS_END);
-         }
-         else if (UA_sock->msglen == BNET_HEARTBEAT) {
+         } else if (UA_sock->msglen == BNET_EOD) {
+            last_is_eod = 1;
+            if (!do_not_forward_eod)
+               csprint(NULL, CS_END);
+         else if (UA_sock->msglen == BNET_HEARTBEAT) {
             bnet_sig(UA_sock, BNET_HB_RESPONSE);
             csprint(_("<< Heartbeat signal received, answered. >>\n"), CS_DEBUG);
-         }
-         else {
+         } else if (UA_sock->msglen == BNET_START_SELECT ||
+                    UA_sock->msglen == BNET_END_SELECT) {
+           /* Ignore start/end selections for now */
+         } else {
             csprint(_("<< Unexpected signal received : "), CS_DEBUG);
             csprint(bnet_sig_to_ascii(UA_sock), CS_DEBUG);
             csprint(">>\n", CS_DEBUG);
@@ -456,6 +486,8 @@ void* console_thread::Entry() {
          csprint(NULL, CS_END);
          break;            /* error or term */
       }
+      
+      do_not_forward_eod = 0;
    }
    
    csprint(NULL, CS_DISCONNECTED);
@@ -466,9 +498,9 @@ void* console_thread::Entry() {
 
    csprint(NULL, CS_TERMINATED);
 
-   #ifdef HAVE_WIN32
-      Exit();
-   #endif
+#ifdef HAVE_WIN32
+   Exit();
+#endif
    
    return NULL;
 }
@@ -476,9 +508,9 @@ void* console_thread::Entry() {
 void console_thread::Write(const char* str) 
 {
    if (UA_sock) {
-       UA_sock->msglen = strlen(str);
-       pm_strcpy(&UA_sock->msg, str);
-       bnet_send(UA_sock);
+      UA_sock->msglen = (int32_t)strlen(str);
+      pm_strcpy(&UA_sock->msg, str);
+      bnet_send(UA_sock);
    } else if (choosingdirector) {
 //      wxString number = str;
 //      number.RemoveLast(); /* Removes \n */