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