]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/wx-console/console_thread.cpp
Fix some trivial errors and implemented the restore of IRIX xattrs.
[bacula/bacula] / bacula / src / wx-console / console_thread.cpp
index 9663dcd6da08416bc08bb79e1f9ce276720e4afc..675c15c36a35835b5ceb08c69b4909828497af9b 100644 (file)
@@ -1,3 +1,30 @@
+/*
+   Bacula® - The Network Backup Solution
+
+   Copyright (C) 2004-2008 Free Software Foundation Europe e.V.
+
+   The main author of Bacula is Kern Sibbald, with contributions from
+   many others, a complete list can be found in the file AUTHORS.
+   This program is Free Software; you can redistribute it and/or
+   modify it under the terms of version three of the GNU Affero General Public
+   License as published by the Free Software Foundation and included
+   in the file LICENSE.
+
+   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 Affero General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+   Bacula® is a registered trademark of Kern Sibbald.
+   The licensor of Bacula is the Free Software Foundation Europe
+   (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
+   Switzerland, email:ftf@fsfeurope.org.
+*/
 /*
  *
  *    Interaction thread between director and the GUI
  *
  *    Version $Id$
  */
-/*
-   Copyright (C) 2004-2005 Kern Sibbald
 
-   This program is free software; you can redistribute it and/or
-   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.
+// 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
 
-   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 
-   the file LICENSE for additional details.
+/* _("...") macro returns a wxChar*, so if we need a char*, we need to convert it with:
+ * wxString(_("...")).mb_str(*wxConvCurrent) */
 
+/*  Windows debug builds set _DEBUG which is used by wxWidgets to select their
+ *  debug memory allocator.  Unfortunately it conflicts with Bacula's SmartAlloc.
+ * So we turn _DEBUG off since we aren't interested in things it enables.
  */
 
-// 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
+#undef _DEBUG
 
-/* _("...") macro returns a wxChar*, so if we need a char*, we need to convert it with:
- * wxString(_("...")).mb_str(*wxConvCurrent) */
+#include "bacula.h"
+#include "console_conf.h"
 
 #include "console_thread.h" // class's header file
 
 #include <wx/thread.h>
 #include <wx/file.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
 
 /* Imported functions */
 int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons);
+bool parse_wxcons_config(CONFIG *config, const char *cfgfile, LEX_ERROR_HANDLER *scan_error);
 
 bool console_thread::inited = false;
 bool console_thread::configloaded = false;
 wxString console_thread::working_dir = wxT(".");
 
 int numdir = 0;
+static CONFIG *config = NULL;
+static void scan_err(const char *file, int line, LEX *lc, const char *msg, ...);
+
 
 /*
  * Call-back for reading a passphrase for an encrypted PEM file
@@ -58,7 +82,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;
 
@@ -135,7 +159,7 @@ static int check_resources()
 
 
 void console_thread::SetWorkingDirectory(wxString w_dir) {
-   if ((w_dir.Last() == '/') || (w_dir.Last() == '\\')) {
+   if (IsPathSeparator(w_dir.Last())) {
       console_thread::working_dir = w_dir.Mid(0, w_dir.Length()-1);
    }
    else {
@@ -143,7 +167,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;
@@ -151,13 +176,14 @@ void console_thread::InitLib() {
    }
    
    init_stack_dump();
-   my_name_is(0, NULL, "wx-console");
+   my_name_is(0, NULL, "bwx-console");
    working_directory = (const char*) console_thread::working_dir.GetData();
    
    inited = true;
 }
 
-void console_thread::FreeLib() {
+void console_thread::FreeLib() 
+{
    if (inited) {
       if (WSACleanup() != 0) {
          csprint(_("Error while cleaning up windows sockets...\n"));
@@ -194,37 +220,40 @@ static void scan_err(const char *file, int line, LEX *lc, const char *msg, ...)
    errmsg << err; 
 }
 
-wxString console_thread::LoadConfig(wxString configfile) {
+wxString console_thread::LoadConfig(wxString configfile) 
+{
    if (!inited) {
       InitLib();
       if (!inited)
          return _("Error while initializing library.");
    }
    
-   free_config_resources();
+   if (config) {
+      config->free_resources();
+      free(config);
+   }          
    
-   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
       add_msg_dest(msgs, MD_STDOUT, i, NULL, NULL);
-#endif
 //    add_msg_dest(msgs, MD_SYSLOG, i, NULL, NULL);
       add_msg_dest(msgs, MD_CONSOLE, i, NULL, NULL);
    }
    
    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)) {
+   config = new_config_parser();
+   if (!parse_wxcons_config(config, configfile.mb_str(*wxConvCurrent), &scan_err)) {
       configloaded = false;
       term_msg();
       return errmsg;
    }
    
-   if (init_tls() != 0) {
-      Jmsg(NULL, M_ERROR_TERM, 0, wxString(_("TLS library initialization failed.\n")).mb_str(*wxConvCurrent));
+   if (init_crypto() != 0) {
+      Jmsg(NULL, M_ERROR_TERM, 0, wxString(_("Cryptographic library initialization failed.\n")).mb_str(*wxConvCurrent));
    }
 
    if (!check_resources()) {
@@ -232,7 +261,7 @@ wxString console_thread::LoadConfig(wxString configfile) {
    }
 
    term_msg();
-   wxRemoveFile(console_thread::working_dir + wxT("/wx-console.conmsg"));
+   wxRemoveFile(console_thread::working_dir + wxT("/bwx-console.conmsg"));
    init_msg(NULL, NULL);
    
    configloaded = true;
@@ -259,15 +288,14 @@ console_thread::~console_thread() {
  * Thread entry point
  */
 void* console_thread::Entry() {
-   /* It seems we must redefine the locale on each thread. */
+#ifndef HAVE_WIN32
+   /* It seems we must redefine the locale on each thread on wxGTK. 
+    * On Win32 it makes bwx-console crash. */
    wxLocale m_locale;
    m_locale.Init();
    m_locale.AddCatalog(wxT("bacula"));
-#ifndef ENABLE_NLS
-#undef LOCALEDIR
-#define LOCALEDIR "."
-#endif
    wxLocale::AddCatalogLookupPathPrefix(wxT(LOCALEDIR));
+#endif
 
    DIRRES* dir;
    if (!inited) {
@@ -275,9 +303,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;
    }
    
@@ -286,9 +314,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;
    }
    
@@ -312,9 +340,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;
@@ -347,7 +375,7 @@ void* console_thread::Entry() {
 
    memset(&jcr, 0, sizeof(jcr));
    
-   jcr.dequeuing = 1; /* TODO: catch messages */
+   jcr.dequeuing_msgs = 1; /* TODO: catch messages */
 
    LockRes();
    /* If cons==NULL, default console will be used */
@@ -397,7 +425,7 @@ void* console_thread::Entry() {
    }
 
 
-   UA_sock = bnet_connect(&jcr, 3, 3, wxString(_("Director daemon")).mb_str(*wxConvCurrent),
+   UA_sock = bnet_connect(&jcr, 3, 3, 0, wxString(_("Director daemon")).mb_str(*wxConvCurrent),
       dir->address, NULL, dir->DIRport, 0);
       
    if (UA_sock == NULL) {
@@ -405,9 +433,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;
    }
 
@@ -420,35 +448,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 bwx-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);
@@ -463,6 +510,8 @@ void* console_thread::Entry() {
          csprint(NULL, CS_END);
          break;            /* error or term */
       }
+      
+      do_not_forward_eod = 0;
    }
    
    csprint(NULL, CS_DISCONNECTED);
@@ -473,9 +522,9 @@ void* console_thread::Entry() {
 
    csprint(NULL, CS_TERMINATED);
 
-   #ifdef HAVE_WIN32
-      Exit();
-   #endif
+#ifdef HAVE_WIN32
+   Exit();
+#endif
    
    return NULL;
 }
@@ -483,9 +532,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 */