/*
Bacula® - The Network Backup Solution
- Copyright (C) 2007-2007 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 two of the GNU 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 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 John Walker.
- The licensor of Bacula is the Free Software Foundation Europe
- (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
- Switzerland, email:ftf@fsfeurope.org.
+ Copyright (C) 2007-2011 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.
+
+ You may use this file and others of this release according to the
+ license defined in the LICENSE file, which includes the Affero General
+ Public License, v3.0 ("AGPLv3") and some additional permissions and
+ terms pursuant to its AGPLv3 Section 7.
+
+ Bacula® is a registered trademark of Kern Sibbald.
*/
/*
- * Version $Id$
+ * DirComm, Director communications,class
*
- * Bacula Communications class that is at a higher level than BSOCK
+ * Kern Sibbald, January MMVII
*
- * Kern Sibbald, May MMVII
- *
- */
+ */
#include "bat.h"
#include "console.h"
#include "restore.h"
#include "select.h"
+#include "textinput.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_sent_blank = false;
+ m_conn = conn;
+ m_in_command = 0;
+ m_in_select = false;
+ m_notify = false;
}
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();
- m_sock->close();
- m_sock = NULL;
+ if (m_notifier) {
+ m_notifier->setEnabled(false);
+ delete m_notifier;
+ m_notifier = NULL;
+ m_notify = false;
+ }
+ if (mainWin->m_connDebug)
+ Pmsg2(000, "DirComm %i terminating connections %s\n", m_conn, m_console->m_dir->name());
+ free_bsock(m_sock);
}
}
/*
- * Connect to Director.
+ * 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;
+ int numcon = 0;
+ int i = 0;
- m_dir = dir;
- if (!m_dir) {
- mainWin->set_status( tr("No Director found.") );
- return;
+ buf[0] = 0;
+
+ foreach_res(cons, R_CONSOLE) {
+ numcon++;
}
- if (m_sock) {
- mainWin->set_status( tr("Already connected.") );
- return;
+
+ if (m_sock && !is_bsock_open(m_sock)) {
+ mainWin->set_status( tr("Already connected."));
+ m_console->display_textf(_("Already connected\"%s\".\n"),
+ m_console->m_dir->name());
+ if (mainWin->m_connDebug) {
+ Pmsg2(000, "DirComm %i BAILING already connected %s\n", m_conn, m_console->m_dir->name());
+ }
+ goto bail_out;
}
- memset(&jcr, 0, sizeof(jcr));
+ if (mainWin->m_connDebug)Pmsg2(000, "DirComm %i connecting %s\n", m_conn, m_console->m_dir->name());
+ 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);
+ if (m_conn == 0) {
+ 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 */
+ for (i=0; i<numcon; i++) {
+ cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)cons);
+ if (cons->director && strcasecmp(cons->director, m_console->m_dir->name()) == 0) {
+ break;
+ }
+ if (i == (numcon - 1)) {
+ cons = NULL;
+ }
+ }
+
+ /* Look for the first non-linked console */
+ if (cons == NULL) {
+ for (i=0; i<numcon; i++) {
+ cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)cons);
+ if (cons->director == NULL) {
+ break;
+ }
+ if (i == (numcon - 1)) {
+ cons = NULL;
+ }
+ }
+ }
+
+ /* If no console, take first one */
+ if (!cons) {
+ cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)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: ",
+ 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
+ * 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,
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) {
+ Pmsg2(000, "DirComm %i BAILING Failed to initialize TLS context for Console %s\n", m_conn, m_console->m_dir->name());
+ }
+ 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());
+ bsnprintf(buf, sizeof(buf), "Passphrase for Director \"%s\" TLS private key: ",
+ 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) {
+ Pmsg2(000, "DirComm %i BAILING Failed to initialize TLS context for Director %s\n", m_conn, m_console->m_dir->name());
+ }
+ 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 {
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) {
+ m_sock = new_bsock();
+ }
+ if (!m_sock->connect(NULL, 5, 15, heart_beat,
+ _("Director daemon"), m_console->m_dir->address,
+ NULL, m_console->m_dir->DIRport, 0)) {
+ m_sock->destroy();
+ m_sock = NULL;
+ }
if (m_sock == NULL) {
- mainWin->set_status( tr("Connection failed") );
- return;
+ mainWin->set_status("Connection failed");
+ if (mainWin->m_connDebug) {
+ Pmsg2(000, "DirComm %i BAILING Connection failed %s\n", m_conn, m_console->m_dir->name());
+ }
+ 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);
+ QTreeWidgetItem *item = mainWin->getFromHash(m_console);
+ if (item) {
+ 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) {
+ Pmsg2(000, "DirComm %i BAILING Connection failed %s\n", m_conn, m_console->m_dir->name());
+ }
+ goto bail_out;
}
+
if (buf[0]) {
m_console->display_text(buf);
}
mainWin->set_status(_("Initializing ..."));
- /* Set up input notifier */
+ /*
+ * 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)));
-
- mainWin->set_status(_("Connected"));
- startTimer(); /* start message timer */
- return;
-}
-
-bool DirComm::dir_cmd(QString &cmd, QStringList &results)
-{
- return dir_cmd(cmd.toUtf8().data(), results);
-}
+ QObject::connect(m_notifier, SIGNAL(activated(int)), this, SLOT(notify_read_dir(int)));
+ m_notifier->setEnabled(true);
+ m_notify = true;
-/*
- * Send a command to the Director, and return the
- * results in a QStringList.
- */
-bool DirComm::dir_cmd(const char *cmd, QStringList &results)
-{
- int stat;
+ write(".api 1");
+ m_api_set = true;
+ m_console->displayToPrompt(m_conn);
- 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 */
-}
-
-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) {
+ Pmsg2(000, "Returning TRUE from DirComm->connect_dir : %i %s\n", m_conn, m_console->m_dir->name());
}
+ 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();
+bail_out:
+ if (mainWin->m_connDebug) {
+ Pmsg2(000, "Returning FALSE from DirComm->connect_dir : %i %s\n", m_conn, m_console->m_dir->name());
}
- notify(true);
- discardToPrompt();
- return true; /* ***FIXME*** return any command error */
+ delete jcr;
+ return false;
}
-/*
- * This should be moved into a bSocket class
+/*
+ * This should be moved into a bSocket class
*/
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());
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 suDirCommand
- */
-void DirComm::beginNewCommand()
-{
- 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;
+ if (mainWin->m_commDebug) Pmsg2(000, "conn %i send: %s\n", m_conn, msg);
+ /*
+ * Ensure we send only one blank line. Multiple blank lines are
+ * simply discarded, it keeps the console output looking nicer.
+ */
+ if (m_sock->msglen == 0 || (m_sock->msglen == 1 && *m_sock->msg == '\n')) {
+ if (!m_sent_blank) {
+ m_sent_blank = true;
+ return m_sock->send();
+ } else {
+ return -1; /* discard multiple blanks */
}
}
- m_console->display_text("\n");
-}
-
-void DirComm::displayToPrompt()
-{
- int stat = 0;
- if (mainWin->m_commDebug) Pmsg0(000, "DisplaytoPrompt\n");
- while (!m_at_prompt) {
- if ((stat=read()) > 0) {
- m_console->display_text(msg());
- }
- }
- if (mainWin->m_commDebug) Pmsg1(000, "endDisplaytoPrompt=%d\n", stat);
+ m_sent_blank = false; /* clear flag */
+ return m_sock->send();
}
-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 DirComm::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 DirComm::read()
{
- int stat = 0;
+ int stat = -1;
+
+ if (!m_sock) {
+ return -1;
+ }
while (m_sock) {
for (;;) {
- stat = bnet_wait_data_intr(m_sock, 1);
+ if (!m_sock) break;
+ 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()) {
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i process_events\n", m_conn);
+ m_console->messagesPending(false);
+ m_console->write_dir(m_conn, ".messages", false);
}
}
+ if (!m_sock) {
+ return -1;
+ }
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 (mainWin->m_commDebug) Pmsg2(000, "conn %i got: %s\n", m_conn, m_sock->msg);
if (m_at_prompt) {
m_console->display_text("\n");
m_at_prompt = false;
}
switch (m_sock->msglen) {
case BNET_MSGS_PENDING :
- if (m_notifier->isEnabled()) {
- if (mainWin->m_commDebug) Pmsg0(000, "MSGS PENDING\n");
- write_dir(".messages");
- displayToPrompt();
- m_messages_pending = false;
+ if (is_notify_enabled() && m_console->hasFocus()) {
+ m_console->messagesPending(false);
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i MSGS PENDING\n", m_conn);
+ m_console->write_dir(m_conn, ".messages", false);
+ m_console->displayToPrompt(m_conn);
+ continue;
}
- m_messages_pending = true;
+ m_console->messagesPending(true);
continue;
case BNET_CMD_OK:
- if (mainWin->m_commDebug) Pmsg0(000, "CMD OK\n");
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i CMD OK\n", m_conn);
m_at_prompt = false;
m_at_main_prompt = false;
+ if (--m_in_command < 0) {
+ m_in_command = 0;
+ }
mainWin->set_status(_("Command completed ..."));
continue;
case BNET_CMD_BEGIN:
- if (mainWin->m_commDebug) Pmsg0(000, "CMD BEGIN\n");
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i CMD BEGIN\n", m_conn);
m_at_prompt = false;
m_at_main_prompt = false;
+ m_in_command++;
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();
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i MAIN PROMPT\n", m_conn);
+ if (!m_at_prompt && ! m_at_main_prompt) {
+ m_at_prompt = true;
+ m_at_main_prompt = true;
+ mainWin->set_status(_("At main prompt waiting for input ..."));
+ }
break;
- case BNET_PROMPT:
- if (mainWin->m_commDebug) Pmsg0(000, "PROMPT\n");
+ case BNET_SUB_PROMPT:
+ if (mainWin->m_commDebug) Pmsg2(000, "conn %i SUB_PROMPT m_in_select=%d\n", m_conn, m_in_select);
m_at_prompt = true;
m_at_main_prompt = false;
mainWin->set_status(_("At prompt waiting for input ..."));
- QApplication::restoreOverrideCursor();
+ break;
+ case BNET_TEXT_INPUT:
+ if (mainWin->m_commDebug) Pmsg4(000, "conn %i TEXT_INPUT at_prompt=%d m_in_select=%d notify=%d\n",
+ m_conn, m_at_prompt, m_in_select, is_notify_enabled());
+ if (!m_in_select && is_notify_enabled()) {
+ new textInputDialog(m_console, m_conn);
+ if (mainWin->m_commDebug) Pmsg0(000, "!m_in_select && is_notify_enabled\n");
+ m_at_prompt = true;
+ m_at_main_prompt = false;
+ mainWin->set_status(_("At prompt waiting for input ..."));
+ }
break;
case BNET_CMD_FAILED:
- if (mainWin->m_commDebug) Pmsg0(000, "CMD FAILED\n");
+ if (mainWin->m_commDebug) Pmsg1(000, "CMD FAILED\n", m_conn);
+ if (--m_in_command < 0) {
+ m_in_command = 0;
+ }
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");
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i EOD\n", m_conn);
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(m_console);
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i START SELECT\n", m_conn);
+ m_in_select = true;
+ new selectDialog(m_console, m_conn);
+ m_in_select = false;
break;
case BNET_YESNO:
- if (mainWin->m_commDebug) Pmsg0(000, "YESNO\n");
- new yesnoPopUp(m_console);
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i YESNO\n", m_conn);
+ new yesnoPopUp(m_console, m_conn);
break;
case BNET_RUN_CMD:
- if (mainWin->m_commDebug) Pmsg0(000, "RUN CMD\n");
- new runCmdPage();
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i RUN CMD\n", m_conn);
+ new runCmdPage(m_conn);
+ break;
+ case BNET_START_RTREE:
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i START RTREE CMD\n", m_conn);
+ new restorePage(m_conn);
+ break;
+ case BNET_END_RTREE:
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i END RTREE CMD\n", m_conn);
break;
case BNET_ERROR_MSG:
- if (mainWin->m_commDebug) Pmsg0(000, "ERROR MSG\n");
- m_sock->recv(); /* get the message */
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i ERROR MSG\n", m_conn);
+ 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);
+ m_console->beginNewCommand(m_conn);
+ mainWin->waitExit();
break;
case BNET_WARNING_MSG:
- if (mainWin->m_commDebug) Pmsg0(000, "WARNING MSG\n");
- m_sock->recv(); /* get the message */
- m_console->display_text(msg());
- QMessageBox::critical(this, "Warning", msg(), QMessageBox::Ok);
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i WARNING MSG\n", m_conn);
+ stat = sock_read(); /* get the message */
+ if (!m_console->m_warningPrevent) {
+ 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 */
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i INFO MSG\n", m_conn);
+ 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_sock->close();
- m_sock = NULL;
+
+ if (!m_sock) {
+ stat = BNET_HARDEOF;
+ return stat;
+ }
+ if (m_sock->is_stop()) { /* error or term request */
+ if (mainWin->m_commDebug) Pmsg1(000, "conn %i BNET STOP\n", m_conn);
+ m_console->stopTimer();
+ free_bsock(m_sock);
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;
+ m_notify = false;
+ }
mainWin->set_status(_("Director disconnected."));
- QApplication::restoreOverrideCursor();
stat = BNET_HARDEOF;
}
break;
- }
+ }
return stat;
}
/* Called by signal when the Director has output for us */
-void DirComm::read_dir(int /* fd */)
+void DirComm::notify_read_dir(int /* fd */)
{
- if (mainWin->m_commDebug) Pmsg0(000, "read_dir\n");
- while (read() >= 0) {
- m_console->display_text(msg());
+ int stat;
+ if (!mainWin->m_notify) {
+ return;
}
+ if (mainWin->m_commDebug) Pmsg1(000, "enter read_dir conn %i read_dir\n", m_conn);
+ stat = m_sock->wait_data(0, 5000);
+ if (stat > 0) {
+ if (mainWin->m_commDebug) Pmsg2(000, "read_dir conn %i stat=%d\n", m_conn, stat);
+ while (read() >= 0) {
+ m_console->display_text(msg());
+ }
+ }
+ if (mainWin->m_commDebug) Pmsg2(000, "exit read_dir conn %i stat=%d\n", m_conn, stat);
}
/*
* When the notifier is enabled, read_dir() will automatically be
- * called by the Qt event loop when ever there is any output
- * from the Directory, and read_dir() will then display it on
+ * called by the Qt event loop when ever there is any output
+ * from the Director, and read_dir() will then display it on
* the console.
*
* When we are in a bat dialog, we want to control *all* output
* from the Directory, so we set notify to off.
- * m_console->notifiy(false);
+ * m_console->notify(false);
*/
-void DirComm::notify(bool enable)
-{
- m_notifier->setEnabled(enable);
+bool DirComm::notify(bool enable)
+{
+ bool prev_enabled = false;
+ /* Set global flag */
+ mainWin->m_notify = enable;
+ if (m_notifier) {
+ prev_enabled = m_notifier->isEnabled();
+ m_notifier->setEnabled(enable);
+ m_notify = enable;
+ if (mainWin->m_connDebug) Pmsg3(000, "conn=%i set_notify=%d prev=%d\n", m_conn, enable, prev_enabled);
+ } else if (mainWin->m_connDebug) {
+ Pmsg2(000, "m_notifier does not exist: %i %s\n", m_conn, m_console->m_dir->name());
+ }
+ 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;
- }
+ return m_notify;
}
/*
* Call-back for reading a passphrase for an encrypted PEM file
- * This function uses getpass(),
+ * 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);
+ //sendit(prompt);
if (win32_cgets(buf, size) == NULL) {
buf[0] = 0;
return 0;
return strlen(buf);
}
# else
+ const char *prompt = (const char *)userdata;
char *passwd;
passwd = getpass(prompt);