]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/console/console.cpp
Translation tweaks
[bacula/bacula] / bacula / src / qt-console / console / console.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2008 Free Software Foundation Europe e.V.
5
6    The main author of Bacula is Kern Sibbald, with contributions from
7    many others, a complete list can be found in the file AUTHORS.
8    This program is Free Software; you can redistribute it and/or
9    modify it under the terms of version two of the GNU General Public
10    License as published by the Free Software Foundation and included
11    in the file LICENSE.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Bacula® is a registered trademark of John Walker.
24    The licensor of Bacula is the Free Software Foundation Europe
25    (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26    Switzerland, email:ftf@fsfeurope.org.
27 */
28 /*
29  *   Version $Id$
30  *
31  *  Console Class
32  *
33  *   Kern Sibbald, January MMVII
34  *
35  */ 
36
37 #include "bat.h"
38 #include "console.h"
39 #include "restore.h"
40 #include "select.h"
41 #include "run/run.h"
42
43 static int tls_pem_callback(char *buf, int size, const void *userdata);
44
45
46 Console::Console(QStackedWidget *parent)
47 {
48    QFont font;
49    m_parent = parent;
50    m_closeable = false;
51    m_console = this;
52
53    setupUi(this);
54    m_sock = NULL;
55    m_at_prompt = false;
56    m_at_main_prompt = false;
57    m_textEdit = textEdit;   /* our console screen */
58    m_cursor = new QTextCursor(m_textEdit->document());
59    mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png"));
60
61    m_timer = NULL;
62    m_contextActions.append(actionStatusDir);
63    m_contextActions.append(actionConsoleHelp);
64    m_contextActions.append(actionRequestMessages);
65    m_contextActions.append(actionConsoleReload);
66    connect(actionStatusDir, SIGNAL(triggered()), this, SLOT(status_dir()));
67    connect(actionConsoleHelp, SIGNAL(triggered()), this, SLOT(consoleHelp()));
68    connect(actionConsoleReload, SIGNAL(triggered()), this, SLOT(consoleReload()));
69    connect(actionRequestMessages, SIGNAL(triggered()), this, SLOT(messages()));
70 }
71
72 Console::~Console()
73 {
74 }
75
76 void Console::startTimer()
77 {
78    m_timer = new QTimer(this);
79    QWidget::connect(m_timer, SIGNAL(timeout()), this, SLOT(poll_messages()));
80    m_timer->start(mainWin->m_checkMessagesInterval*1000);
81 }
82
83 void Console::stopTimer()
84 {
85    if (m_timer) {
86       QWidget::disconnect(m_timer, SIGNAL(timeout()), this, SLOT(poll_messages()));
87       m_timer->stop();
88       delete m_timer;
89       m_timer = NULL;
90    }
91 }
92       
93 void Console::poll_messages()
94 {
95    m_messages_pending = true;
96    if ((m_at_main_prompt) && (mainWin->m_checkMessages)){
97       write(".messages");
98       displayToPrompt();
99    }
100 }
101
102 /* Terminate any open socket */
103 void Console::terminate()
104 {
105    if (m_sock) {
106       notify(false);
107       delete m_notifier;
108       m_notifier = NULL;
109       stopTimer();
110       m_sock->close();
111       m_sock = NULL;
112    }
113 }
114
115 /*
116  * Connect to Director. 
117  */
118 void Console::connect_dir()
119 {
120    JCR *jcr = new JCR;
121    utime_t heart_beat;
122    char buf[1024];
123    CONRES *cons;
124       
125    buf[0] = 0;
126
127    m_textEdit = textEdit;   /* our console screen */
128
129    if (!m_dir) {          
130       mainWin->set_status("No Director found.");
131       goto bail_out;
132    }
133    if (m_sock) {
134       mainWin->set_status("Already connected.");
135       goto bail_out;
136    }
137
138    memset(jcr, 0, sizeof(JCR));
139
140    mainWin->set_statusf(_("Connecting to Director %s:%d"), m_dir->address, m_dir->DIRport);
141    display_textf(_("Connecting to Director %s:%d\n\n"), m_dir->address, m_dir->DIRport);
142
143    /* Give GUI a chance */
144    app->processEvents();
145    
146    LockRes();
147    /* If cons==NULL, default console will be used */
148    cons = (CONRES *)GetNextRes(R_CONSOLE, NULL);
149    UnlockRes();
150
151    /* Initialize Console TLS context once */
152    if (cons && !cons->tls_ctx && (cons->tls_enable || cons->tls_require)) {
153       /* Generate passphrase prompt */
154       bsnprintf(buf, sizeof(buf), "Passphrase for Console \"%s\" TLS private key: ", 
155                 cons->name());
156
157       /* Initialize TLS context:
158        * Args: CA certfile, CA certdir, Certfile, Keyfile,
159        * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer   
160        */
161       cons->tls_ctx = new_tls_context(cons->tls_ca_certfile,
162          cons->tls_ca_certdir, cons->tls_certfile,
163          cons->tls_keyfile, tls_pem_callback, &buf, NULL, true);
164
165       if (!cons->tls_ctx) {
166          display_textf(_("Failed to initialize TLS context for Console \"%s\".\n"),
167             m_dir->name());
168          goto bail_out;
169       }
170    }
171
172    /* Initialize Director TLS context once */
173    if (!m_dir->tls_ctx && (m_dir->tls_enable || m_dir->tls_require)) {
174       /* Generate passphrase prompt */
175       bsnprintf(buf, sizeof(buf), "Passphrase for Director \"%s\" TLS private key: ", 
176                 m_dir->name());
177
178       /* Initialize TLS context:
179        * Args: CA certfile, CA certdir, Certfile, Keyfile,
180        * Keyfile PEM Callback, Keyfile CB Userdata, DHfile, Verify Peer */
181       m_dir->tls_ctx = new_tls_context(m_dir->tls_ca_certfile,
182                           m_dir->tls_ca_certdir, m_dir->tls_certfile,
183                           m_dir->tls_keyfile, tls_pem_callback, &buf, NULL, true);
184
185       if (!m_dir->tls_ctx) {
186          display_textf(_("Failed to initialize TLS context for Director \"%s\".\n"),
187             m_dir->name());
188          mainWin->set_status("Connection failed");
189          goto bail_out;
190       }
191    }
192
193    if (m_dir->heartbeat_interval) {
194       heart_beat = m_dir->heartbeat_interval;
195    } else if (cons) {
196       heart_beat = cons->heartbeat_interval;
197    } else {
198       heart_beat = 0;
199    }        
200
201    m_sock = bnet_connect(NULL, 5, 15, heart_beat,
202                           _("Director daemon"), m_dir->address,
203                           NULL, m_dir->DIRport, 0);
204    if (m_sock == NULL) {
205       mainWin->set_status("Connection failed");
206       goto bail_out;
207    } else {
208       /* Update page selector to green to indicate that Console is connected */
209       mainWin->actionConnect->setIcon(QIcon(":images/connected.png"));
210       QBrush greenBrush(Qt::green);
211       QTreeWidgetItem *item = mainWin->getFromHash(this);
212       item->setForeground(0, greenBrush);
213    }
214
215    jcr->dir_bsock = m_sock;
216
217    if (!authenticate_director(jcr, m_dir, cons, buf, sizeof(buf))) {
218       display_text(buf);
219       goto bail_out;
220    }
221
222    if (buf[0]) {
223       display_text(buf);
224    }
225
226    /* Give GUI a chance */
227    app->processEvents();
228
229    mainWin->set_status(_("Initializing ..."));
230
231    /* Set up input notifier */
232    m_notifier = new QSocketNotifier(m_sock->m_fd, QSocketNotifier::Read, 0);
233    QObject::connect(m_notifier, SIGNAL(activated(int)), this, SLOT(read_dir(int)));
234
235    write(".api 1");
236    displayToPrompt();
237
238    beginNewCommand();
239    job_list.clear();
240    client_list.clear();
241    fileset_list.clear();
242    fileset_list.clear();
243    messages_list.clear();
244    pool_list.clear();
245    storage_list.clear();
246    type_list.clear();
247    level_list.clear();
248    dir_cmd(".jobs", job_list);
249    dir_cmd(".clients", client_list);
250    dir_cmd(".filesets", fileset_list);  
251    dir_cmd(".msgs", messages_list);
252    dir_cmd(".pools", pool_list);
253    dir_cmd(".storage", storage_list);
254    dir_cmd(".types", type_list);
255    dir_cmd(".levels", level_list);
256
257    mainWin->set_status(_("Connected"));
258    startTimer();                      /* start message timer */
259
260 bail_out:
261    delete jcr;
262    return;
263 }
264
265 bool Console::dir_cmd(QString &cmd, QStringList &results)
266 {
267    return dir_cmd(cmd.toUtf8().data(), results);
268 }
269
270 /*
271  * Send a command to the Director, and return the
272  *  results in a QStringList.  
273  */
274 bool Console::dir_cmd(const char *cmd, QStringList &results)
275 {
276    int stat;
277
278    notify(false);
279    write(cmd);
280    while ((stat = read()) > 0) {
281       if (mainWin->m_displayAll) display_text(msg());
282       strip_trailing_junk(msg());
283       results << msg();
284    }
285    notify(true);
286    discardToPrompt();
287    return true;              /* ***FIXME*** return any command error */
288 }
289
290 bool Console::sql_cmd(QString &query, QStringList &results)
291 {
292    return sql_cmd(query.toUtf8().data(), results);
293 }
294
295 /*
296  * Send an sql query to the Director, and return the
297  *  results in a QStringList.  
298  */
299 bool Console::sql_cmd(const char *query, QStringList &results)
300 {
301    int stat;
302    POOL_MEM cmd(PM_MESSAGE);
303
304    if (!is_connectedGui()) {
305       return false;
306    }
307
308    notify(false);
309    
310    pm_strcpy(cmd, ".sql query=\"");
311    pm_strcat(cmd, query);
312    pm_strcat(cmd, "\"");
313    write(cmd.c_str());
314    while ((stat = read()) > 0) {
315       if (mainWin->m_displayAll) display_text(msg());
316       strip_trailing_junk(msg());
317       results << msg();
318    }
319    notify(true);
320    discardToPrompt();
321    return true;              /* ***FIXME*** return any command error */
322 }
323
324
325 /*  
326  * Send a job name to the director, and read all the resulting
327  *  defaults. 
328  */
329 bool Console::get_job_defaults(struct job_defaults &job_defs)
330 {
331    QString scmd;
332    int stat;
333    char *def;
334
335    notify(false);
336    beginNewCommand();
337    scmd = QString(".defaults job=\"%1\"").arg(job_defs.job_name);
338    write(scmd);
339    while ((stat = read()) > 0) {
340       if (mainWin->m_displayAll) display_text(msg());
341       def = strchr(msg(), '=');
342       if (!def) {
343          continue;
344       }
345       /* Pointer to default value */
346       *def++ = 0;
347       strip_trailing_junk(def);
348
349       if (strcmp(msg(), "job") == 0) {
350          if (strcmp(def, job_defs.job_name.toUtf8().data()) != 0) {
351             goto bail_out;
352          }
353          continue;
354       }
355       if (strcmp(msg(), "pool") == 0) {
356          job_defs.pool_name = def;
357          continue;
358       }
359       if (strcmp(msg(), "messages") == 0) {
360          job_defs.messages_name = def;
361          continue;
362       }
363       if (strcmp(msg(), "client") == 0) {
364          job_defs.client_name = def;
365          continue;
366       }
367       if (strcmp(msg(), "storage") == 0) {
368          job_defs.store_name = def;
369          continue;
370       }
371       if (strcmp(msg(), "where") == 0) {
372          job_defs.where = def;
373          continue;
374       }
375       if (strcmp(msg(), "level") == 0) {
376          job_defs.level = def;
377          continue;
378       }
379       if (strcmp(msg(), "type") == 0) {
380          job_defs.type = def;
381          continue;
382       }
383       if (strcmp(msg(), "fileset") == 0) {
384          job_defs.fileset_name = def;
385          continue;
386       }
387       if (strcmp(msg(), "catalog") == 0) {
388          job_defs.catalog_name = def;
389          continue;
390       }
391       if (strcmp(msg(), "enabled") == 0) {
392          job_defs.enabled = *def == '1' ? true : false;
393          continue;
394       }
395    }
396
397    notify(true);
398    return true;
399
400 bail_out:
401    notify(true);
402    return false;
403 }
404
405
406 /*
407  * Save user settings associated with this console
408  */
409 void Console::writeSettings()
410 {
411    QFont font = get_font();
412
413    QSettings settings(m_dir->name(), "bat");
414    settings.beginGroup("Console");
415    settings.setValue("consoleFont", font.family());
416    settings.setValue("consolePointSize", font.pointSize());
417    settings.setValue("consoleFixedPitch", font.fixedPitch());
418    settings.endGroup();
419 }
420
421 /*
422  * Read and restore user settings associated with this console
423  */
424 void Console::readSettings()
425
426    QFont font = get_font();
427
428    QSettings settings(m_dir->name(), "bat");
429    settings.beginGroup("Console");
430    font.setFamily(settings.value("consoleFont", "Courier").value<QString>());
431    font.setPointSize(settings.value("consolePointSize", 10).toInt());
432    font.setFixedPitch(settings.value("consoleFixedPitch", true).toBool());
433    settings.endGroup();
434    m_textEdit->setFont(font);
435 }
436
437 /*
438  * Set the console textEdit font
439  */
440 void Console::set_font()
441 {
442    bool ok;
443    QFont font = QFontDialog::getFont(&ok, QFont(m_textEdit->font()), this);
444    if (ok) {
445       m_textEdit->setFont(font);
446    }
447 }
448
449 /*
450  * Get the console text edit font
451  */
452 const QFont Console::get_font()
453 {
454    return m_textEdit->font();
455 }
456
457 /*
458  * Slot for responding to status dir button on button bar
459  */
460 void Console::status_dir()
461 {
462    QString cmd("status dir");
463    consoleCommand(cmd);
464 }
465
466 /*
467  * Slot for responding to messages button on button bar
468  */
469 void Console::messages()
470 {
471    QString cmd(".messages");
472    consoleCommand(cmd);
473 }
474
475 /*
476  * Put text into the console window
477  */
478 void Console::display_textf(const char *fmt, ...)
479 {
480    va_list arg_ptr;
481    char buf[1000];
482    int len;
483    va_start(arg_ptr, fmt);
484    len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
485    va_end(arg_ptr);
486    display_text(buf);
487 }
488
489 void Console::display_text(const QString buf)
490 {
491    m_cursor->insertText(buf);
492    update_cursor();
493 }
494
495
496 void Console::display_text(const char *buf)
497 {
498    m_cursor->insertText(buf);
499    update_cursor();
500 }
501
502 void Console::display_html(const QString buf)
503 {
504    m_cursor->insertHtml(buf);
505    update_cursor();
506 }
507
508 /* Position cursor to end of screen */
509 void Console::update_cursor()
510 {
511    QApplication::restoreOverrideCursor();
512    m_textEdit->moveCursor(QTextCursor::End);
513    m_textEdit->ensureCursorVisible();
514 }
515
516 /* 
517  * This should be moved into a bSocket class 
518  */
519 char *Console::msg()
520 {
521    if (m_sock) {
522       return m_sock->msg;
523    }
524    return NULL;
525 }
526
527 /* Send a command to the Director */
528 void Console::write_dir(const char *msg)
529 {
530    if (m_sock) {
531       mainWin->set_status(_("Processing command ..."));
532       QApplication::setOverrideCursor(Qt::WaitCursor);
533       write(msg);
534    } else {
535       mainWin->set_status(" Director not connected. Click on connect button.");
536       mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png"));
537       QBrush redBrush(Qt::red);
538       QTreeWidgetItem *item = mainWin->getFromHash(this);
539       item->setForeground(0, redBrush);
540       m_at_prompt = false;
541       m_at_main_prompt = false;
542    }
543 }
544
545 int Console::write(const QString msg)
546 {
547    return write(msg.toUtf8().data());
548 }
549
550 int Console::write(const char *msg)
551 {
552    if (!m_sock) {
553       return -1;
554    }
555    m_sock->msglen = pm_strcpy(m_sock->msg, msg);
556    m_at_prompt = false;
557    m_at_main_prompt = false;
558    if (mainWin->m_commDebug) Pmsg1(000, "send: %s\n", msg);
559    return m_sock->send();
560
561 }
562
563 /*
564  * Get to main command prompt -- i.e. abort any subcommand
565  */
566 void Console::beginNewCommand()
567 {
568    for (int i=0; i < 3; i++) {
569       write(".");
570       while (read() > 0) {
571          if (mainWin->m_displayAll) display_text(msg());
572       }
573       if (m_at_main_prompt) {
574          break;
575       }
576    }
577    display_text("\n");
578 }
579
580 void Console::displayToPrompt()
581
582    int stat = 0;
583    if (mainWin->m_commDebug) Pmsg0(000, "DisplaytoPrompt\n");
584    while (!m_at_prompt) {
585       if ((stat=read()) > 0) {
586          display_text(msg());
587       }
588    }
589    if (mainWin->m_commDebug) Pmsg1(000, "endDisplaytoPrompt=%d\n", stat);
590 }
591
592 void Console::discardToPrompt()
593
594    int stat = 0;
595    if (mainWin->m_commDebug) Pmsg0(000, "discardToPrompt\n");
596    while (!m_at_prompt) {
597       if ((stat=read()) > 0) {
598          if (mainWin->m_displayAll) display_text(msg());
599       }
600    }
601    if (mainWin->m_commDebug) Pmsg1(000, "endDisplayToPrompt=%d\n", stat);
602 }
603
604
605 /* 
606  * Blocking read from director
607  */
608 int Console::read()
609 {
610    int stat = 0;
611    while (m_sock) {
612       for (;;) {
613          stat = bnet_wait_data_intr(m_sock, 1);
614          if (stat > 0) {
615             break;
616          } 
617          app->processEvents();
618          if (m_api_set && m_messages_pending) {
619             write_dir(".messages");
620             m_messages_pending = false;
621          }
622       }
623       m_sock->msg[0] = 0;
624       stat = m_sock->recv();
625       if (stat >= 0) {
626          if (mainWin->m_commDebug) Pmsg1(000, "got: %s\n", m_sock->msg);
627          if (m_at_prompt) {
628             display_text("\n");
629             m_at_prompt = false;
630             m_at_main_prompt = false;
631          }
632       }
633       switch (m_sock->msglen) {
634       case BNET_MSGS_PENDING :
635          if (m_notifier->isEnabled()) {
636             if (mainWin->m_commDebug) Pmsg0(000, "MSGS PENDING\n");
637             write_dir(".messages");
638             displayToPrompt();
639             m_messages_pending = false;
640          }
641          m_messages_pending = true;
642          continue;
643       case BNET_CMD_OK:
644          if (mainWin->m_commDebug) Pmsg0(000, "CMD OK\n");
645          m_at_prompt = false;
646          m_at_main_prompt = false;
647          mainWin->set_status(_("Command completed ..."));
648          continue;
649       case BNET_CMD_BEGIN:
650          if (mainWin->m_commDebug) Pmsg0(000, "CMD BEGIN\n");
651          m_at_prompt = false;
652          m_at_main_prompt = false;
653          mainWin->set_status(_("Processing command ..."));
654          continue;
655       case BNET_MAIN_PROMPT:
656          if (mainWin->m_commDebug) Pmsg0(000, "MAIN PROMPT\n");
657          m_at_prompt = true;
658          m_at_main_prompt = true;
659          mainWin->set_status(_("At main prompt waiting for input ..."));
660          QApplication::restoreOverrideCursor();
661          break;
662       case BNET_PROMPT:
663          if (mainWin->m_commDebug) Pmsg0(000, "PROMPT\n");
664          m_at_prompt = true;
665          m_at_main_prompt = false;
666          mainWin->set_status(_("At prompt waiting for input ..."));
667          QApplication::restoreOverrideCursor();
668          break;
669       case BNET_CMD_FAILED:
670          if (mainWin->m_commDebug) Pmsg0(000, "CMD FAILED\n");
671          mainWin->set_status(_("Command failed."));
672          QApplication::restoreOverrideCursor();
673          break;
674       /* We should not get this one */
675       case BNET_EOD:
676          if (mainWin->m_commDebug) Pmsg0(000, "EOD\n");
677          mainWin->set_status_ready();
678          QApplication::restoreOverrideCursor();
679          if (!m_api_set) {
680             break;
681          }
682          continue;
683       case BNET_START_SELECT:
684          if (mainWin->m_commDebug) Pmsg0(000, "START SELECT\n");
685          new selectDialog(this);    
686          break;
687       case BNET_YESNO:
688          if (mainWin->m_commDebug) Pmsg0(000, "YESNO\n");
689          new yesnoPopUp(this);
690          break;
691       case BNET_RUN_CMD:
692          if (mainWin->m_commDebug) Pmsg0(000, "RUN CMD\n");
693          new runCmdPage();
694          break;
695       case BNET_START_RTREE:
696          if (mainWin->m_commDebug) Pmsg0(000, "START RTREE CMD\n");
697          new restorePage();
698          break;
699       case BNET_END_RTREE:
700          if (mainWin->m_commDebug) Pmsg0(000, "END RTREE CMD\n");
701          break;
702       case BNET_ERROR_MSG:
703          if (mainWin->m_commDebug) Pmsg0(000, "ERROR MSG\n");
704          m_sock->recv();              /* get the message */
705          display_text(msg());
706          QMessageBox::critical(this, "Error", msg(), QMessageBox::Ok);
707          break;
708       case BNET_WARNING_MSG:
709          if (mainWin->m_commDebug) Pmsg0(000, "WARNING MSG\n");
710          m_sock->recv();              /* get the message */
711          display_text(msg());
712          QMessageBox::critical(this, "Warning", msg(), QMessageBox::Ok);
713          break;
714       case BNET_INFO_MSG:
715          if (mainWin->m_commDebug) Pmsg0(000, "INFO MSG\n");
716          m_sock->recv();              /* get the message */
717          display_text(msg());
718          mainWin->set_status(msg());
719          break;
720       }
721       if (is_bnet_stop(m_sock)) {         /* error or term request */
722          if (mainWin->m_commDebug) Pmsg0(000, "BNET STOP\n");
723          stopTimer();
724          m_sock->close();
725          m_sock = NULL;
726          mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png"));
727          QBrush redBrush(Qt::red);
728          QTreeWidgetItem *item = mainWin->getFromHash(this);
729          item->setForeground(0, redBrush);
730          m_notifier->setEnabled(false);
731          delete m_notifier;
732          m_notifier = NULL;
733          mainWin->set_status(_("Director disconnected."));
734          QApplication::restoreOverrideCursor();
735          stat = BNET_HARDEOF;
736       }
737       break;
738    } 
739    return stat;
740 }
741
742 /* Called by signal when the Director has output for us */
743 void Console::read_dir(int /* fd */)
744 {
745    if (mainWin->m_commDebug) Pmsg0(000, "read_dir\n");
746    while (read() >= 0) {
747       display_text(msg());
748    }
749 }
750
751 /*
752  * When the notifier is enabled, read_dir() will automatically be
753  * called by the Qt event loop when ever there is any output 
754  * from the Directory, and read_dir() will then display it on
755  * the console.
756  *
757  * When we are in a bat dialog, we want to control *all* output
758  * from the Directory, so we set notify to off.
759  *    m_console->notifiy(false);
760  */
761 void Console::notify(bool enable) 
762
763    m_notifier->setEnabled(enable);   
764 }
765
766 void Console::setDirectorTreeItem(QTreeWidgetItem *item)
767 {
768    m_directorTreeItem = item;
769 }
770
771 void Console::setDirRes(DIRRES *dir) 
772
773    m_dir = dir;
774 }
775
776 /*
777  * To have the ability to get the name of the director resource.
778  */
779 void Console::getDirResName(QString &name_returned)
780 {
781    name_returned = m_dir->name();
782 }
783
784 bool Console::is_connectedGui()
785 {
786    if (is_connected()) {
787       return true;
788    } else {
789       QString message("Director ");
790       message += " is currently disconnected\n  Please reconnect!!";
791       QMessageBox::warning(this, "Bat",
792          tr(message.toUtf8().data()), QMessageBox::Ok );
793       return false;
794    }
795 }
796
797 /*
798  * A temporary function to prevent connecting to the director if the director
799  * is busy with a restore.
800  */
801 bool Console::preventInUseConnect()
802 {
803    if (!is_connected()) {
804       QString message("Director ");
805       message += m_dir->name();
806       message += " is currently disconnected\n  Please reconnect!!";
807       QMessageBox::warning(this, "Bat",
808          tr(message.toUtf8().data()), QMessageBox::Ok );
809       return false;
810    } else if (!m_at_main_prompt){
811       QString message("Director ");
812       message += m_dir->name();
813       message += " is currently busy\n  Please complete restore or other "
814                  " operation !!  This is a limitation that will be resolved before a beta"
815                  " release.  This is currently an alpha release.";
816       QMessageBox::warning(this, "Bat",
817          tr(message.toUtf8().data()), QMessageBox::Ok );
818       return false;
819    } else if (!m_at_prompt){
820       QString message("Director ");
821       message += m_dir->name();
822       message += " is currently not at a prompt\n  Please try again!!";
823       QMessageBox::warning(this, "Bat",
824          tr(message.toUtf8().data()), QMessageBox::Ok );
825       return false;
826    } else {
827       return true;
828    }
829 }
830
831 /*
832  * Call-back for reading a passphrase for an encrypted PEM file
833  * This function uses getpass(), 
834  *  which uses a static buffer and is NOT thread-safe.
835  */
836 static int tls_pem_callback(char *buf, int size, const void *userdata)
837 {
838    (void)size;
839    (void)userdata;
840 #ifdef HAVE_TLS
841    const char *prompt = (const char *)userdata;
842 # if defined(HAVE_WIN32)
843    sendit(prompt);
844    if (win32_cgets(buf, size) == NULL) {
845       buf[0] = 0;
846       return 0;
847    } else {
848       return strlen(buf);
849    }
850 # else
851    char *passwd;
852
853    passwd = getpass(prompt);
854    bstrncpy(buf, passwd, size);
855    return strlen(buf);
856 # endif
857 #else
858    buf[0] = 0;
859    return 0;
860 #endif
861 }
862
863 /* Slot for responding to page selectors status help command */
864 void Console::consoleHelp()
865 {
866    QString cmd("help");
867    consoleCommand(cmd);
868 }
869
870 /* Slot for responding to page selectors reload bacula-dir.conf */
871 void Console::consoleReload()
872 {
873    QString cmd("reload");
874    consoleCommand(cmd);
875 }
876
877 /* Function to get a list of volumes */
878 void Console::getVolumeList(QStringList &volumeList)
879 {
880    QString query("SELECT VolumeName AS Media FROM Media ORDER BY Media");
881    if (mainWin->m_sqlDebug) {
882       Pmsg1(000, "Query cmd : %s\n",query.toUtf8().data());
883    }
884    QStringList results;
885    if (sql_cmd(query, results)) {
886       QString field;
887       QStringList fieldlist;
888       /* Iterate through the lines of results. */
889       foreach (QString resultline, results) {
890          fieldlist = resultline.split("\t");
891          volumeList.append(fieldlist[0]);
892       } /* foreach resultline */
893    } /* if results from query */
894 }
895
896 /* Function to get a list of volumes */
897 void Console::getStatusList(QStringList &statusLongList)
898 {
899    QString statusQuery("SELECT JobStatusLong FROM Status");
900    if (mainWin->m_sqlDebug) {
901       Pmsg1(000, "Query cmd : %s\n",statusQuery.toUtf8().data());
902    }
903    QStringList statusResults;
904    if (sql_cmd(statusQuery, statusResults)) {
905       QString field;
906       QStringList fieldlist;
907       /* Iterate through the lines of results. */
908       foreach (QString resultline, statusResults) {
909          fieldlist = resultline.split("\t");
910          statusLongList.append(fieldlist[0]);
911       } /* foreach resultline */
912    } /* if results from statusquery */
913 }