From 3cfe3c8b357d584ef876387026ff283f4f80ea06 Mon Sep 17 00:00:00 2001 From: Dirk H Bartley Date: Sat, 21 Mar 2009 00:21:51 +0000 Subject: [PATCH] This is the rather large commit of adding the feature to create multiple connections. I had been struggling with a bug where if a message was pending on startup, the lists would never get populating. It was inconsistent and I think I may have that one. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@8566 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/qt-console/bat.h | 1 - bacula/src/qt-console/bat.pro.in | 2 +- bacula/src/qt-console/bcomm/dircomm.cpp | 359 +++----- bacula/src/qt-console/bcomm/dircomm.h | 65 +- bacula/src/qt-console/bcomm/dircomm_auth.cpp | 25 +- bacula/src/qt-console/clients/clients.cpp | 2 - bacula/src/qt-console/console/console.cpp | 766 ++++++------------ bacula/src/qt-console/console/console.h | 84 +- bacula/src/qt-console/fileset/fileset.cpp | 2 - bacula/src/qt-console/joblist/joblist.cpp | 3 - bacula/src/qt-console/joblog/joblog.cpp | 3 - bacula/src/qt-console/jobs/jobs.cpp | 2 - bacula/src/qt-console/label/label.cpp | 8 +- bacula/src/qt-console/label/label.h | 1 + bacula/src/qt-console/main.cpp | 22 - bacula/src/qt-console/mainwin.cpp | 7 +- bacula/src/qt-console/mainwin.h | 1 + bacula/src/qt-console/mediaedit/mediaedit.cpp | 3 - bacula/src/qt-console/medialist/medialist.cpp | 3 - bacula/src/qt-console/mount/mount.cpp | 8 +- bacula/src/qt-console/mount/mount.h | 1 + bacula/src/qt-console/pages.cpp | 10 +- bacula/src/qt-console/prefs.ui | 103 +-- bacula/src/qt-console/relabel/relabel.cpp | 8 +- bacula/src/qt-console/relabel/relabel.h | 1 + bacula/src/qt-console/restore/prerestore.cpp | 11 +- bacula/src/qt-console/restore/restore.cpp | 74 +- bacula/src/qt-console/restore/restore.h | 4 +- bacula/src/qt-console/restore/restoretree.cpp | 2 - bacula/src/qt-console/run/estimate.cpp | 8 +- bacula/src/qt-console/run/prune.cpp | 6 +- bacula/src/qt-console/run/run.cpp | 8 +- bacula/src/qt-console/run/run.h | 4 + bacula/src/qt-console/run/runcmd.cpp | 18 +- bacula/src/qt-console/select/select.cpp | 27 +- bacula/src/qt-console/select/select.h | 4 +- bacula/src/qt-console/status/clientstat.cpp | 5 +- bacula/src/qt-console/status/dirstat.cpp | 5 +- bacula/src/qt-console/status/storstat.cpp | 5 +- bacula/src/qt-console/storage/storage.cpp | 3 - 40 files changed, 619 insertions(+), 1055 deletions(-) diff --git a/bacula/src/qt-console/bat.h b/bacula/src/qt-console/bat.h index 3a8182be21..d9b5e3ae95 100644 --- a/bacula/src/qt-console/bat.h +++ b/bacula/src/qt-console/bat.h @@ -49,7 +49,6 @@ #include "jcr.h" #include "console.h" - extern MainWin *mainWin; extern QApplication *app; diff --git a/bacula/src/qt-console/bat.pro.in b/bacula/src/qt-console/bat.pro.in index 00c80d58b4..2a6afb7b5b 100644 --- a/bacula/src/qt-console/bat.pro.in +++ b/bacula/src/qt-console/bat.pro.in @@ -67,7 +67,7 @@ SOURCES += bcomm/dircomm.cpp bcomm/dircomm_auth.cpp # Console HEADERS += console/console.h -SOURCES += console/authenticate.cpp console/console.cpp +SOURCES += console/console.cpp # Restore HEADERS += restore/restore.h diff --git a/bacula/src/qt-console/bcomm/dircomm.cpp b/bacula/src/qt-console/bcomm/dircomm.cpp index 422d0cf4a6..c08ca6b115 100644 --- a/bacula/src/qt-console/bcomm/dircomm.cpp +++ b/bacula/src/qt-console/bcomm/dircomm.cpp @@ -1,7 +1,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2007-2007 Free Software Foundation Europe e.V. + Copyright (C) 2007-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. @@ -28,9 +28,9 @@ /* * Version $Id$ * - * Bacula Communications class that is at a higher level than BSOCK + * Console Class * - * Kern Sibbald, May MMVII + * Kern Sibbald, January MMVII * */ @@ -39,58 +39,33 @@ #include "restore.h" #include "select.h" #include "run/run.h" -#include "dircomm.h" static int tls_pem_callback(char *buf, int size, const void *userdata); - -DirComm::DirComm(Console *console) +DirComm::DirComm(Console *parent, int conn): +m_notifier(NULL), +m_api_set(false) { - m_console = console; + m_console = parent; m_sock = NULL; m_at_prompt = false; m_at_main_prompt = false; - m_timer = NULL; + m_conn = conn; } DirComm::~DirComm() { - if (m_timer) { - stopTimer(); - } -} - -void DirComm::startTimer() -{ - m_timer = new QTimer(m_console); - QWidget::connect(m_timer, SIGNAL(timeout()), this, SLOT(poll_messages())); - m_timer->start(mainWin->m_checkMessagesInterval*1000); -} - -void DirComm::stopTimer() -{ - if (m_timer) { - QWidget::disconnect(m_timer, SIGNAL(timeout()), this, SLOT(poll_messages())); - m_timer->stop(); - delete m_timer; - m_timer = NULL; - } -} - -void DirComm::poll_messages() -{ - m_messages_pending = true; - if ((m_at_main_prompt) && (mainWin->m_checkMessages)){ - write(".messages"); - displayToPrompt(); - } } /* Terminate any open socket */ void DirComm::terminate() { if (m_sock) { - stopTimer(); + if (m_notifier) { + m_notifier->setEnabled(false); + delete m_notifier; + m_notifier = NULL; + } m_sock->close(); m_sock = NULL; } @@ -99,30 +74,37 @@ void DirComm::terminate() /* * Connect to Director. */ -void DirComm::connect_dir(DIRRES *dir, CONRES *cons) +bool DirComm::connect_dir() { - JCR jcr; + JCR *jcr = new JCR; utime_t heart_beat; char buf[1024]; + CONRES *cons; + + buf[0] = 0; - m_dir = dir; - if (!m_dir) { - mainWin->set_status( tr("No Director found.") ); - return; - } if (m_sock) { - mainWin->set_status( tr("Already connected.") ); - return; + mainWin->set_status( tr("Already connected.")); + m_console->display_textf(_("Already connected\"%s\".\n"), + m_console->m_dir->name()); + if (mainWin->m_connDebug) + Pmsg1(000, "DirComm %i BAILING already connected\n", m_conn); + goto bail_out; } - memset(&jcr, 0, sizeof(jcr)); + memset(jcr, 0, sizeof(JCR)); - mainWin->set_statusf(_("Connecting to Director %s:%d"), m_dir->address, m_dir->DIRport); - m_console->display_textf(_("Connecting to Director %s:%d\n\n"), m_dir->address, m_dir->DIRport); + mainWin->set_statusf(_("Connecting to Director %s:%d"), m_console->m_dir->address, m_console->m_dir->DIRport); + m_console->display_textf(_("Connecting to Director %s:%d\n\n"), m_console->m_dir->address, m_console->m_dir->DIRport); /* Give GUI a chance */ app->processEvents(); + LockRes(); + /* If cons==NULL, default console will be used */ + cons = (CONRES *)GetNextRes(R_CONSOLE, NULL); + UnlockRes(); + /* Initialize Console TLS context once */ if (cons && !cons->tls_ctx && (cons->tls_enable || cons->tls_require)) { /* Generate passphrase prompt */ @@ -139,34 +121,38 @@ void DirComm::connect_dir(DIRRES *dir, CONRES *cons) if (!cons->tls_ctx) { m_console->display_textf(_("Failed to initialize TLS context for Console \"%s\".\n"), - m_dir->name()); - return; + m_console->m_dir->name()); + if (mainWin->m_connDebug) + Pmsg1(000, "DirComm %i BAILING Failed to initialize TLS context for Console \n", m_conn); + goto bail_out; } } /* Initialize Director TLS context once */ - if (!m_dir->tls_ctx && (m_dir->tls_enable || m_dir->tls_require)) { + if (!m_console->m_dir->tls_ctx && (m_console->m_dir->tls_enable || m_console->m_dir->tls_require)) { /* Generate passphrase prompt */ bsnprintf(buf, sizeof(buf), "Passphrase for Director \"%s\" TLS private key: ", - m_dir->name()); + m_console->m_dir->name()); /* Initialize TLS context: * Args: CA certfile, CA certdir, Certfile, Keyfile, * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ - m_dir->tls_ctx = new_tls_context(m_dir->tls_ca_certfile, - m_dir->tls_ca_certdir, m_dir->tls_certfile, - m_dir->tls_keyfile, tls_pem_callback, &buf, NULL, true); + m_console->m_dir->tls_ctx = new_tls_context(m_console->m_dir->tls_ca_certfile, + m_console->m_dir->tls_ca_certdir, m_console->m_dir->tls_certfile, + m_console->m_dir->tls_keyfile, tls_pem_callback, &buf, NULL, true); - if (!m_dir->tls_ctx) { + if (!m_console->m_dir->tls_ctx) { m_console->display_textf(_("Failed to initialize TLS context for Director \"%s\".\n"), - m_dir->name()); + m_console->m_dir->name()); mainWin->set_status("Connection failed"); - return; + if (mainWin->m_connDebug) + Pmsg1(000, "DirComm %i BAILING Failed to initialize TLS context for Director \n", m_conn); + goto bail_out; } } - if (m_dir->heartbeat_interval) { - heart_beat = m_dir->heartbeat_interval; + if (m_console->m_dir->heartbeat_interval) { + heart_beat = m_console->m_dir->heartbeat_interval; } else if (cons) { heart_beat = cons->heartbeat_interval; } else { @@ -174,25 +160,30 @@ void DirComm::connect_dir(DIRRES *dir, CONRES *cons) } m_sock = bnet_connect(NULL, 5, 15, heart_beat, - _("Director daemon"), m_dir->address, - NULL, m_dir->DIRport, 0); + _("Director daemon"), m_console->m_dir->address, + NULL, m_console->m_dir->DIRport, 0); if (m_sock == NULL) { - mainWin->set_status( tr("Connection failed") ); - return; + mainWin->set_status("Connection failed"); + if (mainWin->m_connDebug) + Pmsg1(000, "DirComm %i BAILING Connection failed\n", m_conn); + goto bail_out; } else { /* Update page selector to green to indicate that Console is connected */ mainWin->actionConnect->setIcon(QIcon(":images/connected.png")); QBrush greenBrush(Qt::green); - QTreeWidgetItem *item = mainWin->getFromHash(this); + QTreeWidgetItem *item = mainWin->getFromHash(m_console); item->setForeground(0, greenBrush); } - jcr.dir_bsock = m_sock; + jcr->dir_bsock = m_sock; - if (!authenticate_director(&jcr, m_dir, cons, buf, sizeof(buf))) { + if (!authenticate_director(jcr, m_console->m_dir, cons, buf, sizeof(buf))) { m_console->display_text(buf); - return; + if (mainWin->m_connDebug) + Pmsg1(000, "DirComm %i BAILING Connection failed\n", m_conn); + goto bail_out; } + if (buf[0]) { m_console->display_text(buf); } @@ -202,72 +193,29 @@ void DirComm::connect_dir(DIRRES *dir, CONRES *cons) mainWin->set_status(_("Initializing ...")); +#ifndef HAVE_WIN32 /* Set up input notifier */ m_notifier = new QSocketNotifier(m_sock->m_fd, QSocketNotifier::Read, 0); QObject::connect(m_notifier, SIGNAL(activated(int)), this, SLOT(read_dir(int))); +#endif - mainWin->set_status(_("Connected")); - startTimer(); /* start message timer */ - return; -} - -bool DirComm::dir_cmd(QString &cmd, QStringList &results) -{ - return dir_cmd(cmd.toUtf8().data(), results); -} - -/* - * Send a command to the Director, and return the - * results in a QStringList. - */ -bool DirComm::dir_cmd(const char *cmd, QStringList &results) -{ - int stat; - - notify(false); - write(cmd); - while ((stat = read()) > 0) { - if (mainWin->m_displayAll) m_console->display_text(msg()); - strip_trailing_junk(msg()); - results << msg(); - } - notify(true); - discardToPrompt(); - return true; /* ***FIXME*** return any command error */ -} + write(".api 1"); + m_api_set = true; + m_console->displayToPrompt(m_conn); -bool DirComm::sql_cmd(QString &query, QStringList &results) -{ - return sql_cmd(query.toUtf8().data(), results); -} + m_console->beginNewCommand(m_conn); -/* - * Send an sql query to the Director, and return the - * results in a QStringList. - */ -bool DirComm::sql_cmd(const char *query, QStringList &results) -{ - int stat; - POOL_MEM cmd(PM_MESSAGE); + mainWin->set_status(_("Connected")); - if (!is_connectedGui()) { - return false; - } + if (mainWin->m_connDebug) + Pmsg1(000, "Returning TRUE from DirComm->connect_dir : %i\n", m_conn); + return true; - notify(false); - - pm_strcpy(cmd, ".sql query=\""); - pm_strcat(cmd, query); - pm_strcat(cmd, "\""); - write(cmd.c_str()); - while ((stat = read()) > 0) { - if (mainWin->m_displayAll) m_console->display_text(msg()); - strip_trailing_junk(msg()); - results << msg(); - } - notify(true); - discardToPrompt(); - return true; /* ***FIXME*** return any command error */ +bail_out: + if (mainWin->m_connDebug) + Pmsg1(000, "Returning FALSE from DirComm->connect_dir : %i\n", m_conn); + delete jcr; + return false; } /* @@ -281,24 +229,6 @@ char *DirComm::msg() return NULL; } -/* Send a command to the Director */ -void DirComm::write_dir(const char *msg) -{ - if (m_sock) { - mainWin->set_status(_("Processing command ...")); - QApplication::setOverrideCursor(Qt::WaitCursor); - write(msg); - } else { - mainWin->set_status( tr(" Director not connected. Click on connect button.") ); - mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png")); - QBrush redBrush(Qt::red); - QTreeWidgetItem *item = mainWin->getFromHash(this); - item->setForeground(0, redBrush); - m_at_prompt = false; - m_at_main_prompt = false; - } -} - int DirComm::write(const QString msg) { return write(msg.toUtf8().data()); @@ -314,58 +244,21 @@ int DirComm::write(const char *msg) m_at_main_prompt = false; if (mainWin->m_commDebug) Pmsg1(000, "send: %s\n", msg); return m_sock->send(); - } -/* - * Get to main command prompt -- i.e. abort any suDirCommand - */ -void DirComm::beginNewCommand() +int DirComm::sock_read() { - for (int i=0; i < 3; i++) { - write(".\n"); - while (read() > 0) { - if (mainWin->m_displayAll) m_console->display_text(msg()); - } - if (m_at_main_prompt) { - break; - } - } - m_console->display_text("\n"); -} - -void DirComm::displayToPrompt() -{ - int stat = 0; - QString buf; - if (mainWin->m_commDebug) Pmsg0(000, "DisplaytoPrompt\n"); - while (!m_at_prompt) { - if ((stat=read()) > 0) { - buf += msg(); - if (buf.size() >= 8196 || m_messages_pending) { - m_console->display_text(buf); - buf.clear(); - m_messages_pending = false; - } - } - } - m_console->display_text(buf); - if (mainWin->m_commDebug) Pmsg1(000, "endDisplaytoPrompt=%d\n", stat); -} - -void DirComm::discardToPrompt() -{ - int stat = 0; - if (mainWin->m_commDebug) Pmsg0(000, "discardToPrompt\n"); - while (!m_at_prompt) { - if ((stat=read()) > 0) { - if (mainWin->m_displayAll) m_console->display_text(msg()); - } - } - if (mainWin->m_commDebug) Pmsg1(000, "endDisplayToPrompt=%d\n", stat); + int stat; +#ifdef HAVE_WIN32 + bool wasEnabled = notify(false); + stat = m_sock->recv(); + notify(wasEnabled); +#else + stat = m_sock->recv(); +#endif + return stat; } - /* * Blocking read from director */ @@ -374,18 +267,18 @@ int DirComm::read() int stat = 0; while (m_sock) { for (;;) { - stat = bnet_wait_data_intr(m_sock, 1); + stat = m_sock->wait_data_intr(0, 50000); if (stat > 0) { break; } app->processEvents(); - if (m_api_set && m_messages_pending) { - write_dir(".messages"); - m_messages_pending = false; + if (m_api_set && m_console->is_messagesPending() && is_notify_enabled() && m_console->hasFocus()) { + m_console->write_dir(m_conn, ".messages"); + m_console->messagesPending(false); } } m_sock->msg[0] = 0; - stat = m_sock->recv(); + stat = sock_read(); if (stat >= 0) { if (mainWin->m_commDebug) Pmsg1(000, "got: %s\n", m_sock->msg); if (m_at_prompt) { @@ -396,13 +289,13 @@ int DirComm::read() } switch (m_sock->msglen) { case BNET_MSGS_PENDING : - if (m_notifier->isEnabled()) { + if (is_notify_enabled() && m_console->hasFocus()) { if (mainWin->m_commDebug) Pmsg0(000, "MSGS PENDING\n"); - write_dir(".messages"); - displayToPrompt(); - m_messages_pending = false; + m_console->write_dir(m_conn, ".messages"); + m_console->displayToPrompt(m_conn); + m_console->messagesPending(false); } - m_messages_pending = true; + m_console->messagesPending(true); continue; case BNET_CMD_OK: if (mainWin->m_commDebug) Pmsg0(000, "CMD OK\n"); @@ -450,43 +343,52 @@ int DirComm::read() break; case BNET_YESNO: if (mainWin->m_commDebug) Pmsg0(000, "YESNO\n"); - new yesnoPopUp(m_console); + new yesnoPopUp(m_console, m_conn); break; case BNET_RUN_CMD: if (mainWin->m_commDebug) Pmsg0(000, "RUN CMD\n"); new runCmdPage(); break; + case BNET_START_RTREE: + if (mainWin->m_commDebug) Pmsg0(000, "START RTREE CMD\n"); + new restorePage(m_conn); + break; + case BNET_END_RTREE: + if (mainWin->m_commDebug) Pmsg0(000, "END RTREE CMD\n"); + break; case BNET_ERROR_MSG: if (mainWin->m_commDebug) Pmsg0(000, "ERROR MSG\n"); - m_sock->recv(); /* get the message */ + stat = sock_read(); /* get the message */ m_console->display_text(msg()); - QMessageBox::critical(this, "Error", msg(), QMessageBox::Ok); + QMessageBox::critical(m_console, "Error", msg(), QMessageBox::Ok); break; case BNET_WARNING_MSG: if (mainWin->m_commDebug) Pmsg0(000, "WARNING MSG\n"); - m_sock->recv(); /* get the message */ + stat = sock_read(); /* get the message */ m_console->display_text(msg()); - QMessageBox::critical(this, "Warning", msg(), QMessageBox::Ok); + QMessageBox::critical(m_console, "Warning", msg(), QMessageBox::Ok); break; case BNET_INFO_MSG: if (mainWin->m_commDebug) Pmsg0(000, "INFO MSG\n"); - m_sock->recv(); /* get the message */ + stat = sock_read(); /* get the message */ m_console->display_text(msg()); mainWin->set_status(msg()); break; } if (is_bnet_stop(m_sock)) { /* error or term request */ if (mainWin->m_commDebug) Pmsg0(000, "BNET STOP\n"); - stopTimer(); + m_console->stopTimer(); m_sock->close(); m_sock = NULL; mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png")); QBrush redBrush(Qt::red); - QTreeWidgetItem *item = mainWin->getFromHash(this); + QTreeWidgetItem *item = mainWin->getFromHash(m_console); item->setForeground(0, redBrush); - m_notifier->setEnabled(false); - delete m_notifier; - m_notifier = NULL; + if (m_notifier) { + m_notifier->setEnabled(false); + delete m_notifier; + m_notifier = NULL; + } mainWin->set_status(_("Director disconnected.")); QApplication::restoreOverrideCursor(); stat = BNET_HARDEOF; @@ -515,21 +417,28 @@ void DirComm::read_dir(int /* fd */) * from the Directory, so we set notify to off. * m_console->notifiy(false); */ -void DirComm::notify(bool enable) +bool DirComm::notify(bool enable) { - m_notifier->setEnabled(enable); + bool prev_enabled = false; + if (m_notifier) { + prev_enabled = m_notifier->isEnabled(); + m_notifier->setEnabled(enable); + if (mainWin->m_connDebug) + if (prev_enabled && !enable) + Pmsg1(000, "m_notifier Disabling notifier: %i\n", m_conn); + else if (!prev_enabled && enable) + Pmsg1(000, "m_notifier Enabling notifier: %i\n", m_conn); + } else if (mainWin->m_connDebug) + Pmsg1(000, "m_notifier does not exist: %i\n", m_conn); + return prev_enabled; } -bool DirComm::is_connectedGui() +bool DirComm::is_notify_enabled() const { - if (is_connected()) { - return true; - } else { - QString message( tr("Director is currently disconnected\n Please reconnect!")); - QMessageBox::warning(this, "Bat", - message.toUtf8().data(), QMessageBox::Ok ); - return false; - } + bool enabled = false; + if (m_notifier) + enabled = m_notifier->isEnabled(); + return enabled; } /* diff --git a/bacula/src/qt-console/bcomm/dircomm.h b/bacula/src/qt-console/bcomm/dircomm.h index b042036481..4f84a2a03f 100644 --- a/bacula/src/qt-console/bcomm/dircomm.h +++ b/bacula/src/qt-console/bcomm/dircomm.h @@ -3,7 +3,7 @@ /* Bacula® - The Network Backup Solution - Copyright (C) 2007-2007 Free Software Foundation Europe e.V. + Copyright (C) 2007-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. @@ -29,76 +29,57 @@ */ /* * Version $Id$ - * - * This is an attempt to move the higher level read/write type - * functionality to the Director out of the Console class into - * a Bacula Communications class. This class builds on the - * BSOCK class. - * * - * Kern Sibbald, May 2007 + * Kern Sibbald, January 2007 */ -#include "bat.h" +#include #include "pages.h" +#include "ui_console.h" +#include + +#ifndef MAX_NAME_LENGTH +#define MAX_NAME_LENGTH 128 +#endif class DIRRES; class BSOCK; +class JCR; class CONRES; -class DirComm : public Pages +//class DirComm : public QObject +class DirComm : public QObject { Q_OBJECT - + friend class Console; public: - DirComm(Console *console); + DirComm(Console *parent, int conn); ~DirComm(); - void display_text(const char *buf); - void display_text(const QString buf); - void display_textf(const char *fmt, ...); - void display_html(const QString buf); - void update_cursor(void); - void write_dir(const char *buf); - bool dir_cmd(const char *cmd, QStringList &results); - bool dir_cmd(QString &cmd, QStringList &results); - bool sql_cmd(const char *cmd, QStringList &results); - bool sql_cmd(QString &cmd, QStringList &results); + Console *m_console; + int sock_read(); bool authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons, char *buf, int buflen); bool is_connected() { return m_sock != NULL; }; - bool is_connectedGui(); + bool is_ready() { return is_connected() && m_at_prompt && m_at_main_prompt; }; char *msg(); - void notify(bool enable); + bool notify(bool enable); // enables/disables socket notification - returns the previous state + bool is_notify_enabled() const; void terminate(); - void beginNewCommand(); - void displayToPrompt(); - void discardToPrompt(); - void setDirectorTreeItem(QTreeWidgetItem *); - void setDirRes(DIRRES *dir); - void getDirResName(QString &); - void startTimer(); - void stopTimer(); - -public slots: - void connect_dir(DIRRES *dir, CONRES *cons); - void read_dir(int fd); + bool connect_dir(); int read(void); int write(const char *msg); int write(QString msg); - void poll_messages(void); -public: +public slots: + void read_dir(int fd); private: - DIRRES *m_dir; BSOCK *m_sock; bool m_at_prompt; bool m_at_main_prompt; QSocketNotifier *m_notifier; - Console *m_console; bool m_api_set; - bool m_messages_pending; - QTimer *m_timer; + int m_conn; }; #endif /* _DIRCOMM_H_ */ diff --git a/bacula/src/qt-console/bcomm/dircomm_auth.cpp b/bacula/src/qt-console/bcomm/dircomm_auth.cpp index fbd1b4a4de..1f7524a6b7 100644 --- a/bacula/src/qt-console/bcomm/dircomm_auth.cpp +++ b/bacula/src/qt-console/bcomm/dircomm_auth.cpp @@ -39,7 +39,6 @@ #include "bat.h" -#include "dircomm.h" /* Commands sent to Director */ @@ -59,6 +58,7 @@ bool DirComm::authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons, BSOCK *dir = jcr->dir_bsock; int tls_local_need = BNET_TLS_NONE; int tls_remote_need = BNET_TLS_NONE; + bool tls_authenticate; int compatible = true; char bashed_name[MAX_NAME_LENGTH]; char *password; @@ -80,6 +80,7 @@ bool DirComm::authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons, tls_local_need = BNET_TLS_OK; } } + tls_authenticate = cons->tls_authenticate; tls_ctx = cons->tls_ctx; } else { bstrncpy(bashed_name, "*UserAgent*", sizeof(bashed_name)); @@ -93,8 +94,13 @@ bool DirComm::authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons, } } + tls_authenticate = director->tls_authenticate; tls_ctx = director->tls_ctx; } + if (tls_authenticate) { + tls_local_need = BNET_TLS_REQUIRED; + } + /* Timeout Hello after 15 secs */ dir->start_timer(15); dir->fsend(hello, bashed_name); @@ -126,14 +132,15 @@ bool DirComm::authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons, } /* Is TLS Enabled? */ - if (have_tls) { - if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { - /* Engage TLS! Full Speed Ahead! */ - if (!bnet_tls_client(tls_ctx, dir, NULL)) { - bsnprintf(errmsg, errmsg_len, _("TLS negotiation failed with Director at \"%s:%d\"\n"), - dir->host(), dir->port()); - goto bail_out; - } + if (tls_local_need >= BNET_TLS_OK && tls_remote_need >= BNET_TLS_OK) { + /* Engage TLS! Full Speed Ahead! */ + if (!bnet_tls_client(tls_ctx, dir, NULL)) { + bsnprintf(errmsg, errmsg_len, _("TLS negotiation failed with Director at \"%s:%d\"\n"), + dir->host(), dir->port()); + goto bail_out; + } + if (tls_authenticate) { /* authenticate only? */ + dir->free_tls(); /* Yes, shutdown tls */ } } diff --git a/bacula/src/qt-console/clients/clients.cpp b/bacula/src/qt-console/clients/clients.cpp index 20eabe1260..9f82e278aa 100644 --- a/bacula/src/qt-console/clients/clients.cpp +++ b/bacula/src/qt-console/clients/clients.cpp @@ -72,8 +72,6 @@ Clients::~Clients() */ void Clients::populateTable() { - if (!m_console->preventInUseConnect()) - return; m_populated = true; Freeze frz(*tableWidget); /* disable updating*/ diff --git a/bacula/src/qt-console/console/console.cpp b/bacula/src/qt-console/console/console.cpp index 7e4cd70652..8a14015091 100644 --- a/bacula/src/qt-console/console/console.cpp +++ b/bacula/src/qt-console/console/console.cpp @@ -40,23 +40,17 @@ #include "select.h" #include "run/run.h" -static int tls_pem_callback(char *buf, int size, const void *userdata); - - -Console::Console(QStackedWidget *parent): -m_notifier(NULL), -m_api_set(false) +Console::Console(QStackedWidget *parent) { QFont font; m_messages_pending = false; m_parent = parent; m_closeable = false; m_console = this; + m_dircommCounter = 0; + m_dircommHash.insert(m_dircommCounter, new DirComm(this, m_dircommCounter)); setupUi(this); - m_sock = NULL; - m_at_prompt = false; - m_at_main_prompt = false; m_textEdit = textEdit; /* our console screen */ m_cursor = new QTextCursor(m_textEdit->document()); mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png")); @@ -97,180 +91,70 @@ void Console::stopTimer() * requires preferences of check messages and operates at interval */ void Console::poll_messages() { - if ( mainWin->m_checkMessages && m_at_main_prompt && hasFocus()){ + int conn = availableDirComm(); + DirComm *dircomm = m_dircommHash.value(conn); + + if (mainWin->m_checkMessages && dircomm->m_at_main_prompt && hasFocus()){ messagesPending(true); - write(".messages"); - displayToPrompt(); + dircomm->write(".messages"); + displayToPrompt(conn); messagesPending(false); } } -/* Terminate any open socket */ -void Console::terminate() -{ - if (m_sock) { - if (m_notifier) { - m_notifier->setEnabled(false); - delete m_notifier; - m_notifier = NULL; - } - stopTimer(); - m_sock->close(); - m_sock = NULL; - } -} - /* * Connect to Director. */ void Console::connect_dir() { - JCR *jcr = new JCR; - utime_t heart_beat; - char buf[1024]; - CONRES *cons; - - buf[0] = 0; - - m_textEdit = textEdit; /* our console screen */ + DirComm *dircomm = m_dircommHash.value(0); - if (!m_dir) { + if (!m_console->m_dir) { mainWin->set_status( tr("No Director found.")); - goto bail_out; - } - if (m_sock) { - mainWin->set_status( tr("Already connected.")); - goto bail_out; + return; } - memset(jcr, 0, sizeof(JCR)); - - mainWin->set_statusf(_("Connecting to Director %s:%d"), m_dir->address, m_dir->DIRport); - display_textf(_("Connecting to Director %s:%d\n\n"), m_dir->address, m_dir->DIRport); + m_textEdit = textEdit; /* our console screen */ - /* Give GUI a chance */ - app->processEvents(); - - LockRes(); - /* If cons==NULL, default console will be used */ - cons = (CONRES *)GetNextRes(R_CONSOLE, NULL); - UnlockRes(); - - /* Initialize Console TLS context once */ - if (cons && !cons->tls_ctx && (cons->tls_enable || cons->tls_require)) { - /* Generate passphrase prompt */ - bsnprintf(buf, sizeof(buf), "Passphrase for Console \"%s\" TLS private key: ", - cons->name()); - - /* Initialize TLS context: - * Args: CA certfile, CA certdir, Certfile, Keyfile, - * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer - */ - cons->tls_ctx = new_tls_context(cons->tls_ca_certfile, - cons->tls_ca_certdir, cons->tls_certfile, - cons->tls_keyfile, tls_pem_callback, &buf, NULL, true); - - if (!cons->tls_ctx) { - display_textf(_("Failed to initialize TLS context for Console \"%s\".\n"), - m_dir->name()); - goto bail_out; + if (dircomm->connect_dir()) { + if (mainWin->m_connDebug) + Pmsg0(000, "DirComm 0 Seems to have Connected\n"); + beginNewCommand(0); + job_list.clear(); + client_list.clear(); + fileset_list.clear(); + fileset_list.clear(); + messages_list.clear(); + pool_list.clear(); + storage_list.clear(); + type_list.clear(); + level_list.clear(); + int jl = 0; + bool done = false; + /* this was added because I was getting job lists with 0 count, but not consistently*/ + while (!done) { + dir_cmd(".jobs", job_list); + jl++; + if ((jl > 10) || job_list.count() > 0) done = true; } - } - - /* Initialize Director TLS context once */ - if (!m_dir->tls_ctx && (m_dir->tls_enable || m_dir->tls_require)) { - /* Generate passphrase prompt */ - bsnprintf(buf, sizeof(buf), "Passphrase for Director \"%s\" TLS private key: ", - m_dir->name()); - - /* Initialize TLS context: - * Args: CA certfile, CA certdir, Certfile, Keyfile, - * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */ - m_dir->tls_ctx = new_tls_context(m_dir->tls_ca_certfile, - m_dir->tls_ca_certdir, m_dir->tls_certfile, - m_dir->tls_keyfile, tls_pem_callback, &buf, NULL, true); - - if (!m_dir->tls_ctx) { - display_textf(_("Failed to initialize TLS context for Director \"%s\".\n"), - m_dir->name()); - mainWin->set_status( tr("Connection failed") ); - goto bail_out; + dir_cmd(".clients", client_list); + dir_cmd(".filesets", fileset_list); + dir_cmd(".msgs", messages_list); + dir_cmd(".pools", pool_list); + dir_cmd(".storage", storage_list); + dir_cmd(".types", type_list); + dir_cmd(".levels", level_list); + + if (mainWin->m_connDebug) { + QString dbgmsg = QString("jobs=%1 clients=%2 filesets=%3 msgs=%4 pools=%5 storage=%6 types=%7 levels=%8\n") + .arg(job_list.count()).arg(client_list.count()).arg(fileset_list.count()).arg(messages_list.count()) + .arg(pool_list.count()).arg(storage_list.count()).arg(type_list.count()).arg(level_list.count()); + Pmsg1(000, "%s\n", dbgmsg.toUtf8().data()); } + + mainWin->set_status(_("Connected")); + startTimer(); /* start message timer */ } - - if (m_dir->heartbeat_interval) { - heart_beat = m_dir->heartbeat_interval; - } else if (cons) { - heart_beat = cons->heartbeat_interval; - } else { - heart_beat = 0; - } - - m_sock = bnet_connect(NULL, 5, 15, heart_beat, - _("Director daemon"), m_dir->address, - NULL, m_dir->DIRport, 0); - if (m_sock == NULL) { - mainWin->set_status("Connection failed"); - goto bail_out; - } else { - /* Update page selector to green to indicate that Console is connected */ - mainWin->actionConnect->setIcon(QIcon(":images/connected.png")); - QBrush greenBrush(Qt::green); - QTreeWidgetItem *item = mainWin->getFromHash(this); - item->setForeground(0, greenBrush); - } - - jcr->dir_bsock = m_sock; - - if (!authenticate_director(jcr, m_dir, cons, buf, sizeof(buf))) { - display_text(buf); - goto bail_out; - } - - if (buf[0]) { - display_text(buf); - } - - /* Give GUI a chance */ - app->processEvents(); - - mainWin->set_status(_("Initializing ...")); - -#ifndef HAVE_WIN32 - /* Set up input notifier */ - m_notifier = new QSocketNotifier(m_sock->m_fd, QSocketNotifier::Read, 0); - QObject::connect(m_notifier, SIGNAL(activated(int)), this, SLOT(read_dir(int))); -#endif - - write(".api 1"); - m_api_set = true; - displayToPrompt(); - - beginNewCommand(); - job_list.clear(); - client_list.clear(); - fileset_list.clear(); - fileset_list.clear(); - messages_list.clear(); - pool_list.clear(); - storage_list.clear(); - type_list.clear(); - level_list.clear(); - dir_cmd(".jobs", job_list); - dir_cmd(".clients", client_list); - dir_cmd(".filesets", fileset_list); - dir_cmd(".msgs", messages_list); - dir_cmd(".pools", pool_list); - dir_cmd(".storage", storage_list); - dir_cmd(".types", type_list); - dir_cmd(".levels", level_list); - - mainWin->set_status(_("Connected")); - startTimer(); /* start message timer */ - -bail_out: - delete jcr; - return; } bool Console::dir_cmd(QString &cmd, QStringList &results) @@ -284,17 +168,21 @@ bool Console::dir_cmd(QString &cmd, QStringList &results) */ bool Console::dir_cmd(const char *cmd, QStringList &results) { + int conn = availableDirComm(); int stat; - - notify(false); - write(cmd); - while ((stat = read()) > 0) { - if (mainWin->m_displayAll) display_text(msg()); - strip_trailing_junk(msg()); - results << msg(); + DirComm *dircomm = m_dircommHash.value(conn); + + if (mainWin->m_connDebug) + Pmsg2(000, "dir_cmd conn %i %s\n", conn, cmd); + notify(conn, false); + dircomm->write(cmd); + while ((stat = dircomm->read()) > 0) { + if (mainWin->m_displayAll) display_text(dircomm->msg()); + strip_trailing_junk(dircomm->msg()); + results << dircomm->msg(); } - notify(true); - discardToPrompt(); + notify(conn, true); + discardToPrompt(conn); return true; /* ***FIXME*** return any command error */ } @@ -309,6 +197,8 @@ bool Console::sql_cmd(QString &query, QStringList &results) */ bool Console::sql_cmd(const char *query, QStringList &results) { + int conn = availableDirComm(); + DirComm *dircomm = m_dircommHash.value(conn); int stat; POOL_MEM cmd(PM_MESSAGE); @@ -316,33 +206,62 @@ bool Console::sql_cmd(const char *query, QStringList &results) return false; } - notify(false); + if (mainWin->m_connDebug) + Pmsg2(000, "sql_cmd conn %i %s\n", conn, query); + notify(conn, false); pm_strcpy(cmd, ".sql query=\""); pm_strcat(cmd, query); pm_strcat(cmd, "\""); - write(cmd.c_str()); - while ((stat = read()) > 0) { + dircomm->write(cmd.c_str()); + while ((stat = dircomm->read()) > 0) { bool first = true; if (mainWin->m_displayAll) { - display_text(msg()); + display_text(dircomm->msg()); display_text("\n"); } - strip_trailing_junk(msg()); + strip_trailing_junk(dircomm->msg()); bool doappend = true; if (first) { - QString dum = msg(); + QString dum = dircomm->msg(); if ((dum.left(6) == "*None*")) doappend = false; } if (doappend) - results << msg(); + results << dircomm->msg(); first = false; } - notify(true); - discardToPrompt(); + notify(conn, true); + discardToPrompt(conn); return true; /* ***FIXME*** return any command error */ } +/* Send a command to the Director */ +int Console::write_dir(const char *msg) +{ + int conn = availableDirComm(); + write_dir(conn, msg); + return conn; +} + +/* Send a command to the Director */ +void Console::write_dir(int conn, const char *msg) +{ + DirComm *dircomm = m_dircommHash.value(conn); + + if (dircomm->m_sock) { + mainWin->set_status(_("Processing command ...")); + QApplication::setOverrideCursor(Qt::WaitCursor); + dircomm->write(msg); + } else { + mainWin->set_status( tr(" Director not connected. Click on connect button.")); + mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png")); + QBrush redBrush(Qt::red); + QTreeWidgetItem *item = mainWin->getFromHash(this); + item->setForeground(0, redBrush); + dircomm->m_at_prompt = false; + dircomm->m_at_main_prompt = false; + } +} /* * Send a job name to the director, and read all the resulting @@ -354,13 +273,16 @@ bool Console::get_job_defaults(struct job_defaults &job_defs) int stat; char *def; - notify(false); - beginNewCommand(); + int conn = notifyOff(); + beginNewCommand(conn); + DirComm *dircomm = m_dircommHash.value(conn); + if (mainWin->m_connDebug) + Pmsg1(000, "job_defaults conn %i\n", conn); scmd = QString(".defaults job=\"%1\"").arg(job_defs.job_name); - write(scmd); - while ((stat = read()) > 0) { - if (mainWin->m_displayAll) display_text(msg()); - def = strchr(msg(), '='); + dircomm->write(scmd); + while ((stat = dircomm->read()) > 0) { + if (mainWin->m_displayAll) display_text(dircomm->msg()); + def = strchr(dircomm->msg(), '='); if (!def) { continue; } @@ -368,59 +290,59 @@ bool Console::get_job_defaults(struct job_defaults &job_defs) *def++ = 0; strip_trailing_junk(def); - if (strcmp(msg(), "job") == 0) { + if (strcmp(dircomm->msg(), "job") == 0) { if (strcmp(def, job_defs.job_name.toUtf8().data()) != 0) { goto bail_out; } continue; } - if (strcmp(msg(), "pool") == 0) { + if (strcmp(dircomm->msg(), "pool") == 0) { job_defs.pool_name = def; continue; } - if (strcmp(msg(), "messages") == 0) { + if (strcmp(dircomm->msg(), "messages") == 0) { job_defs.messages_name = def; continue; } - if (strcmp(msg(), "client") == 0) { + if (strcmp(dircomm->msg(), "client") == 0) { job_defs.client_name = def; continue; } - if (strcmp(msg(), "storage") == 0) { + if (strcmp(dircomm->msg(), "storage") == 0) { job_defs.store_name = def; continue; } - if (strcmp(msg(), "where") == 0) { + if (strcmp(dircomm->msg(), "where") == 0) { job_defs.where = def; continue; } - if (strcmp(msg(), "level") == 0) { + if (strcmp(dircomm->msg(), "level") == 0) { job_defs.level = def; continue; } - if (strcmp(msg(), "type") == 0) { + if (strcmp(dircomm->msg(), "type") == 0) { job_defs.type = def; continue; } - if (strcmp(msg(), "fileset") == 0) { + if (strcmp(dircomm->msg(), "fileset") == 0) { job_defs.fileset_name = def; continue; } - if (strcmp(msg(), "catalog") == 0) { + if (strcmp(dircomm->msg(), "catalog") == 0) { job_defs.catalog_name = def; continue; } - if (strcmp(msg(), "enabled") == 0) { + if (strcmp(dircomm->msg(), "enabled") == 0) { job_defs.enabled = *def == '1' ? true : false; continue; } } - notify(true); + notify(conn, true); return true; bail_out: - notify(true); + notify(conn, true); return false; } @@ -537,78 +459,32 @@ void Console::update_cursor() m_textEdit->ensureCursorVisible(); } -/* - * This should be moved into a bSocket class - */ -char *Console::msg() +void Console::beginNewCommand(int conn) { - if (m_sock) { - return m_sock->msg; - } - return NULL; -} + DirComm *dircomm = m_dircommHash.value(conn); -/* Send a command to the Director */ -void Console::write_dir(const char *msg) -{ - if (m_sock) { - mainWin->set_status(_("Processing command ...")); - QApplication::setOverrideCursor(Qt::WaitCursor); - write(msg); - } else { - mainWin->set_status( tr(" Director not connected. Click on connect button.")); - mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png")); - QBrush redBrush(Qt::red); - QTreeWidgetItem *item = mainWin->getFromHash(this); - item->setForeground(0, redBrush); - m_at_prompt = false; - m_at_main_prompt = false; - } -} - -int Console::write(const QString msg) -{ - return write(msg.toUtf8().data()); -} - -int Console::write(const char *msg) -{ - if (!m_sock) { - return -1; - } - m_sock->msglen = pm_strcpy(m_sock->msg, msg); - m_at_prompt = false; - m_at_main_prompt = false; - if (mainWin->m_commDebug) Pmsg1(000, "send: %s\n", msg); - return m_sock->send(); - -} - -/* - * Get to main command prompt -- i.e. abort any subcommand - */ -void Console::beginNewCommand() -{ for (int i=0; i < 3; i++) { - write("."); - while (read() > 0) { - if (mainWin->m_displayAll) display_text(msg()); + dircomm->write("."); + while (dircomm->read() > 0) { + if (mainWin->m_displayAll) display_text(dircomm->msg()); } - if (m_at_main_prompt) { + if (dircomm->m_at_main_prompt) { break; } } display_text("\n"); } -void Console::displayToPrompt() +void Console::displayToPrompt(int conn) { + DirComm *dircomm = m_dircommHash.value(conn); + int stat = 0; QString buf; if (mainWin->m_commDebug) Pmsg0(000, "DisplaytoPrompt\n"); - while (!m_at_prompt) { - if ((stat=read()) > 0) { - buf += msg(); + while (!dircomm->m_at_prompt) { + if ((stat=dircomm->read()) > 0) { + buf += dircomm->msg(); if (buf.size() >= 8196 || m_messages_pending) { display_text(buf); buf.clear(); @@ -620,181 +496,22 @@ void Console::displayToPrompt() if (mainWin->m_commDebug) Pmsg1(000, "endDisplaytoPrompt=%d\n", stat); } -void Console::discardToPrompt() -{ +void Console::discardToPrompt(int conn) +{ + DirComm *dircomm = m_dircommHash.value(conn); + int stat = 0; if (mainWin->m_commDebug) Pmsg0(000, "discardToPrompt\n"); if (mainWin->m_displayAll) { - displayToPrompt(); + displayToPrompt(conn); } else { - while (!m_at_prompt) { - stat=read(); + while (!dircomm->m_at_prompt) { + stat=dircomm->read(); } } if (mainWin->m_commDebug) Pmsg1(000, "endDiscardToPrompt=%d\n", stat); } -int Console::sock_read() -{ - int stat; -#ifdef HAVE_WIN32 - bool wasEnabled = notify(false); - stat = m_sock->recv(); - notify(wasEnabled); -#else - stat = m_sock->recv(); -#endif - return stat; -} - -/* - * Blocking read from director - */ -int Console::read() -{ - int stat = 0; - while (m_sock) { - for (;;) { - stat = m_sock->wait_data_intr(0, 50000); - if (stat > 0) { - break; - } - app->processEvents(); - if (m_api_set && m_messages_pending && is_notify_enabled() && hasFocus()) { - write_dir(".messages"); - messagesPending(false); - } - } - m_sock->msg[0] = 0; - stat = sock_read(); - if (stat >= 0) { - if (mainWin->m_commDebug) Pmsg1(000, "got: %s\n", m_sock->msg); - if (m_at_prompt) { - display_text("\n"); - m_at_prompt = false; - m_at_main_prompt = false; - } - } - switch (m_sock->msglen) { - case BNET_MSGS_PENDING : - if (is_notify_enabled() && hasFocus()) { - if (mainWin->m_commDebug) Pmsg0(000, "MSGS PENDING\n"); - write_dir(".messages"); - displayToPrompt(); - messagesPending(false); - } - messagesPending(true); - continue; - case BNET_CMD_OK: - if (mainWin->m_commDebug) Pmsg0(000, "CMD OK\n"); - m_at_prompt = false; - m_at_main_prompt = false; - mainWin->set_status(_("Command completed ...")); - continue; - case BNET_CMD_BEGIN: - if (mainWin->m_commDebug) Pmsg0(000, "CMD BEGIN\n"); - m_at_prompt = false; - m_at_main_prompt = false; - mainWin->set_status(_("Processing command ...")); - continue; - case BNET_MAIN_PROMPT: - if (mainWin->m_commDebug) Pmsg0(000, "MAIN PROMPT\n"); - m_at_prompt = true; - m_at_main_prompt = true; - mainWin->set_status(_("At main prompt waiting for input ...")); - QApplication::restoreOverrideCursor(); - break; - case BNET_PROMPT: - if (mainWin->m_commDebug) Pmsg0(000, "PROMPT\n"); - m_at_prompt = true; - m_at_main_prompt = false; - mainWin->set_status(_("At prompt waiting for input ...")); - QApplication::restoreOverrideCursor(); - break; - case BNET_CMD_FAILED: - if (mainWin->m_commDebug) Pmsg0(000, "CMD FAILED\n"); - mainWin->set_status(_("Command failed.")); - QApplication::restoreOverrideCursor(); - break; - /* We should not get this one */ - case BNET_EOD: - if (mainWin->m_commDebug) Pmsg0(000, "EOD\n"); - mainWin->set_status_ready(); - QApplication::restoreOverrideCursor(); - if (!m_api_set) { - break; - } - continue; - case BNET_START_SELECT: - if (mainWin->m_commDebug) Pmsg0(000, "START SELECT\n"); - new selectDialog(this); - break; - case BNET_YESNO: - if (mainWin->m_commDebug) Pmsg0(000, "YESNO\n"); - new yesnoPopUp(this); - break; - case BNET_RUN_CMD: - if (mainWin->m_commDebug) Pmsg0(000, "RUN CMD\n"); - new runCmdPage(); - break; - case BNET_START_RTREE: - if (mainWin->m_commDebug) Pmsg0(000, "START RTREE CMD\n"); - new restorePage(); - break; - case BNET_END_RTREE: - if (mainWin->m_commDebug) Pmsg0(000, "END RTREE CMD\n"); - break; - case BNET_ERROR_MSG: - if (mainWin->m_commDebug) Pmsg0(000, "ERROR MSG\n"); - stat = sock_read(); /* get the message */ - display_text(msg()); - QMessageBox::critical(this, "Error", msg(), QMessageBox::Ok); - break; - case BNET_WARNING_MSG: - if (mainWin->m_commDebug) Pmsg0(000, "WARNING MSG\n"); - stat = sock_read(); /* get the message */ - display_text(msg()); - QMessageBox::critical(this, "Warning", msg(), QMessageBox::Ok); - break; - case BNET_INFO_MSG: - if (mainWin->m_commDebug) Pmsg0(000, "INFO MSG\n"); - stat = sock_read(); /* get the message */ - display_text(msg()); - mainWin->set_status(msg()); - break; - } - if (is_bnet_stop(m_sock)) { /* error or term request */ - if (mainWin->m_commDebug) Pmsg0(000, "BNET STOP\n"); - stopTimer(); - m_sock->close(); - m_sock = NULL; - mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png")); - QBrush redBrush(Qt::red); - QTreeWidgetItem *item = mainWin->getFromHash(this); - item->setForeground(0, redBrush); - if (m_notifier) { - m_notifier->setEnabled(false); - delete m_notifier; - m_notifier = NULL; - } - mainWin->set_status(_("Director disconnected.")); - QApplication::restoreOverrideCursor(); - stat = BNET_HARDEOF; - } - break; - } - return stat; -} - -/* Called by signal when the Director has output for us */ -void Console::read_dir(int /* fd */) -{ - if (mainWin->m_commDebug) Pmsg0(000, "read_dir\n"); - while (read() >= 0) { - display_text(msg()); - } -} - /* * When the notifier is enabled, read_dir() will automatically be * called by the Qt event loop when ever there is any output @@ -805,22 +522,27 @@ void Console::read_dir(int /* fd */) * from the Directory, so we set notify to off. * m_console->notifiy(false); */ -bool Console::notify(bool enable) + +/* dual purpose function to turn notify off and return an available connection */ +int Console::notifyOff() { - bool prev_enabled = false; - if (m_notifier) { - prev_enabled = m_notifier->isEnabled(); - m_notifier->setEnabled(enable); - } - return prev_enabled; + int conn = availableDirComm(); + notify(conn, false); + return conn; +} + +/* knowing a connection, turn notify off or on */ +bool Console::notify(int conn, bool enable) +{ + DirComm *dircomm = m_dircommHash.value(conn); + return dircomm->notify(enable); } -bool Console::is_notify_enabled() const +/* knowing a connection, return notify state */ +bool Console::is_notify_enabled(int conn) const { - bool enabled = false; - if (m_notifier) - enabled = m_notifier->isEnabled(); - return enabled; + DirComm *dircomm = m_dircommHash.value(conn); + return dircomm->is_notify_enabled(); } void Console::setDirectorTreeItem(QTreeWidgetItem *item) @@ -841,77 +563,6 @@ void Console::getDirResName(QString &name_returned) name_returned = m_dir->name(); } -bool Console::is_connectedGui() -{ - if (is_connected()) { - return true; - } else { - QString message = tr("Director is currently disconnected\nPlease reconnect!"); - QMessageBox::warning(this, "Bat", message, QMessageBox::Ok ); - return false; - } -} - -/* - * A temporary function to prevent connecting to the director if the director - * is busy with a restore. - */ -bool Console::preventInUseConnect() -{ - if (!is_connected()) { - QString message = tr("Director %1 is currently disconnected\n" - "Please reconnect!").arg(m_dir->name()); - QMessageBox::warning(this, "Bat", message, QMessageBox::Ok ); - return false; - } else if (!m_at_main_prompt){ - QString message = tr("Director %1 is currently busy\n Please complete " - "restore or other operation! This is a limitation " - "that will be resolved before a beta release. " - "This is currently an alpha release.").arg(m_dir->name()); - QMessageBox::warning(this, "Bat", message, QMessageBox::Ok ); - return false; - } else if (!m_at_prompt){ - QString message = tr("Director %1 is currently not at a prompt\n" - " Please try again!").arg(m_dir->name()); - QMessageBox::warning(this, "Bat", message, QMessageBox::Ok ); - return false; - } else { - return true; - } -} - -/* - * Call-back for reading a passphrase for an encrypted PEM file - * This function uses getpass(), - * which uses a static buffer and is NOT thread-safe. - */ -static int tls_pem_callback(char *buf, int size, const void *userdata) -{ - (void)size; - (void)userdata; -#ifdef HAVE_TLS - const char *prompt = (const char *)userdata; -# if defined(HAVE_WIN32) - //sendit(prompt); - if (win32_cgets(buf, size) == NULL) { - buf[0] = 0; - return 0; - } else { - return strlen(buf); - } -# else - char *passwd; - - passwd = getpass(prompt); - bstrncpy(buf, passwd, size); - return strlen(buf); -# endif -#else - buf[0] = 0; - return 0; -#endif -} - /* Slot for responding to page selectors status help command */ void Console::consoleHelp() { @@ -983,3 +634,100 @@ bool Console::messagesPending(bool pend) mainWin->setMessageIcon(); return prev; } + +/* terminate all existing connections */ +void Console::terminate() +{ + foreach(DirComm* dircomm, m_dircommHash) { + dircomm->terminate(); + } + m_console->stopTimer(); +} + +/* Maybe this should be checking the list, for the moment lets check 0 which should be connected */ +bool Console::is_connectedGui() +{ + if (is_connected(0)) { + return true; + } else { + QString message = tr("Director is currently disconnected\nPlease reconnect!"); + QMessageBox::warning(this, "Bat", message, QMessageBox::Ok ); + return false; + } +} + +int Console::read(int conn) +{ + DirComm *dircomm = m_dircommHash.value(conn); + return dircomm->read(); +} + +char *Console::msg(int conn) +{ + DirComm *dircomm = m_dircommHash.value(conn); + return dircomm->msg(); +} + +int Console::write(int conn, const QString msg) +{ + DirComm *dircomm = m_dircommHash.value(conn); + return dircomm->write(msg); +} + +int Console::write(int conn, const char *msg) +{ + DirComm *dircomm = m_dircommHash.value(conn); + return dircomm->write(msg); +} + +/* This checks to see if any is connected */ +bool Console::is_connected() +{ + bool connected = false; + foreach(DirComm* dircomm, m_dircommHash) { + if (dircomm->is_connected()) + return true; + } + return connected; +} + +/* knowing the connection id, is it connected */ +bool Console::is_connected(int conn) +{ + DirComm *dircomm = m_dircommHash.value(conn); + return dircomm->is_connected(); +} + +/* + * Need an available connection. Check existing connections or create one + */ +int Console::availableDirComm() +{ + QHash::const_iterator iter = m_dircommHash.constBegin(); + while (iter != m_dircommHash.constEnd()) { + DirComm *dircomm = iter.value(); + if (dircomm->m_at_prompt && dircomm->m_at_main_prompt && dircomm->is_notify_enabled()) + return dircomm->m_conn; + ++iter; + } + return newDirComm(); +} + +/* + * Create a new connection + */ +int Console::newDirComm() +{ + m_dircommCounter += 1; + if (mainWin->m_connDebug) + Pmsg1(000, "DirComm %i About to Create and Connect\n", m_dircommCounter); + DirComm *dircomm = new DirComm(this, m_dircommCounter); + m_dircommHash.insert(m_dircommCounter, dircomm); + bool success = dircomm->connect_dir(); + if (mainWin->m_connDebug) + if (success) + Pmsg1(000, "DirComm %i Connected\n", m_dircommCounter); + else + Pmsg1(000, "DirComm %i NOT Connected\n", m_dircommCounter); + return m_dircommCounter; +} diff --git a/bacula/src/qt-console/console/console.h b/bacula/src/qt-console/console/console.h index 65ab2d8c9c..198bf0ad0b 100644 --- a/bacula/src/qt-console/console/console.h +++ b/bacula/src/qt-console/console/console.h @@ -36,6 +36,7 @@ #include #include "pages.h" #include "ui_console.h" +#include "bcomm/dircomm.h" #ifndef MAX_NAME_LENGTH #define MAX_NAME_LENGTH 128 @@ -58,57 +59,64 @@ struct job_defaults { bool enabled; }; -class DIRRES; -class BSOCK; -class JCR; -class CONRES; +//class DIRRES; +//class BSOCK; +//class JCR; +//class CONRES; class Console : public Pages, public Ui::ConsoleForm { Q_OBJECT + friend class DirComm; public: Console(QStackedWidget *parent); ~Console(); - void display_text(const char *buf); - void display_text(const QString buf); - void display_textf(const char *fmt, ...); - void display_html(const QString buf); - void update_cursor(void); - void write_dir(const char *buf); - int sock_read(); + int read(int conn); + char *msg(int conn); + void discardToPrompt(int conn); + int write(int conn, const char *msg); + int write(int conn, QString msg); + int notifyOff(); // enables/disables socket notification - returns the previous state + bool notify(int conn, bool enable); // enables/disables socket notification - returns the previous state + bool is_notify_enabled(int conn) const; + int availableDirComm(); + void displayToPrompt(int conn); + bool dir_cmd(const char *cmd, QStringList &results); bool dir_cmd(QString &cmd, QStringList &results); bool sql_cmd(const char *cmd, QStringList &results); bool sql_cmd(QString &cmd, QStringList &results); - bool authenticate_director(JCR *jcr, DIRRES *director, CONRES *cons, - char *buf, int buflen); - bool is_connected() { return m_sock != NULL; }; - bool is_ready() { return is_connected() && m_at_prompt && m_at_main_prompt; }; - bool is_connectedGui(); - bool preventInUseConnect(); - const QFont get_font(); + int write_dir(const char *buf); + void write_dir(int conn, const char *buf); + void getDirResName(QString &); + void setDirRes(DIRRES *dir); void writeSettings(); void readSettings(); - char *msg(); - bool notify(bool enable); // enables/disables socket notification - returns the previous state - bool is_notify_enabled() const; - QStringList get_list(char *cmd); - bool get_job_defaults(struct job_defaults &); - void terminate(); - void beginNewCommand(); - void displayToPrompt(); - void discardToPrompt(); void setDirectorTreeItem(QTreeWidgetItem *); - void setDirRes(DIRRES *dir); + void terminate(); + bool is_messagesPending() { return m_messages_pending; }; + bool is_connected(); + bool is_connected(int conn); QTreeWidgetItem *directorTreeItem() { return m_directorTreeItem; }; - void getDirResName(QString &); void startTimer(); - void stopTimer(); + void display_text(const char *buf); + void display_text(const QString buf); + void display_textf(const char *fmt, ...); + void display_html(const QString buf); + bool get_job_defaults(struct job_defaults &); + const QFont get_font(); + void beginNewCommand(int conn); void getVolumeList(QStringList &); void getStatusList(QStringList &); - bool is_messagesPending() { return m_messages_pending; }; +private: + void update_cursor(void); + void stopTimer(); + bool is_connectedGui(); + int newDirComm(); + +public: QStringList job_list; QStringList client_list; QStringList fileset_list; @@ -118,13 +126,8 @@ public: QStringList type_list; QStringList level_list; - public slots: void connect_dir(); - void read_dir(int fd); - int read(void); - int write(const char *msg); - int write(QString msg); void status_dir(void); void messages(void); void set_font(void); @@ -137,17 +140,14 @@ public: private: QTextEdit *m_textEdit; - BSOCK *m_sock; - bool m_at_prompt; - bool m_at_main_prompt; - QSocketNotifier *m_notifier; QTextCursor *m_cursor; QTreeWidgetItem *m_directorTreeItem; - bool m_api_set; bool m_messages_pending; QTimer *m_timer; - bool hasFocus(); bool messagesPending(bool pend); + bool hasFocus(); + QHash m_dircommHash; + int m_dircommCounter; }; #endif /* _CONSOLE_H_ */ diff --git a/bacula/src/qt-console/fileset/fileset.cpp b/bacula/src/qt-console/fileset/fileset.cpp index 60d878f160..cbf3acaf78 100644 --- a/bacula/src/qt-console/fileset/fileset.cpp +++ b/bacula/src/qt-console/fileset/fileset.cpp @@ -71,8 +71,6 @@ FileSet::~FileSet() */ void FileSet::populateTable() { - if (!m_console->preventInUseConnect()) - return; m_populated = true; Freeze frz(*tableWidget); /* disable updating*/ diff --git a/bacula/src/qt-console/joblist/joblist.cpp b/bacula/src/qt-console/joblist/joblist.cpp index 532507e5af..5b9d48906b 100644 --- a/bacula/src/qt-console/joblist/joblist.cpp +++ b/bacula/src/qt-console/joblist/joblist.cpp @@ -108,9 +108,6 @@ JobList::~JobList() */ void JobList::populateTable() { - if (!m_console->preventInUseConnect()) - return; - /* Can't do this in constructor because not neccesarily conected in constructor */ prepareFilterWidgets(); m_populated = true; diff --git a/bacula/src/qt-console/joblog/joblog.cpp b/bacula/src/qt-console/joblog/joblog.cpp index 566f8f997b..c366cb7e34 100644 --- a/bacula/src/qt-console/joblog/joblog.cpp +++ b/bacula/src/qt-console/joblog/joblog.cpp @@ -75,9 +75,6 @@ void JobLog::getFont() */ void JobLog::populateText() { - if (!m_console->preventInUseConnect()) - return; - QString query; query = "SELECT Time, LogText FROM Log WHERE JobId='" + m_jobId + "' order by Time"; diff --git a/bacula/src/qt-console/jobs/jobs.cpp b/bacula/src/qt-console/jobs/jobs.cpp index e7a30f908b..f79e960cae 100644 --- a/bacula/src/qt-console/jobs/jobs.cpp +++ b/bacula/src/qt-console/jobs/jobs.cpp @@ -69,8 +69,6 @@ Jobs::~Jobs() */ void Jobs::populateTable() { - if (!m_console->preventInUseConnect()) - return; m_populated = true; Freeze frz(*tableWidget); /* disable updating*/ diff --git a/bacula/src/qt-console/label/label.cpp b/bacula/src/qt-console/label/label.cpp index c6a8b5a789..446da44e4f 100644 --- a/bacula/src/qt-console/label/label.cpp +++ b/bacula/src/qt-console/label/label.cpp @@ -62,7 +62,7 @@ void labelPage::showPage(QString &defString) m_name = "Label"; pgInitialize(); setupUi(this); - m_console->notify(false); + m_conn = m_console->notifyOff(); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/label.png"))); @@ -100,8 +100,8 @@ void labelPage::okButtonPushed() Pmsg1(000, "sending command : %s\n",scmd.toUtf8().data()); } m_console->write_dir(scmd.toUtf8().data()); - m_console->displayToPrompt(); - m_console->notify(true); + m_console->displayToPrompt(m_conn); + m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } @@ -109,7 +109,7 @@ void labelPage::okButtonPushed() void labelPage::cancelButtonPushed() { this->hide(); - m_console->notify(true); + m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } diff --git a/bacula/src/qt-console/label/label.h b/bacula/src/qt-console/label/label.h index 03bd669796..103bfc5264 100644 --- a/bacula/src/qt-console/label/label.h +++ b/bacula/src/qt-console/label/label.h @@ -53,6 +53,7 @@ private slots: void automountOffButtonPushed(); private: + int m_conn; }; #endif /* _LABEL_H_ */ diff --git a/bacula/src/qt-console/main.cpp b/bacula/src/qt-console/main.cpp index ab99bace1b..861a4619cd 100644 --- a/bacula/src/qt-console/main.cpp +++ b/bacula/src/qt-console/main.cpp @@ -183,28 +183,6 @@ PROG_COPYRIGHT exit(1); } -#ifdef xxx -/* - * Call-back for reading a passphrase for an encrypted PEM file - * This function uses getpass(), which uses a static buffer and is NOT thread-safe. - */ -static int tls_pem_callback(char *buf, int size, const void *userdata) -{ -#ifdef HAVE_TLS - const char *prompt = (const char *) userdata; - char *passwd; - - passwd = getpass(prompt); - bstrncpy(buf, passwd, size); - return (strlen(buf)); -#else - buf[0] = 0; - return 0; -#endif -} -#endif - - /* * Make a quick check to see that we have all the * resources needed. diff --git a/bacula/src/qt-console/mainwin.cpp b/bacula/src/qt-console/mainwin.cpp index 3e3567bd3d..1b2a9a0142 100644 --- a/bacula/src/qt-console/mainwin.cpp +++ b/bacula/src/qt-console/mainwin.cpp @@ -651,6 +651,7 @@ void MainWin::setPreferences() { prefsDialog prefs; prefs.commDebug->setCheckState(m_commDebug ? Qt::Checked : Qt::Unchecked); + prefs.connDebug->setCheckState(m_connDebug ? Qt::Checked : Qt::Unchecked); prefs.displayAll->setCheckState(m_displayAll ? Qt::Checked : Qt::Unchecked); prefs.sqlDebug->setCheckState(m_sqlDebug ? Qt::Checked : Qt::Unchecked); prefs.commandDebug->setCheckState(m_commandDebug ? Qt::Checked : Qt::Unchecked); @@ -706,6 +707,7 @@ void prefsDialog::accept() { this->hide(); mainWin->m_commDebug = this->commDebug->checkState() == Qt::Checked; + mainWin->m_connDebug = this->connDebug->checkState() == Qt::Checked; mainWin->m_displayAll = this->displayAll->checkState() == Qt::Checked; mainWin->m_sqlDebug = this->sqlDebug->checkState() == Qt::Checked; mainWin->m_commandDebug = this->commandDebug->checkState() == Qt::Checked; @@ -746,6 +748,7 @@ void prefsDialog::accept() QSettings settings("www.bacula.org", "bat"); settings.beginGroup("Debug"); settings.setValue("commDebug", mainWin->m_commDebug); + settings.setValue("connDebug", mainWin->m_connDebug); settings.setValue("displayAll", mainWin->m_displayAll); settings.setValue("sqlDebug", mainWin->m_sqlDebug); settings.setValue("commandDebug", mainWin->m_commandDebug); @@ -784,9 +787,6 @@ void prefsDialog::accept() settings.setValue("rtRestore2Debug", mainWin->m_rtRestore2Debug); settings.setValue("rtRestore3Debug", mainWin->m_rtRestore3Debug); settings.endGroup(); - foreach(Console *console, mainWin->m_consoleHash) { - console->startTimer(); - } } void prefsDialog::reject() @@ -801,6 +801,7 @@ void MainWin::readPreferences() QSettings settings("www.bacula.org", "bat"); settings.beginGroup("Debug"); m_commDebug = settings.value("commDebug", false).toBool(); + m_connDebug = settings.value("connDebug", false).toBool(); m_displayAll = settings.value("displayAll", false).toBool(); m_sqlDebug = settings.value("sqlDebug", false).toBool(); m_commandDebug = settings.value("commandDebug", false).toBool(); diff --git a/bacula/src/qt-console/mainwin.h b/bacula/src/qt-console/mainwin.h index 09c10591d4..87b49c4cba 100644 --- a/bacula/src/qt-console/mainwin.h +++ b/bacula/src/qt-console/mainwin.h @@ -75,6 +75,7 @@ public: QString m_dtformat; /* Begin Preferences variables */ bool m_commDebug; + bool m_connDebug; bool m_displayAll; bool m_sqlDebug; bool m_commandDebug; diff --git a/bacula/src/qt-console/mediaedit/mediaedit.cpp b/bacula/src/qt-console/mediaedit/mediaedit.cpp index a1ff69eadc..fc53d81d01 100644 --- a/bacula/src/qt-console/mediaedit/mediaedit.cpp +++ b/bacula/src/qt-console/mediaedit/mediaedit.cpp @@ -63,9 +63,6 @@ MediaEdit::MediaEdit(QTreeWidgetItem *parentWidget, QString &mediaId) m_status = ""; m_slot = 0; - if (!m_console->preventInUseConnect()) - return; - /* The media's pool */ poolCombo->addItems(m_console->pool_list); diff --git a/bacula/src/qt-console/medialist/medialist.cpp b/bacula/src/qt-console/medialist/medialist.cpp index 9189f1fcbe..07df54bfd0 100644 --- a/bacula/src/qt-console/medialist/medialist.cpp +++ b/bacula/src/qt-console/medialist/medialist.cpp @@ -80,9 +80,6 @@ void MediaList::populateTree() writeExpandedSettings(); m_populated = true; - if (!m_console->preventInUseConnect()) - return; - Freeze frz(*mp_treeWidget); /* disable updating*/ QStringList headerlist = (QStringList() diff --git a/bacula/src/qt-console/mount/mount.cpp b/bacula/src/qt-console/mount/mount.cpp index 905b954cc6..3f7ec7dda8 100644 --- a/bacula/src/qt-console/mount/mount.cpp +++ b/bacula/src/qt-console/mount/mount.cpp @@ -44,7 +44,7 @@ mountDialog::mountDialog(Console *console, QString &storageName) { m_console = console; m_storageName = storageName; - m_console->notify(false); + m_conn = m_console->notifyOff(); setupUi(this); this->show(); @@ -74,8 +74,8 @@ void mountDialog::accept() m_console->display_text(tr("Director Response :\n\n")); m_console->write_dir(scmd.toUtf8().data()); - m_console->displayToPrompt(); - m_console->notify(true); + m_console->displayToPrompt(m_conn); + m_console->notify(m_conn, true); delete this; mainWin->resetFocus(); } @@ -83,7 +83,7 @@ void mountDialog::accept() void mountDialog::reject() { this->hide(); - m_console->notify(true); + m_console->notify(m_conn, true); delete this; mainWin->resetFocus(); } diff --git a/bacula/src/qt-console/mount/mount.h b/bacula/src/qt-console/mount/mount.h index 575de0b40d..dd8817b8e2 100644 --- a/bacula/src/qt-console/mount/mount.h +++ b/bacula/src/qt-console/mount/mount.h @@ -50,6 +50,7 @@ private slots: private: Console *m_console; QString m_storageName; + int m_conn; }; #endif /* _MOUNT_H_ */ diff --git a/bacula/src/qt-console/pages.cpp b/bacula/src/qt-console/pages.cpp index 4dbe17f121..56d237be54 100644 --- a/bacula/src/qt-console/pages.cpp +++ b/bacula/src/qt-console/pages.cpp @@ -230,11 +230,6 @@ void Pages::treeWidgetName(QString &name) */ void Pages::consoleCommand(QString &command) { - /*if (!m_console->is_connectedGui()) - return;*/ - if (!m_console->preventInUseConnect()) { - return; - } consoleInput(command); } @@ -245,14 +240,15 @@ void Pages::consoleCommand(QString &command) */ void Pages::consoleInput(QString &command) { + int conn; /* Bring this director's console to the front of the stack */ setConsoleCurrent(); QString displayhtml(""); displayhtml += command + "\n"; m_console->display_html(displayhtml); m_console->display_text("\n"); - m_console->write_dir(command.toUtf8().data()); - m_console->displayToPrompt(); + conn = m_console->write_dir(command.toUtf8().data()); + m_console->displayToPrompt(conn); } /* diff --git a/bacula/src/qt-console/prefs.ui b/bacula/src/qt-console/prefs.ui index dbcccc253f..f5f4ddcd8e 100644 --- a/bacula/src/qt-console/prefs.ui +++ b/bacula/src/qt-console/prefs.ui @@ -43,7 +43,7 @@ - 2 + 3 @@ -473,80 +473,47 @@ Debugging Options - - 9 - - - 9 - - - 9 - - - 9 - - - 6 - - - 6 - - - - 0 + + + Debug comm - - 0 + + + + + + Debug multiple connection - - 0 + + + + + + Display all messages in console - - 0 + + + + + + Debug Sql queries - - 6 + + + + + + Debug Commands - - 6 + + + + + + Debug Miscelaneous Items - - - - Debug comm - - - - - - - Display all messages in console - - - - - - - Debug Commands - - - - - - - Debug Sql queries - - - - - - - Debug Miscelaneous Items - - - - + diff --git a/bacula/src/qt-console/relabel/relabel.cpp b/bacula/src/qt-console/relabel/relabel.cpp index 8afc3a8f83..a7aff3381c 100644 --- a/bacula/src/qt-console/relabel/relabel.cpp +++ b/bacula/src/qt-console/relabel/relabel.cpp @@ -45,7 +45,7 @@ relabelDialog::relabelDialog(Console *console, QString &fromVolume) { m_console = console; m_fromVolume = fromVolume; - m_console->notify(false); + m_conn = m_console->notifyOff(); setupUi(this); storageCombo->addItems(console->storage_list); poolCombo->addItems(console->pool_list); @@ -110,8 +110,8 @@ void relabelDialog::accept() Pmsg1(000, "sending command : %s\n",scmd.toUtf8().data()); } m_console->write_dir(scmd.toUtf8().data()); - m_console->displayToPrompt(); - m_console->notify(true); + m_console->displayToPrompt(m_conn); + m_console->notify(m_conn, true); delete this; mainWin->resetFocus(); } @@ -119,7 +119,7 @@ void relabelDialog::accept() void relabelDialog::reject() { this->hide(); - m_console->notify(true); + m_console->notify(m_conn, true); delete this; mainWin->resetFocus(); } diff --git a/bacula/src/qt-console/relabel/relabel.h b/bacula/src/qt-console/relabel/relabel.h index 28dbe421ba..c6d15352d6 100644 --- a/bacula/src/qt-console/relabel/relabel.h +++ b/bacula/src/qt-console/relabel/relabel.h @@ -53,6 +53,7 @@ private slots: private: Console *m_console; QString m_fromVolume; + int m_conn; }; #endif /* _RELABEL_H_ */ diff --git a/bacula/src/qt-console/restore/prerestore.cpp b/bacula/src/qt-console/restore/prerestore.cpp index 4bad5f3f92..88f296b326 100644 --- a/bacula/src/qt-console/restore/prerestore.cpp +++ b/bacula/src/qt-console/restore/prerestore.cpp @@ -62,14 +62,11 @@ void prerestorePage::buildPage() m_name = tr("Restore"); setupUi(this); pgInitialize(); - m_console->notify(false); + m_conn = m_console->notifyOff(); m_closeable = true; QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/restore.png"))); - if (!m_console->preventInUseConnect()) - return; - jobCombo->addItems(m_console->job_list); filesetCombo->addItems(m_console->fileset_list); clientCombo->addItems(m_console->client_list); @@ -170,7 +167,7 @@ void prerestorePage::okButtonPushed() if (mainWin->m_commandDebug) { Pmsg1(000, "preRestore command \'%s\'\n", cmd.toUtf8().data()); } - m_console->write_dir(cmd.toUtf8().data()); + m_console->write_dir(m_conn, cmd.toUtf8().data()); /* Note, do not turn notifier back on here ... */ if (selectFilesRadio->isChecked()) { @@ -180,7 +177,7 @@ void prerestorePage::okButtonPushed() closeStackPage(); mainWin->resetFocus(); } - m_console->notify(true); + m_console->notify(m_conn, true); } @@ -191,7 +188,7 @@ void prerestorePage::cancelButtonPushed() { mainWin->set_status(tr("Canceled")); this->hide(); - m_console->notify(true); + m_console->notify(m_conn, true); closeStackPage(); } diff --git a/bacula/src/qt-console/restore/restore.cpp b/bacula/src/qt-console/restore/restore.cpp index 2c7da9940f..e743a80621 100644 --- a/bacula/src/qt-console/restore/restore.cpp +++ b/bacula/src/qt-console/restore/restore.cpp @@ -38,8 +38,10 @@ #include "bat.h" #include "restore.h" -restorePage::restorePage() +restorePage::restorePage(int conn) { + Pmsg1(000, "Construcing restorePage Instance connection %i\n", conn); + m_conn = conn; QStringList titles; setupUi(this); @@ -48,7 +50,7 @@ restorePage::restorePage() QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/restore.png"))); - m_console->notify(false); /* this should already be off */ + m_console->notify(m_conn, false); /* this should already be off */ m_closeable = true; connect(fileWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), @@ -69,7 +71,7 @@ restorePage::restorePage() connect(actionUnMark, SIGNAL(triggered()), this, SLOT(unmarkButtonPushed())); setFont(m_console->get_font()); - m_console->displayToPrompt(); + m_console->displayToPrompt(m_conn); titles << tr("Mark") << tr("File") << tr("Mode") << tr("User") << tr("Group") << tr("Size") << tr("Date"); @@ -101,11 +103,11 @@ void restorePage::fillDirectory() POOLMEM *path = get_pool_memory(PM_FNAME); fileWidget->clear(); - m_console->write_dir("dir"); + m_console->write_dir(m_conn, "dir"); QList treeItemList; QStringList item; - while (m_console->read() > 0) { - char *p = m_console->msg(); + while (m_console->read(m_conn) > 0) { + char *p = m_console->msg(m_conn); char *l; strip_trailing_junk(p); if (*p == '$' || !*p) { @@ -289,8 +291,8 @@ void restorePage::okButtonPushed() { // printf("In restorePage::okButtonPushed\n"); this->hide(); - m_console->write("done"); - m_console->notify(true); + m_console->write(m_conn, "done"); + m_console->notify(m_conn, true); setConsoleCurrent(); closeStackPage(); mainWin->resetFocus(); @@ -300,11 +302,11 @@ void restorePage::okButtonPushed() void restorePage::cancelButtonPushed() { this->hide(); - m_console->write("quit"); - m_console->displayToPrompt(); + m_console->write(m_conn, "quit"); + m_console->displayToPrompt(m_conn); mainWin->set_status(tr("Canceled")); closeStackPage(); - m_console->notify(true); + m_console->notify(m_conn, true); mainWin->resetFocus(); } @@ -322,12 +324,12 @@ void restorePage::fileDoubleClicked(QTreeWidgetItem *item, int column) item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png"))); item->setData(0, Qt::UserRole, true); } - m_console->write_dir(cmd); - if (m_console->read() > 0) { - strip_trailing_junk(m_console->msg()); - statusLine->setText(m_console->msg()); + m_console->write_dir(m_conn, cmd); + if (m_console->read(m_conn) > 0) { + strip_trailing_junk(m_console->msg(m_conn)); + statusLine->setText(m_console->msg(m_conn)); } - m_console->displayToPrompt(); + m_console->displayToPrompt(m_conn); return; } /* @@ -376,13 +378,13 @@ void restorePage::markButtonPushed() count++; bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data()); item->setIcon(0, QIcon(QString::fromUtf8(":images/check.png"))); - m_console->write_dir(cmd); - if (m_console->read() > 0) { - strip_trailing_junk(m_console->msg()); - statusLine->setText(m_console->msg()); + m_console->write_dir(m_conn, cmd); + if (m_console->read(m_conn) > 0) { + strip_trailing_junk(m_console->msg(m_conn)); + statusLine->setText(m_console->msg(m_conn)); } Dmsg1(100, "cmd=%s\n", cmd); - m_console->discardToPrompt(); + m_console->discardToPrompt(m_conn); } if (count == 0) { mainWin->set_status("Nothing selected, nothing done"); @@ -405,13 +407,13 @@ void restorePage::unmarkButtonPushed() count++; bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data()); item->setIcon(0, QIcon(QString::fromUtf8(":images/unchecked.png"))); - m_console->write_dir(cmd); - if (m_console->read() > 0) { - strip_trailing_junk(m_console->msg()); - statusLine->setText(m_console->msg()); + m_console->write_dir(m_conn, cmd); + if (m_console->read(m_conn) > 0) { + strip_trailing_junk(m_console->msg(m_conn)); + statusLine->setText(m_console->msg(m_conn)); } Dmsg1(100, "cmd=%s\n", cmd); - m_console->discardToPrompt(); + m_console->discardToPrompt(m_conn); } if (count == 0) { mainWin->set_status(tr("Nothing selected, nothing done")); @@ -431,17 +433,17 @@ bool restorePage::cwd(const char *dir) statusLine->setText(""); bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir); Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd); - m_console->write_dir(cd_cmd); + m_console->write_dir(m_conn, cd_cmd); lineEdit->clear(); - if ((stat = m_console->read()) > 0) { - m_cwd = m_console->msg(); + if ((stat = m_console->read(m_conn)) > 0) { + m_cwd = m_console->msg(m_conn); lineEdit->insert(m_cwd); - Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg()); + Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg(m_conn)); } else { Dmsg1(000, "stat=%d\n", stat); QMessageBox::critical(this, "Error", tr("cd command failed"), QMessageBox::Ok); } - m_console->discardToPrompt(); + m_console->discardToPrompt(m_conn); return true; /* ***FIXME*** return real status */ } @@ -451,16 +453,16 @@ bool restorePage::cwd(const char *dir) char *restorePage::get_cwd() { int stat; - m_console->write_dir(".pwd"); + m_console->write_dir(m_conn, ".pwd"); Dmsg0(100, "send: .pwd\n"); - if ((stat = m_console->read()) > 0) { - m_cwd = m_console->msg(); - Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg()); + if ((stat = m_console->read(m_conn)) > 0) { + m_cwd = m_console->msg(m_conn); + Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg(m_conn)); } else { Dmsg1(000, "Something went wrong read stat=%d\n", stat); QMessageBox::critical(this, "Error", tr(".pwd command failed"), QMessageBox::Ok); } - m_console->discardToPrompt(); + m_console->discardToPrompt(m_conn); return m_cwd.toUtf8().data(); } diff --git a/bacula/src/qt-console/restore/restore.h b/bacula/src/qt-console/restore/restore.h index bfb83659ba..355f118711 100644 --- a/bacula/src/qt-console/restore/restore.h +++ b/bacula/src/qt-console/restore/restore.h @@ -68,6 +68,7 @@ private slots: void jobIdEditFinished(); private: + int m_conn; int jobdefsFromJob(QStringList &, QString &); void buildPage(); bool checkJobIdList(); @@ -85,7 +86,7 @@ class restorePage : public Pages, public Ui::restoreForm Q_OBJECT public: - restorePage(); + restorePage(int conn); ~restorePage(); void fillDirectory(); char *get_cwd(); @@ -102,6 +103,7 @@ private slots: void addDirectory(QString &); private: + int m_conn; void writeSettings(); void readSettings(); QString m_cwd; diff --git a/bacula/src/qt-console/restore/restoretree.cpp b/bacula/src/qt-console/restore/restoretree.cpp index 8ebbc9563d..37a78a1f48 100644 --- a/bacula/src/qt-console/restore/restoretree.cpp +++ b/bacula/src/qt-console/restore/restoretree.cpp @@ -460,8 +460,6 @@ bool restoreTree::addDirectory(QString &m_cwd, QString &newdirr) void restoreTree::currentStackItem() { if(!m_populated) { - if (!m_console->preventInUseConnect()) - return; setupPage(); m_populated = true; } diff --git a/bacula/src/qt-console/run/estimate.cpp b/bacula/src/qt-console/run/estimate.cpp index 28f8ddf189..4d900faa9c 100644 --- a/bacula/src/qt-console/run/estimate.cpp +++ b/bacula/src/qt-console/run/estimate.cpp @@ -47,9 +47,9 @@ estimatePage::estimatePage() m_name = tr("Estimate"); pgInitialize(); setupUi(this); - m_console->notify(false); + m_conn = m_console->notifyOff(); - m_console->beginNewCommand(); + m_console->beginNewCommand(m_conn); jobCombo->addItems(m_console->job_list); filesetCombo->addItems(m_console->fileset_list); levelCombo->addItems(m_console->level_list); @@ -84,7 +84,7 @@ void estimatePage::okButtonPushed() } consoleCommand(cmd); - m_console->notify(true); + m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } @@ -94,7 +94,7 @@ void estimatePage::cancelButtonPushed() { mainWin->set_status(" Canceled"); this->hide(); - m_console->notify(true); + m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } diff --git a/bacula/src/qt-console/run/prune.cpp b/bacula/src/qt-console/run/prune.cpp index cf6c4b71a1..0118e65202 100644 --- a/bacula/src/qt-console/run/prune.cpp +++ b/bacula/src/qt-console/run/prune.cpp @@ -47,7 +47,7 @@ prunePage::prunePage(const QString &volume, const QString &client) m_name = tr("Prune"); pgInitialize(); setupUi(this); - m_console->notify(false); + m_conn = m_console->notifyOff(); QString query("SELECT VolumeName AS Media FROM Media ORDER BY Media"); if (mainWin->m_sqlDebug) { @@ -113,7 +113,7 @@ void prunePage::okButtonPushed() } consoleCommand(cmd); - m_console->notify(true); + m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } @@ -123,7 +123,7 @@ void prunePage::cancelButtonPushed() { mainWin->set_status(tr(" Canceled")); this->hide(); - m_console->notify(true); + m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } diff --git a/bacula/src/qt-console/run/run.cpp b/bacula/src/qt-console/run/run.cpp index 7d32c50a4a..5381db1fed 100644 --- a/bacula/src/qt-console/run/run.cpp +++ b/bacula/src/qt-console/run/run.cpp @@ -49,9 +49,9 @@ runPage::runPage(const QString &defJob) setupUi(this); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/run.png"))); - m_console->notify(false); + m_conn = m_console->notifyOff(); - m_console->beginNewCommand(); + m_console->beginNewCommand(m_conn); jobCombo->addItems(m_console->job_list); filesetCombo->addItems(m_console->fileset_list); levelCombo->addItems(m_console->level_list); @@ -106,7 +106,7 @@ void runPage::okButtonPushed() } consoleCommand(cmd); - m_console->notify(true); + m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } @@ -116,7 +116,7 @@ void runPage::cancelButtonPushed() { mainWin->set_status(tr(" Canceled")); this->hide(); - m_console->notify(true); + m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } diff --git a/bacula/src/qt-console/run/run.h b/bacula/src/qt-console/run/run.h index ac949c0400..40e1728940 100644 --- a/bacula/src/qt-console/run/run.h +++ b/bacula/src/qt-console/run/run.h @@ -22,6 +22,7 @@ public slots: void job_name_change(int index); private: + int m_conn; }; class runCmdPage : public Pages, public Ui::runCmdForm @@ -37,6 +38,7 @@ public slots: private: void fill(); + int m_conn; }; class estimatePage : public Pages, public Ui::estimateForm @@ -52,6 +54,7 @@ public slots: void job_name_change(int index); private: + int m_conn; }; class prunePage : public Pages, public Ui::pruneForm @@ -68,6 +71,7 @@ public slots: void clientChanged(); private: + int m_conn; }; #endif /* _RUN_H_ */ diff --git a/bacula/src/qt-console/run/runcmd.cpp b/bacula/src/qt-console/run/runcmd.cpp index 587ee053c1..ce1f7d5820 100644 --- a/bacula/src/qt-console/run/runcmd.cpp +++ b/bacula/src/qt-console/run/runcmd.cpp @@ -53,10 +53,10 @@ runCmdPage::runCmdPage() setupUi(this); QTreeWidgetItem* thisitem = mainWin->getFromHash(this); thisitem->setIcon(0,QIcon(QString::fromUtf8(":images/restore.png"))); - m_console->notify(false); + m_conn = m_console->notifyOff(); fill(); - m_console->discardToPrompt(); + m_console->discardToPrompt(m_conn); connect(okButton, SIGNAL(pressed()), this, SLOT(okButtonPushed())); connect(cancelButton, SIGNAL(pressed()), this, SLOT(cancelButtonPushed())); @@ -80,8 +80,8 @@ void runCmdPage::fill() storageCombo->addItems(m_console->storage_list); dateTimeEdit->setDisplayFormat(mainWin->m_dtformat); - m_console->read(); - item = m_console->msg(); + m_console->read(m_conn); + item = m_console->msg(m_conn); items = item.split("\n"); label->setText(items[0]); Dmsg1(200, "Title=%s\n", items[0].toUtf8().data()); @@ -161,22 +161,22 @@ void runCmdPage::okButtonPushed() m_console->display_html(displayhtml); m_console->display_text("\n"); m_console->write_dir(cmd.toUtf8().data()); - m_console->displayToPrompt(); + m_console->displayToPrompt(m_conn); // consoleCommand(cmd); ***FIXME set back to consoleCommand when connection issue is resolved - m_console->notify(true); + m_console->notify(m_conn, true); closeStackPage(); } void runCmdPage::cancelButtonPushed() { - m_console->displayToPrompt(); + m_console->displayToPrompt(m_conn); m_console->write_dir("."); - m_console->displayToPrompt(); + m_console->displayToPrompt(m_conn); mainWin->set_status(tr(" Canceled")); this->hide(); - m_console->notify(true); + m_console->notify(m_conn, true); closeStackPage(); mainWin->resetFocus(); } diff --git a/bacula/src/qt-console/select/select.cpp b/bacula/src/qt-console/select/select.cpp index ee36f8d061..7c12d342a0 100644 --- a/bacula/src/qt-console/select/select.cpp +++ b/bacula/src/qt-console/select/select.cpp @@ -51,14 +51,15 @@ selectDialog::selectDialog(Console *console) setupUi(this); connect(listBox, SIGNAL(currentRowChanged(int)), this, SLOT(index_change(int))); setAttribute(Qt::WA_DeleteOnClose); - m_console->read(); /* get title */ - labelWidget->setText(m_console->msg()); - while ((stat=m_console->read()) > 0) { + m_conn = m_console->notifyOff(); + m_console->read(m_conn); /* get title */ + labelWidget->setText(m_console->msg(m_conn)); + while ((stat=m_console->read(m_conn)) > 0) { item = new QListWidgetItem; - item->setText(m_console->msg()); + item->setText(m_console->msg(m_conn)); listBox->insertItem(row++, item); } - m_console->displayToPrompt(); + m_console->displayToPrompt(m_conn); this->show(); } @@ -69,10 +70,10 @@ void selectDialog::accept() this->hide(); bsnprintf(cmd, sizeof(cmd), "%d", m_index+1); m_console->write_dir(cmd); - m_console->displayToPrompt(); + m_console->displayToPrompt(m_conn); this->close(); mainWin->resetFocus(); - m_console->displayToPrompt(); + m_console->displayToPrompt(m_conn); } @@ -83,7 +84,7 @@ void selectDialog::reject() mainWin->set_status(tr(" Canceled")); this->close(); mainWin->resetFocus(); - m_console->beginNewCommand(); + m_console->beginNewCommand(m_conn); } /* @@ -102,16 +103,16 @@ void selectDialog::index_change(int index) /* * Read the items for the selection */ -yesnoPopUp::yesnoPopUp(Console *console) +yesnoPopUp::yesnoPopUp(Console *console, int conn) { QMessageBox msgBox; setAttribute(Qt::WA_DeleteOnClose); - console->read(); /* get yesno question */ + console->read(conn); /* get yesno question */ msgBox.setWindowTitle(tr("Bat Question")); - msgBox.setText(console->msg()); + msgBox.setText(console->msg(conn)); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); - console->displayToPrompt(); + console->displayToPrompt(conn); switch (msgBox.exec()) { case QMessageBox::Yes: console->write_dir("yes"); @@ -120,6 +121,6 @@ yesnoPopUp::yesnoPopUp(Console *console) console->write_dir("no"); break; } - console->displayToPrompt(); + console->displayToPrompt(conn); mainWin->resetFocus(); } diff --git a/bacula/src/qt-console/select/select.h b/bacula/src/qt-console/select/select.h index ae546a8888..21be1b1518 100644 --- a/bacula/src/qt-console/select/select.h +++ b/bacula/src/qt-console/select/select.h @@ -21,7 +21,7 @@ public slots: private: Console *m_console; int m_index; - + int m_conn; }; class yesnoPopUp : public QDialog @@ -29,7 +29,7 @@ class yesnoPopUp : public QDialog Q_OBJECT public: - yesnoPopUp(Console *console); + yesnoPopUp(Console *console, int conn); }; diff --git a/bacula/src/qt-console/status/clientstat.cpp b/bacula/src/qt-console/status/clientstat.cpp index e722552895..bc23cc47f0 100644 --- a/bacula/src/qt-console/status/clientstat.cpp +++ b/bacula/src/qt-console/status/clientstat.cpp @@ -87,8 +87,6 @@ ClientStat::~ClientStat() */ void ClientStat::populateAll() { - if (!m_console->preventInUseConnect()) - return; populateHeader(); populateTerminated(); populateRunning(); @@ -101,8 +99,7 @@ void ClientStat::timerTriggered() { bool iscurrent = mainWin->stackedWidget->currentIndex() == mainWin->stackedWidget->indexOf(this); if (((isDocked() && iscurrent) || (!isDocked())) && mainWin->m_refreshStatusDir) { - if (m_console->is_ready()) - populateAll(); + populateAll(); } } diff --git a/bacula/src/qt-console/status/dirstat.cpp b/bacula/src/qt-console/status/dirstat.cpp index 573ed304ae..305ddda284 100644 --- a/bacula/src/qt-console/status/dirstat.cpp +++ b/bacula/src/qt-console/status/dirstat.cpp @@ -87,8 +87,6 @@ DirStat::~DirStat() */ void DirStat::populateAll() { - if (!m_console->preventInUseConnect()) - return; populateHeader(); populateTerminated(); populateScheduled(); @@ -102,8 +100,7 @@ void DirStat::timerTriggered() { bool iscurrent = mainWin->stackedWidget->currentIndex() == mainWin->stackedWidget->indexOf(this); if (((isDocked() && iscurrent) || (!isDocked())) && mainWin->m_refreshStatusDir) { - if (m_console->is_ready()) - populateAll(); + populateAll(); } } diff --git a/bacula/src/qt-console/status/storstat.cpp b/bacula/src/qt-console/status/storstat.cpp index f67a131cab..ff842710f3 100644 --- a/bacula/src/qt-console/status/storstat.cpp +++ b/bacula/src/qt-console/status/storstat.cpp @@ -101,8 +101,6 @@ StorStat::~StorStat() */ void StorStat::populateAll() { - if (!m_console->preventInUseConnect()) - return; populateTerminated(); populateCurrentTab(tabWidget->currentIndex()); } @@ -114,8 +112,7 @@ void StorStat::timerTriggered() { bool iscurrent = mainWin->stackedWidget->currentIndex() == mainWin->stackedWidget->indexOf(this); if (((isDocked() && iscurrent) || (!isDocked())) && (checkBox->checkState() == Qt::Checked)) { - if (m_console->is_ready()) - populateAll(); + populateAll(); } } diff --git a/bacula/src/qt-console/storage/storage.cpp b/bacula/src/qt-console/storage/storage.cpp index 40b3b8cdb2..37a354832e 100644 --- a/bacula/src/qt-console/storage/storage.cpp +++ b/bacula/src/qt-console/storage/storage.cpp @@ -74,9 +74,6 @@ Storage::~Storage() */ void Storage::populateTree() { - if (!m_console->preventInUseConnect()) - return; - if (m_populated) writeExpandedSettings(); m_populated = true; -- 2.39.5