]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/console/console.cpp
Fix bat command line input bug
[bacula/bacula] / bacula / src / qt-console / console / console.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-2009 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 Kern Sibbald.
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 Console::Console(QStackedWidget *parent)
44 {
45    QFont font;
46    m_messages_pending = false;
47    m_parent = parent;
48    m_closeable = false;
49    m_console = this;
50    m_warningPrevent = false;
51    m_dircommCounter = 0;
52    m_dircommHash.insert(m_dircommCounter, new DirComm(this, m_dircommCounter));
53
54    setupUi(this);
55    m_textEdit = textEdit;   /* our console screen */
56    m_cursor = new QTextCursor(m_textEdit->document());
57    mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png"));
58
59    m_timer = NULL;
60    m_contextActions.append(actionStatusDir);
61    m_contextActions.append(actionConsoleHelp);
62    m_contextActions.append(actionRequestMessages);
63    m_contextActions.append(actionConsoleReload);
64    connect(actionStatusDir, SIGNAL(triggered()), this, SLOT(status_dir()));
65    connect(actionConsoleHelp, SIGNAL(triggered()), this, SLOT(consoleHelp()));
66    connect(actionConsoleReload, SIGNAL(triggered()), this, SLOT(consoleReload()));
67    connect(actionRequestMessages, SIGNAL(triggered()), this, SLOT(messages()));
68 }
69
70 Console::~Console()
71 {
72 }
73
74 void Console::startTimer()
75 {
76    m_timer = new QTimer(this);
77    QWidget::connect(m_timer, SIGNAL(timeout()), this, SLOT(poll_messages()));
78    m_timer->start(mainWin->m_checkMessagesInterval*1000);
79 }
80
81 void Console::stopTimer()
82 {
83    if (m_timer) {
84       QWidget::disconnect(m_timer, SIGNAL(timeout()), this, SLOT(poll_messages()));
85       m_timer->stop();
86       delete m_timer;
87       m_timer = NULL;
88    }
89 }
90
91 /* slot connected to the timer
92  * requires preferences of check messages and operates at interval */
93 void Console::poll_messages()
94 {
95    int conn;
96    if (!availableDirComm(conn))
97       return;
98    DirComm *dircomm = m_dircommHash.value(conn);
99
100    if (mainWin->m_checkMessages && dircomm->m_at_main_prompt && hasFocus() && !mainWin->getWaitState()){
101       messagesPending(true);
102       dircomm->write(".messages");
103       displayToPrompt(conn);
104       messagesPending(false);
105    }
106 }
107
108 /*
109  * Connect to Director.  This does not connect to the director, dircomm does.
110  * This creates the first and possibly 2nd dircomm instance
111  */
112 void Console::connect_dir()
113 {
114    DirComm *dircomm = m_dircommHash.value(0);
115
116    if (!m_console->m_dir) {
117       mainWin->set_status( tr("No Director found."));
118       return;
119    }
120
121    m_textEdit = textEdit;   /* our console screen */
122
123    if (dircomm->connect_dir()) {
124       if (mainWin->m_connDebug)
125          Pmsg1(000, "DirComm 0 Seems to have Connected %s\n", m_dir->name());
126       beginNewCommand(0);
127    }
128    mainWin->set_status(_("Connected"));
129    
130    startTimer();                      /* start message timer */
131 }
132
133 /*
134  * A function created to separate out the population of the lists
135  * from the Console::connect_dir function
136  */
137 void Console::populateLists(bool forcenew)
138 {
139    int conn;
140    if (forcenew) {
141       if (!newDirComm(conn)) {
142          Pmsg1(000, "newDirComm Seems to Failed to create a connection for populateLists %s\n", m_dir->name());
143          return;
144       }
145    } else {
146       if (!availableDirComm(conn)) {
147          Pmsg1(000, "availableDirComm Seems to Failed to find a connection for populateListsi %s\n", m_dir->name());
148          return;
149       }
150    }
151    populateLists(conn);
152 }
153
154 void Console::populateLists(int conn)
155 {
156    job_list.clear();
157    client_list.clear();
158    fileset_list.clear();
159    messages_list.clear();
160    pool_list.clear();
161    storage_list.clear();
162    type_list.clear();
163    level_list.clear();
164    dir_cmd(conn, ".jobs", job_list);
165    dir_cmd(conn, ".clients", client_list);
166    dir_cmd(conn, ".filesets", fileset_list);  
167    dir_cmd(conn, ".msgs", messages_list);
168    dir_cmd(conn, ".pools", pool_list);
169    dir_cmd(conn, ".storage", storage_list);
170    dir_cmd(conn, ".types", type_list);
171    dir_cmd(conn, ".levels", level_list);
172
173    if (mainWin->m_connDebug) {
174       QString dbgmsg = QString("jobs=%1 clients=%2 filesets=%3 msgs=%4 pools=%5 storage=%6 types=%7 levels=%8 conn=%9 %10\n")
175         .arg(job_list.count()).arg(client_list.count()).arg(fileset_list.count()).arg(messages_list.count())
176         .arg(pool_list.count()).arg(storage_list.count()).arg(type_list.count()).arg(level_list.count())
177         .arg(conn).arg(m_dir->name());
178       Pmsg1(000, "%s", dbgmsg.toUtf8().data());
179    }
180    job_list.sort();
181    client_list.sort();
182    fileset_list.sort();
183    messages_list.sort();
184    pool_list.sort();
185    storage_list.sort();
186    type_list.sort();
187    level_list.sort();
188 }
189
190 /*
191  *  Overload function for dir_cmd with a QString
192  *  Ease of use
193  */
194 bool Console::dir_cmd(QString &cmd, QStringList &results)
195 {
196    return dir_cmd(cmd.toUtf8().data(), results);
197 }
198
199 /*
200  *  Overload function for dir_cmd, this is if connection is not worried about
201  */
202 bool Console::dir_cmd(const char *cmd, QStringList &results)
203 {
204    int conn;
205    if (availableDirComm(conn)) {
206       dir_cmd(conn, cmd, results);
207       return true;
208    } else {
209       Pmsg1(000, "dir_cmd Seems to Failed to find a connection %s\n", m_dir->name());
210       return false;
211    }
212 }
213
214 /*
215  * Send a command to the Director, and return the
216  *  results in a QStringList.  
217  */
218 bool Console::dir_cmd(int conn, const char *cmd, QStringList &results)
219 {
220    mainWin->waitEnter();
221    DirComm *dircomm = m_dircommHash.value(conn);
222    int stat;
223
224    if (mainWin->m_connDebug) {
225       QString dbgmsg = QString("dir_cmd conn %1 %2 %3\n").arg(conn).arg(m_dir->name()).arg(cmd);
226       Pmsg1(000, "%s", dbgmsg.toUtf8().data());
227    }
228    notify(conn, false);
229    dircomm->write(cmd);
230    while ((stat = dircomm->read()) > 0 && dircomm->is_in_command()) {
231       if (mainWin->m_displayAll) display_text(dircomm->msg());
232       strip_trailing_junk(dircomm->msg());
233       results << dircomm->msg();
234    }
235    if (stat > 0 && mainWin->m_displayAll) display_text(dircomm->msg());
236    notify(conn, true);
237    discardToPrompt(conn);
238    mainWin->waitExit();
239    return true;              /* ***FIXME*** return any command error */
240 }
241
242 /*
243  * OverLoads for sql_cmd
244  */
245 bool Console::sql_cmd(int &conn, QString &query, QStringList &results)
246 {
247    return sql_cmd(conn, query.toUtf8().data(), results, false);
248 }
249
250 bool Console::sql_cmd(QString &query, QStringList &results)
251 {
252    int conn;
253    if (!availableDirComm(conn))
254       return false;
255    return sql_cmd(conn, query.toUtf8().data(), results, true);
256 }
257
258 bool Console::sql_cmd(const char *query, QStringList &results)
259 {
260    int conn;
261    if (!availableDirComm(conn))
262       return false;
263    return sql_cmd(conn, query, results, true);
264 }
265
266 /*
267  * Send an sql query to the Director, and return the
268  *  results in a QStringList.  
269  */
270 bool Console::sql_cmd(int &conn, const char *query, QStringList &results, bool donotify)
271 {
272    DirComm *dircomm = m_dircommHash.value(conn);
273    int stat;
274    POOL_MEM cmd(PM_MESSAGE);
275
276    if (!is_connectedGui()) {
277       return false;
278    }
279
280    if (mainWin->m_connDebug)
281       Pmsg2(000, "sql_cmd conn %i %s\n", conn, query);
282    if (donotify)
283       dircomm->notify(false);
284    mainWin->waitEnter();
285    
286    pm_strcpy(cmd, ".sql query=\"");
287    pm_strcat(cmd, query);
288    pm_strcat(cmd, "\"");
289    dircomm->write(cmd.c_str());
290    while ((stat = dircomm->read()) > 0) {
291       bool first = true;
292       if (mainWin->m_displayAll) {
293          display_text(dircomm->msg());
294          display_text("\n");
295       }
296       strip_trailing_junk(dircomm->msg());
297       bool doappend = true;
298       if (first) {
299          QString dum = dircomm->msg();
300          if ((dum.left(6) == "*None*")) doappend = false;
301       }
302       if (doappend)
303          results << dircomm->msg();
304       first = false;
305    }
306    if (donotify)
307       dircomm->notify(true);
308    discardToPrompt(conn);
309    mainWin->waitExit();
310    return true;              /* ***FIXME*** return any command error */
311 }
312
313 /* 
314  * Overloads for
315  * Sending a command to the Director
316  */
317 int Console::write_dir(const char *msg)
318 {
319    int conn;
320    if (availableDirComm(conn))
321       write_dir(conn, msg);
322    return conn;
323 }
324
325 int Console::write_dir(const char *msg, bool dowait)
326 {
327    int conn;
328    if (availableDirComm(conn))
329       write_dir(conn, msg, dowait);
330    return conn;
331 }
332
333 void Console::write_dir(int conn, const char *msg)
334 {
335    write_dir(conn, msg, true);
336 }
337
338 /*
339  * Send a command to the Director
340  */
341 void Console::write_dir(int conn, const char *msg, bool dowait)
342 {
343    DirComm *dircomm = m_dircommHash.value(conn);
344
345    if (dircomm->m_sock) {
346       mainWin->set_status(_("Processing command ..."));
347       if (dowait)
348          mainWin->waitEnter();
349       dircomm->write(msg);
350       if (dowait)
351          mainWin->waitExit();
352    } else {
353       mainWin->set_status( tr(" Director not connected. Click on connect button."));
354       mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png"));
355       QBrush redBrush(Qt::red);
356       QTreeWidgetItem *item = mainWin->getFromHash(this);
357       item->setForeground(0, redBrush);
358       dircomm->m_at_prompt = false;
359       dircomm->m_at_main_prompt = false;
360    }
361 }
362
363 /*
364  * get_job_defaults overload
365  */
366 bool Console::get_job_defaults(struct job_defaults &job_defs)
367 {
368    int conn;
369    return get_job_defaults(conn, job_defs, true);
370 }
371
372 bool Console::get_job_defaults(int &conn, struct job_defaults &job_defs)
373 {
374    return get_job_defaults(conn, job_defs, false);
375 }
376
377 /*  
378  * Send a job name to the director, and read all the resulting
379  *  defaults. 
380  */
381 bool Console::get_job_defaults(int &conn, struct job_defaults &job_defs, bool donotify)
382 {
383    QString scmd;
384    int stat;
385    char *def;
386
387    if (donotify)
388       conn = notifyOff();
389    beginNewCommand(conn);
390    DirComm *dircomm = m_dircommHash.value(conn);
391    bool prevWaitState = mainWin->getWaitState();
392    if (!prevWaitState)
393       mainWin->waitEnter();
394    if (mainWin->m_connDebug)
395       Pmsg2(000, "job_defaults conn %i %s\n", conn, m_dir->name());
396    scmd = QString(".defaults job=\"%1\"").arg(job_defs.job_name);
397    dircomm->write(scmd);
398    while ((stat = dircomm->read()) > 0) {
399       if (mainWin->m_displayAll) display_text(dircomm->msg());
400       def = strchr(dircomm->msg(), '=');
401       if (!def) {
402          continue;
403       }
404       /* Pointer to default value */
405       *def++ = 0;
406       strip_trailing_junk(def);
407
408       if (strcmp(dircomm->msg(), "job") == 0) {
409          if (strcmp(def, job_defs.job_name.toUtf8().data()) != 0) {
410             goto bail_out;
411          }
412          continue;
413       }
414       if (strcmp(dircomm->msg(), "pool") == 0) {
415          job_defs.pool_name = def;
416          continue;
417       }
418       if (strcmp(dircomm->msg(), "messages") == 0) {
419          job_defs.messages_name = def;
420          continue;
421       }
422       if (strcmp(dircomm->msg(), "client") == 0) {
423          job_defs.client_name = def;
424          continue;
425       }
426       if (strcmp(dircomm->msg(), "storage") == 0) {
427          job_defs.store_name = def;
428          continue;
429       }
430       if (strcmp(dircomm->msg(), "where") == 0) {
431          job_defs.where = def;
432          continue;
433       }
434       if (strcmp(dircomm->msg(), "level") == 0) {
435          job_defs.level = def;
436          continue;
437       }
438       if (strcmp(dircomm->msg(), "type") == 0) {
439          job_defs.type = def;
440          continue;
441       }
442       if (strcmp(dircomm->msg(), "fileset") == 0) {
443          job_defs.fileset_name = def;
444          continue;
445       }
446       if (strcmp(dircomm->msg(), "catalog") == 0) {
447          job_defs.catalog_name = def;
448          continue;
449       }
450       if (strcmp(dircomm->msg(), "enabled") == 0) {
451          job_defs.enabled = *def == '1' ? true : false;
452          continue;
453       }
454    }
455
456    if (donotify)
457       notify(conn, true);
458    if (!prevWaitState)
459       mainWin->waitExit();
460    return true;
461
462 bail_out:
463    if (donotify)
464       notify(conn, true);
465    if (!prevWaitState)
466       mainWin->waitExit();
467    return false;
468 }
469
470
471 /*
472  * Save user settings associated with this console
473  */
474 void Console::writeSettings()
475 {
476    QFont font = get_font();
477
478    QSettings settings(m_dir->name(), "bat");
479    settings.beginGroup("Console");
480    settings.setValue("consoleFont", font.family());
481    settings.setValue("consolePointSize", font.pointSize());
482    settings.setValue("consoleFixedPitch", font.fixedPitch());
483    settings.endGroup();
484 }
485
486 /*
487  * Read and restore user settings associated with this console
488  */
489 void Console::readSettings()
490
491    QFont font = get_font();
492
493    QSettings settings(m_dir->name(), "bat");
494    settings.beginGroup("Console");
495    font.setFamily(settings.value("consoleFont", "Courier").value<QString>());
496    font.setPointSize(settings.value("consolePointSize", 10).toInt());
497    font.setFixedPitch(settings.value("consoleFixedPitch", true).toBool());
498    settings.endGroup();
499    m_textEdit->setFont(font);
500 }
501
502 /*
503  * Set the console textEdit font
504  */
505 void Console::set_font()
506 {
507    bool ok;
508    QFont font = QFontDialog::getFont(&ok, QFont(m_textEdit->font()), this);
509    if (ok) {
510       m_textEdit->setFont(font);
511    }
512 }
513
514 /*
515  * Get the console text edit font
516  */
517 const QFont Console::get_font()
518 {
519    return m_textEdit->font();
520 }
521
522 /*
523  * Slot for responding to status dir button on button bar
524  */
525 void Console::status_dir()
526 {
527    QString cmd("status dir");
528    consoleCommand(cmd);
529 }
530
531 /*
532  * Slot for responding to messages button on button bar
533  * Here we want to bring the console to the front so use pages' consoleCommand
534  */
535 void Console::messages()
536 {
537    QString cmd(".messages");
538    consoleCommand(cmd);
539    messagesPending(false);
540 }
541
542 /*
543  * Put text into the console window
544  */
545 void Console::display_textf(const char *fmt, ...)
546 {
547    va_list arg_ptr;
548    char buf[1000];
549    int len;
550    va_start(arg_ptr, fmt);
551    len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
552    va_end(arg_ptr);
553    display_text(buf);
554 }
555
556 void Console::display_text(const QString buf)
557 {
558    m_cursor->insertText(buf);
559    update_cursor();
560 }
561
562
563 void Console::display_text(const char *buf)
564 {
565    m_cursor->insertText(buf);
566    update_cursor();
567 }
568
569 void Console::display_html(const QString buf)
570 {
571    m_cursor->insertHtml(buf);
572    update_cursor();
573 }
574
575 /* Position cursor to end of screen */
576 void Console::update_cursor()
577 {
578    m_textEdit->moveCursor(QTextCursor::End);
579    m_textEdit->ensureCursorVisible();
580 }
581
582 void Console::beginNewCommand(int conn)
583 {
584    DirComm *dircomm = m_dircommHash.value(conn);
585
586    for (int i=0; i < 3; i++) {
587       dircomm->write(".");
588       while (dircomm->read() > 0) {
589          Pmsg2(000, "begin new command loop %i %s\n", i, m_dir->name());
590          if (mainWin->m_displayAll) display_text(dircomm->msg());
591       }
592       if (dircomm->m_at_main_prompt) {
593          break;
594       }
595    }
596    display_text("\n");
597 }
598
599 void Console::displayToPrompt(int conn)
600
601    DirComm *dircomm = m_dircommHash.value(conn);
602
603    int stat = 0;
604    QString buf;
605    if (mainWin->m_commDebug) Pmsg1(000, "DisplaytoPrompt %s\n", m_dir->name());
606    while (!dircomm->m_at_prompt) {
607       if ((stat=dircomm->read()) > 0) {
608          buf += dircomm->msg();
609          if (buf.size() >= 8196 || m_messages_pending) {
610             display_text(buf);
611             buf.clear();
612             messagesPending(false);
613          }
614       }
615    }
616    display_text(buf);
617    if (mainWin->m_commDebug) Pmsg2(000, "endDisplaytoPrompt=%d %s\n", stat, m_dir->name());
618 }
619
620 void Console::discardToPrompt(int conn)
621 {
622    DirComm *dircomm = m_dircommHash.value(conn);
623
624    int stat = 0;
625    if (mainWin->m_commDebug) Pmsg1(000, "discardToPrompt %s\n", m_dir->name());
626    if (mainWin->m_displayAll) {
627       displayToPrompt(conn);
628    } else {
629       while (!dircomm->m_at_prompt) {
630          stat = dircomm->read();
631          if (stat < 0) {
632             break;
633          }
634       }
635    }
636    if (mainWin->m_commDebug) Pmsg2(000, "endDiscardToPrompt=%d %s\n", stat, m_dir->name());
637 }
638
639 /*
640  * When the notifier is enabled, read_dir() will automatically be
641  * called by the Qt event loop when ever there is any output 
642  * from the Director, and read_dir() will then display it on
643  * the console.
644  *
645  * When we are in a bat dialog, we want to control *all* output
646  * from the Director, so we set notify to off.
647  *    m_console->notifiy(false);
648  */
649
650 /* dual purpose function to turn notify off and return an available connection */
651 int Console::notifyOff()
652
653    int conn = 0;
654    if (availableDirComm(conn))
655       notify(conn, false);
656    return conn;
657 }
658
659 /* knowing a connection, turn notify off or on */
660 bool Console::notify(int conn, bool enable)
661
662    DirComm *dircomm = m_dircommHash.value(conn);
663    return dircomm->notify(enable);
664 }
665
666 /* knowing a connection, return notify state */
667 bool Console::is_notify_enabled(int conn) const
668 {
669    DirComm *dircomm = m_dircommHash.value(conn);
670    return dircomm->is_notify_enabled();
671 }
672
673 void Console::setDirectorTreeItem(QTreeWidgetItem *item)
674 {
675    m_directorTreeItem = item;
676 }
677
678 void Console::setDirRes(DIRRES *dir) 
679
680    m_dir = dir;
681 }
682
683 /*
684  * To have the ability to get the name of the director resource.
685  */
686 void Console::getDirResName(QString &name_returned)
687 {
688    name_returned = m_dir->name();
689 }
690
691 /* Slot for responding to page selectors status help command */
692 void Console::consoleHelp()
693 {
694    QString cmd("help");
695    consoleCommand(cmd);
696 }
697
698 /* Slot for responding to page selectors reload bacula-dir.conf */
699 void Console::consoleReload()
700 {
701    QString cmd("reload");
702    consoleCommand(cmd);
703 }
704
705 /* For suppressing .messages
706  * This may be rendered not needed if the multiple connections feature gets working */
707 bool Console::hasFocus()
708 {
709    if (mainWin->stackedWidget->currentIndex() == mainWin->stackedWidget->indexOf(this))
710       return true;
711    else
712       return false;
713 }
714
715 /* For adding feature to have the gui's messages button change when 
716  * messages are pending */
717 bool Console::messagesPending(bool pend)
718 {
719    bool prev = m_messages_pending;
720    m_messages_pending = pend;
721    mainWin->setMessageIcon();
722    return prev;
723 }
724
725 /* terminate all existing connections */
726 void Console::terminate()
727 {
728    foreach(DirComm* dircomm,  m_dircommHash) {
729       dircomm->terminate();
730    }
731    m_console->stopTimer();
732 }
733
734 /* Maybe this should be checking the list, for the moment lets check 0 which should be connected */
735 bool Console::is_connectedGui()
736 {
737    if (is_connected(0)) {
738       return true;
739    } else {
740       QString message = tr("Director is currently disconnected\nPlease reconnect!");
741       QMessageBox::warning(this, "Bat", message, QMessageBox::Ok );
742       return false;
743    }
744 }
745
746 int Console::read(int conn)
747 {
748    DirComm *dircomm = m_dircommHash.value(conn);
749    return dircomm->read();
750 }
751
752 char *Console::msg(int conn)
753 {
754    DirComm *dircomm = m_dircommHash.value(conn);
755    return dircomm->msg();
756 }
757
758 int Console::write(int conn, const QString msg)
759 {
760    DirComm *dircomm = m_dircommHash.value(conn);
761    mainWin->waitEnter();
762    int ret = dircomm->write(msg);
763    mainWin->waitExit();
764    return ret;
765 }
766
767 int Console::write(int conn, const char *msg)
768 {
769    DirComm *dircomm = m_dircommHash.value(conn);
770    mainWin->waitEnter();
771    int ret = dircomm->write(msg);
772    mainWin->waitExit();
773    return ret;
774 }
775
776 /* This checks to see if any is connected */
777 bool Console::is_connected()
778 {
779    bool connected = false;
780    foreach(DirComm* dircomm,  m_dircommHash) {
781       if (dircomm->is_connected())
782          return true;
783    }
784    return connected;
785 }
786
787 /* knowing the connection id, is it connected */
788 bool Console::is_connected(int conn)
789 {
790    DirComm *dircomm = m_dircommHash.value(conn);
791    return dircomm->is_connected();
792 }
793
794 /*
795  * Need an available connection.  Check existing connections or create one
796  */
797 bool Console::availableDirComm(int &conn)
798 {
799    QHash<int, DirComm*>::const_iterator iter = m_dircommHash.constBegin();
800    while (iter != m_dircommHash.constEnd()) {
801       DirComm *dircomm = iter.value();
802       if (dircomm->m_at_prompt && dircomm->m_at_main_prompt && dircomm->is_notify_enabled()) {
803          conn = dircomm->m_conn;
804          return true;
805       }
806       ++iter;
807    }
808    if (newDirComm(conn))
809       return true;
810    else
811       return false;
812 }
813
814
815 /*
816  * Need current connection.
817  */
818 bool Console::currentDirComm(int &conn)
819 {
820    QHash<int, DirComm*>::const_iterator iter = m_dircommHash.constBegin();
821    while (iter != m_dircommHash.constEnd()) {
822       DirComm *dircomm = iter.value();
823       if (dircomm->m_at_prompt && !dircomm->m_at_main_prompt && dircomm->is_notify_enabled()) {
824          conn = dircomm->m_conn;
825          return true;
826       }
827       ++iter;
828    }
829    return false;
830 }
831
832 /*
833  *  Create a new connection
834  */
835 bool Console::newDirComm(int &conn)
836 {
837    m_dircommCounter += 1;
838    conn = m_dircommCounter;
839    if (mainWin->m_connDebug)
840       Pmsg2(000, "DirComm %i About to Create and Connect %s\n", m_dircommCounter, m_dir->name());
841    DirComm *dircomm = new DirComm(this, m_dircommCounter);
842    m_dircommHash.insert(m_dircommCounter, dircomm);
843    bool success = dircomm->connect_dir();
844    if (mainWin->m_connDebug) {
845       if (success)
846          Pmsg2(000, "DirComm %i Connected %s\n", conn, m_dir->name());
847       else
848          Pmsg2(000, "DirComm %i NOT Connected %s\n", conn, m_dir->name());
849    }
850    return success;
851 }