]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/wx-console/console_thread.cpp
wx-console: Improve error handling when reading configuration file.
[bacula/bacula] / bacula / src / wx-console / console_thread.cpp
index 8f0d665f3a2dfdffc528dd825f45dd494a15dd77..0eed96f451046da1ab2093e8775f6e94d3f91ee4 100644 (file)
@@ -4,6 +4,7 @@
  *
  *    Nicolas Boichat, April 2004
  *
+ *    Version $Id$
  */
 /*
    Copyright (C) 2004 Kern Sibbald and John Walker
@@ -50,6 +51,16 @@ int authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons);
 
 bool console_thread::inited = false;
 bool console_thread::configloaded = false;
+wxString console_thread::working_dir = ".";
+
+void console_thread::SetWorkingDirectory(wxString w_dir) {
+   if ((w_dir.Last() == '/') || (w_dir.Last() == '\\')) {
+      console_thread::working_dir = w_dir.Mid(0, w_dir.Length()-1);
+   }
+   else {
+      console_thread::working_dir = w_dir;
+   }
+}
 
 void console_thread::InitLib() {
    if (WSA_Init() != 0) {
@@ -61,6 +72,7 @@ void console_thread::InitLib() {
    init_stack_dump();
    my_name_is(0, NULL, "wx-console");
    //textdomain("bacula-console");
+   working_directory = console_thread::working_dir;
    
    inited = true;
 }
@@ -73,6 +85,34 @@ void console_thread::FreeLib() {
    }
 }
 
+wxString errmsg;
+
+/*
+ * Format a scanner error message
+ */
+static void scan_err(const char *file, int line, LEX *lc, const char *msg, ...)
+{
+   va_list arg_ptr;
+   char buf[MAXSTRING];
+   char more[MAXSTRING];
+   char err[MAXSTRING];
+   
+   va_start(arg_ptr, msg);
+   bvsnprintf(buf, sizeof(buf), msg, arg_ptr);
+   va_end(arg_ptr);
+
+   if (lc->line_no > lc->begin_line_no) {
+      bsnprintf(more, sizeof(more),
+                _("Problem probably begins at line %d.\n"), lc->begin_line_no);
+   } else {
+      more[0] = 0;
+   }
+   bsnprintf(err, sizeof(err), _("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) {
    if (!inited) {
       InitLib();
@@ -80,6 +120,8 @@ wxString console_thread::LoadConfig(wxString configfile) {
          return "Error while initializing library.";
    }
    
+   free_config_resources();
+   
    MSGS* msgs = (MSGS *)malloc(sizeof(MSGS));
    memset(msgs, 0, sizeof(MSGS));
    for (int i=1; i<=M_MAX; i++) {
@@ -91,31 +133,17 @@ wxString console_thread::LoadConfig(wxString configfile) {
    }
    
    init_msg(NULL, msgs);
-   init_console_msg(".");
+   init_console_msg(console_thread::working_dir);
 
-   /* TODO (#4#): Allow the user to choose his config file. */
-   if (!parse_config(configfile.c_str(), 0)) {
+   errmsg = "";
+   if (!parse_config(configfile.c_str(), &scan_err)) {
       configloaded = false;
-      wxFile file("./wx-console.conmsg");
-      if (!file.IsOpened())
-         return "Unable to retrieve error message.";
-      wxString err = "";
-      wxChar buffer[513];
-      off_t len;
-      while ((len = file.Read(buffer, 512)) > -1) {
-         buffer[len] = (wxChar)0;
-         err += buffer;
-         if (file.Eof())
-            break;
-      }
-      file.Close();
       term_msg();
-      wxRemoveFile("./wx-console.conmsg");
-      return err;
+      return errmsg;
    }
    
    term_msg();
-   wxRemoveFile("./wx-console.conmsg");
+   wxRemoveFile(console_thread::working_dir + "/wx-console.conmsg");
    init_msg(NULL, NULL);
    
    configloaded = true;
@@ -126,6 +154,7 @@ wxString console_thread::LoadConfig(wxString configfile) {
 // class constructor
 console_thread::console_thread() {
    UA_sock = NULL;
+   choosingdirector = false;
 }
 
 // class destructor
@@ -165,15 +194,66 @@ void* console_thread::Entry() {
    
    csprint("Connecting...\n");
   
+   int count = 0;
+   DIRRES* res[16]; /* Maximum 16 directors */
+   
    LockRes();
-   DIRRES *dir = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
+   DIRRES* dir;
+   foreach_res(dir, R_DIRECTOR) {
+      res[count] = dir;
+      count++;
+      if (count == 16) {
+         break;
+      }
+   }
    UnlockRes();
+   
+   if (count == 0) {
+      csprint("Error : No director defined in config file.\n");
+      csprint(NULL, CS_END);
+      csprint(NULL, CS_DISCONNECTED);
+      csprint(NULL, CS_TERMINATED);
+      #ifdef HAVE_WIN32
+         Exit();
+      #endif
+      return NULL;
+   }
+   else if (count == 1) {
+      directorchoosen = 1;
+   }
+   else {
+      while (true) {
+         csprint("Multiple directors found in your config file.\n");
+         for (int i = 0; i < count; i++) {
+            if (i < 9) {
+               csprint(wxString("    ") << (i+1) << ": " << res[i]->hdr.name << "\n");
+            }
+            else {
+               csprint(wxString("   ") <<  (i+1) << ": " << res[i]->hdr.name << "\n");
+            }
+         }
+         csprint(wxString("Please choose a director (1-") << count << ") : ");
+         csprint(NULL, CS_PROMPT);
+         choosingdirector = true;
+         directorchoosen = -1;
+         while(directorchoosen == -1) {
+            bmicrosleep(0, 2000);
+            Yield();
+         }      
+         choosingdirector = false;
+         if (directorchoosen != 0) {
+            break;
+         }
+      }
+   }
 
    memset(&jcr, 0, sizeof(jcr));
    
    jcr.dequeuing = 1; /* TODO: catch messages */
 
-   UA_sock = bnet_connect(&jcr, 3, 3, "Director daemon", dir->address, NULL, dir->DIRport, 0);
+   UA_sock = bnet_connect(&jcr, 3, 3, "Director daemon",
+      res[directorchoosen-1]->address, NULL, res[directorchoosen-1]->DIRport, 0);
+      
    if (UA_sock == NULL) {
       csprint("Failed to connect to the director\n");
       csprint(NULL, CS_END);
@@ -192,7 +272,7 @@ void* console_thread::Entry() {
    /* If cons==NULL, default console will be used */
    CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL);
    UnlockRes();
-   if (!authenticate_director(&jcr, dir, cons)) {
+   if (!authenticate_director(&jcr, res[directorchoosen-1], cons)) {
       csprint("ERR=");
       csprint(UA_sock->msg);
       csprint(NULL, CS_END);
@@ -206,7 +286,7 @@ void* console_thread::Entry() {
    
    csprint(NULL, CS_CONNECTED);
    
-   Write("messages\n");
+   Write(".messages\n");
 
    int stat;
 
@@ -264,6 +344,17 @@ void console_thread::Write(const char* str) {
        pm_strcpy(&UA_sock->msg, str);
        bnet_send(UA_sock);
    }
+   else if (choosingdirector) {
+      wxString number = str;
+      number.RemoveLast(); /* Removes \n */
+      long val;
+      if (number.ToLong(&val)) {
+         directorchoosen = (int)val;
+      }
+      else {
+         directorchoosen = 0;
+      }
+   }
 }
 
 void console_thread::Delete() {
@@ -272,8 +363,8 @@ void console_thread::Delete() {
       bnet_sig(UA_sock, BNET_TERMINATE); /* send EOF */
       bnet_close(UA_sock);
       UA_sock = NULL;
-      csprint(NULL, CS_END);
+      /*csprint(NULL, CS_END);
       csprint(NULL, CS_DISCONNECTED);
-      csprint(NULL, CS_TERMINATED);
+      csprint(NULL, CS_TERMINATED);*/
    }
 }