]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/console/console.cpp
25a5b1305f8ad730c97b44572043cf713af7ef84
[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()){
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 /* Send a command to the Director */
306 int Console::write_dir(const char *msg)
307 {
308    int conn;
309    if(availableDirComm(conn))
310       write_dir(conn, msg);
311    return conn;
312 }
313
314 /* Send a command to the Director */
315 void Console::write_dir(int conn, const char *msg)
316 {
317    DirComm *dircomm = m_dircommHash.value(conn);
318
319    if (dircomm->m_sock) {
320       mainWin->set_status(_("Processing command ..."));
321       mainWin->waitEnter();
322       dircomm->write(msg);
323       mainWin->waitExit();
324    } else {
325       mainWin->set_status( tr(" Director not connected. Click on connect button."));
326       mainWin->actionConnect->setIcon(QIcon(":images/disconnected.png"));
327       QBrush redBrush(Qt::red);
328       QTreeWidgetItem *item = mainWin->getFromHash(this);
329       item->setForeground(0, redBrush);
330       dircomm->m_at_prompt = false;
331       dircomm->m_at_main_prompt = false;
332    }
333 }
334
335 /*
336  * get_job_defaults overload
337  */
338 bool Console::get_job_defaults(struct job_defaults &job_defs)
339 {
340    int conn;
341    return get_job_defaults(conn, job_defs, true);
342 }
343
344 bool Console::get_job_defaults(int &conn, struct job_defaults &job_defs)
345 {
346    return get_job_defaults(conn, job_defs, false);
347 }
348
349 /*  
350  * Send a job name to the director, and read all the resulting
351  *  defaults. 
352  */
353 bool Console::get_job_defaults(int &conn, struct job_defaults &job_defs, bool donotify)
354 {
355    QString scmd;
356    int stat;
357    char *def;
358
359    if (donotify)
360       conn = notifyOff();
361    beginNewCommand(conn);
362    DirComm *dircomm = m_dircommHash.value(conn);
363    bool prevWaitState = mainWin->getWaitState();
364    if (!prevWaitState)
365       mainWin->waitEnter();
366    if (mainWin->m_connDebug)
367       Pmsg2(000, "job_defaults conn %i %s\n", conn, m_dir->name());
368    scmd = QString(".defaults job=\"%1\"").arg(job_defs.job_name);
369    dircomm->write(scmd);
370    while ((stat = dircomm->read()) > 0) {
371       if (mainWin->m_displayAll) display_text(dircomm->msg());
372       def = strchr(dircomm->msg(), '=');
373       if (!def) {
374          continue;
375       }
376       /* Pointer to default value */
377       *def++ = 0;
378       strip_trailing_junk(def);
379
380       if (strcmp(dircomm->msg(), "job") == 0) {
381          if (strcmp(def, job_defs.job_name.toUtf8().data()) != 0) {
382             goto bail_out;
383          }
384          continue;
385       }
386       if (strcmp(dircomm->msg(), "pool") == 0) {
387          job_defs.pool_name = def;
388          continue;
389       }
390       if (strcmp(dircomm->msg(), "messages") == 0) {
391          job_defs.messages_name = def;
392          continue;
393       }
394       if (strcmp(dircomm->msg(), "client") == 0) {
395          job_defs.client_name = def;
396          continue;
397       }
398       if (strcmp(dircomm->msg(), "storage") == 0) {
399          job_defs.store_name = def;
400          continue;
401       }
402       if (strcmp(dircomm->msg(), "where") == 0) {
403          job_defs.where = def;
404          continue;
405       }
406       if (strcmp(dircomm->msg(), "level") == 0) {
407          job_defs.level = def;
408          continue;
409       }
410       if (strcmp(dircomm->msg(), "type") == 0) {
411          job_defs.type = def;
412          continue;
413       }
414       if (strcmp(dircomm->msg(), "fileset") == 0) {
415          job_defs.fileset_name = def;
416          continue;
417       }
418       if (strcmp(dircomm->msg(), "catalog") == 0) {
419          job_defs.catalog_name = def;
420          continue;
421       }
422       if (strcmp(dircomm->msg(), "enabled") == 0) {
423          job_defs.enabled = *def == '1' ? true : false;
424          continue;
425       }
426    }
427
428    if (donotify)
429       notify(conn, true);
430    if (!prevWaitState)
431       mainWin->waitExit();
432    return true;
433
434 bail_out:
435    if (donotify)
436       notify(conn, true);
437    if (!prevWaitState)
438       mainWin->waitExit();
439    return false;
440 }
441
442
443 /*
444  * Save user settings associated with this console
445  */
446 void Console::writeSettings()
447 {
448    QFont font = get_font();
449
450    QSettings settings(m_dir->name(), "bat");
451    settings.beginGroup("Console");
452    settings.setValue("consoleFont", font.family());
453    settings.setValue("consolePointSize", font.pointSize());
454    settings.setValue("consoleFixedPitch", font.fixedPitch());
455    settings.endGroup();
456 }
457
458 /*
459  * Read and restore user settings associated with this console
460  */
461 void Console::readSettings()
462
463    QFont font = get_font();
464
465    QSettings settings(m_dir->name(), "bat");
466    settings.beginGroup("Console");
467    font.setFamily(settings.value("consoleFont", "Courier").value<QString>());
468    font.setPointSize(settings.value("consolePointSize", 10).toInt());
469    font.setFixedPitch(settings.value("consoleFixedPitch", true).toBool());
470    settings.endGroup();
471    m_textEdit->setFont(font);
472 }
473
474 /*
475  * Set the console textEdit font
476  */
477 void Console::set_font()
478 {
479    bool ok;
480    QFont font = QFontDialog::getFont(&ok, QFont(m_textEdit->font()), this);
481    if (ok) {
482       m_textEdit->setFont(font);
483    }
484 }
485
486 /*
487  * Get the console text edit font
488  */
489 const QFont Console::get_font()
490 {
491    return m_textEdit->font();
492 }
493
494 /*
495  * Slot for responding to status dir button on button bar
496  */
497 void Console::status_dir()
498 {
499    QString cmd("status dir");
500    consoleCommand(cmd);
501 }
502
503 /*
504  * Slot for responding to messages button on button bar
505  * Here we want to bring the console to the front so use pages' consoleCommand
506  */
507 void Console::messages()
508 {
509    QString cmd(".messages");
510    consoleCommand(cmd);
511    messagesPending(false);
512 }
513
514 /*
515  * Put text into the console window
516  */
517 void Console::display_textf(const char *fmt, ...)
518 {
519    va_list arg_ptr;
520    char buf[1000];
521    int len;
522    va_start(arg_ptr, fmt);
523    len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
524    va_end(arg_ptr);
525    display_text(buf);
526 }
527
528 void Console::display_text(const QString buf)
529 {
530    m_cursor->insertText(buf);
531    update_cursor();
532 }
533
534
535 void Console::display_text(const char *buf)
536 {
537    m_cursor->insertText(buf);
538    update_cursor();
539 }
540
541 void Console::display_html(const QString buf)
542 {
543    m_cursor->insertHtml(buf);
544    update_cursor();
545 }
546
547 /* Position cursor to end of screen */
548 void Console::update_cursor()
549 {
550 //   QApplication::restoreOverrideCursor();
551    m_textEdit->moveCursor(QTextCursor::End);
552    m_textEdit->ensureCursorVisible();
553 }
554
555 void Console::beginNewCommand(int conn)
556 {
557    DirComm *dircomm = m_dircommHash.value(conn);
558
559    for (int i=0; i < 3; i++) {
560       dircomm->write(".");
561       while (dircomm->read() > 0) {
562          Pmsg2(000, "begin new command loop %i %s\n", i, m_dir->name());
563          if (mainWin->m_displayAll) display_text(dircomm->msg());
564       }
565       if (dircomm->m_at_main_prompt) {
566          break;
567       }
568    }
569    display_text("\n");
570 }
571
572 void Console::displayToPrompt(int conn)
573
574    DirComm *dircomm = m_dircommHash.value(conn);
575
576    int stat = 0;
577    QString buf;
578    if (mainWin->m_commDebug) Pmsg1(000, "DisplaytoPrompt %s\n", m_dir->name());
579    while (!dircomm->m_at_prompt) {
580       if ((stat=dircomm->read()) > 0) {
581          buf += dircomm->msg();
582          if (buf.size() >= 8196 || m_messages_pending) {
583             display_text(buf);
584             buf.clear();
585             messagesPending(false);
586          }
587       }
588    }
589    display_text(buf);
590    if (mainWin->m_commDebug) Pmsg2(000, "endDisplaytoPrompt=%d %s\n", stat, m_dir->name());
591 }
592
593 void Console::discardToPrompt(int conn)
594 {
595    DirComm *dircomm = m_dircommHash.value(conn);
596
597    int stat = 0;
598    if (mainWin->m_commDebug) Pmsg1(000, "discardToPrompt %s\n", m_dir->name());
599    if (mainWin->m_displayAll) {
600       displayToPrompt(conn);
601    } else {
602       while (!dircomm->m_at_prompt) {
603          stat=dircomm->read();
604       }
605    }
606    if (mainWin->m_commDebug) Pmsg2(000, "endDiscardToPrompt=%d %s\n", stat, m_dir->name());
607 }
608
609 /*
610  * When the notifier is enabled, read_dir() will automatically be
611  * called by the Qt event loop when ever there is any output 
612  * from the Directory, and read_dir() will then display it on
613  * the console.
614  *
615  * When we are in a bat dialog, we want to control *all* output
616  * from the Directory, so we set notify to off.
617  *    m_console->notifiy(false);
618  */
619
620 /* dual purpose function to turn notify off and return an available connection */
621 int Console::notifyOff()
622
623    int conn = 0;
624    if(availableDirComm(conn))
625       notify(conn, false);
626    return conn;
627 }
628
629 /* knowing a connection, turn notify off or on */
630 bool Console::notify(int conn, bool enable)
631
632    DirComm *dircomm = m_dircommHash.value(conn);
633    return dircomm->notify(enable);
634 }
635
636 /* knowing a connection, return notify state */
637 bool Console::is_notify_enabled(int conn) const
638 {
639    DirComm *dircomm = m_dircommHash.value(conn);
640    return dircomm->is_notify_enabled();
641 }
642
643 void Console::setDirectorTreeItem(QTreeWidgetItem *item)
644 {
645    m_directorTreeItem = item;
646 }
647
648 void Console::setDirRes(DIRRES *dir) 
649
650    m_dir = dir;
651 }
652
653 /*
654  * To have the ability to get the name of the director resource.
655  */
656 void Console::getDirResName(QString &name_returned)
657 {
658    name_returned = m_dir->name();
659 }
660
661 /* Slot for responding to page selectors status help command */
662 void Console::consoleHelp()
663 {
664    QString cmd("help");
665    consoleCommand(cmd);
666 }
667
668 /* Slot for responding to page selectors reload bacula-dir.conf */
669 void Console::consoleReload()
670 {
671    QString cmd("reload");
672    consoleCommand(cmd);
673 }
674
675 /* For suppressing .messages
676  * This may be rendered not needed if the multiple connections feature gets working */
677 bool Console::hasFocus()
678 {
679    if (mainWin->stackedWidget->currentIndex() == mainWin->stackedWidget->indexOf(this))
680       return true;
681    else
682       return false;
683 }
684
685 /* For adding feature to have the gui's messages button change when 
686  * messages are pending */
687 bool Console::messagesPending(bool pend)
688 {
689    bool prev = m_messages_pending;
690    m_messages_pending = pend;
691    mainWin->setMessageIcon();
692    return prev;
693 }
694
695 /* terminate all existing connections */
696 void Console::terminate()
697 {
698    foreach(DirComm* dircomm,  m_dircommHash) {
699       dircomm->terminate();
700    }
701    m_console->stopTimer();
702 }
703
704 /* Maybe this should be checking the list, for the moment lets check 0 which should be connected */
705 bool Console::is_connectedGui()
706 {
707    if (is_connected(0)) {
708       return true;
709    } else {
710       QString message = tr("Director is currently disconnected\nPlease reconnect!");
711       QMessageBox::warning(this, "Bat", message, QMessageBox::Ok );
712       return false;
713    }
714 }
715
716 int Console::read(int conn)
717 {
718    DirComm *dircomm = m_dircommHash.value(conn);
719    return dircomm->read();
720 }
721
722 char *Console::msg(int conn)
723 {
724    DirComm *dircomm = m_dircommHash.value(conn);
725    return dircomm->msg();
726 }
727
728 int Console::write(int conn, const QString msg)
729 {
730    DirComm *dircomm = m_dircommHash.value(conn);
731    mainWin->waitEnter();
732    int ret = dircomm->write(msg);
733    mainWin->waitExit();
734    return ret;
735 }
736
737 int Console::write(int conn, const char *msg)
738 {
739    DirComm *dircomm = m_dircommHash.value(conn);
740    mainWin->waitEnter();
741    int ret = dircomm->write(msg);
742    mainWin->waitExit();
743    return ret;
744 }
745
746 /* This checks to see if any is connected */
747 bool Console::is_connected()
748 {
749    bool connected = false;
750    foreach(DirComm* dircomm,  m_dircommHash) {
751       if (dircomm->is_connected())
752          return true;
753    }
754    return connected;
755 }
756
757 /* knowing the connection id, is it connected */
758 bool Console::is_connected(int conn)
759 {
760    DirComm *dircomm = m_dircommHash.value(conn);
761    return dircomm->is_connected();
762 }
763
764 /*
765  * Need an available connection.  Check existing connections or create one
766  */
767 bool Console::availableDirComm(int &conn)
768 {
769    QHash<int, DirComm*>::const_iterator iter = m_dircommHash.constBegin();
770    while (iter != m_dircommHash.constEnd()) {
771       DirComm *dircomm = iter.value();
772       if (dircomm->m_at_prompt && dircomm->m_at_main_prompt && dircomm->is_notify_enabled()) {
773          conn = dircomm->m_conn;
774          return true;
775       }
776       ++iter;
777    }
778    if (newDirComm(conn))
779       return true;
780    else
781       return false;
782 }
783
784 /*
785  *  Create a new connection
786  */
787 bool Console::newDirComm(int &conn)
788 {
789    m_dircommCounter += 1;
790    conn = m_dircommCounter;
791    if (mainWin->m_connDebug)
792       Pmsg2(000, "DirComm %i About to Create and Connect %s\n", m_dircommCounter, m_dir->name());
793    DirComm *dircomm = new DirComm(this, m_dircommCounter);
794    m_dircommHash.insert(m_dircommCounter, dircomm);
795    bool success = dircomm->connect_dir();
796    if (mainWin->m_connDebug) {
797       if (success)
798          Pmsg2(000, "DirComm %i Connected %s\n", conn, m_dir->name());
799       else
800          Pmsg2(000, "DirComm %i NOT Connected %s\n", conn, m_dir->name());
801    }
802    return success;
803 }