2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2007 Free Software Foundation Europe e.V.
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 plus additions
11 that are listed in the file LICENSE.
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.
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
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.
34 * Kern Sibbald, January MMVI
38 #include <QAbstractEventDispatcher>
42 Console::Console(QStackedWidget *parent)
45 QTreeWidgetItem *item, *topItem;
46 QTreeWidget *treeWidget = mainWin->treeWidget;
49 parent->addWidget(this);
52 m_textEdit = textEdit; /* our console screen */
53 m_cursor = new QTextCursor(m_textEdit->document());
54 mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/disconnected.png")));
56 bRestore *brestore = new bRestore(parent);
57 brestore->setupUi(brestore);
58 parent->addWidget(brestore);
60 /* Just take the first Director */
62 m_dir = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
65 /* ***FIXME*** Dummy setup of treeWidget */
67 treeWidget->setColumnCount(1);
68 treeWidget->setHeaderLabel("Selection");
69 topItem = new QTreeWidgetItem(treeWidget);
70 topItem->setText(0, m_dir->name());
71 topItem->setIcon(0, QIcon(QString::fromUtf8("images/server.png")));
72 item = new QTreeWidgetItem(topItem);
74 item->setText(0, "Console");
75 item->setText(1, "0");
76 QBrush redBrush(Qt::red);
77 item->setForeground(0, redBrush);
78 item = new QTreeWidgetItem(topItem);
79 item->setText(0, "brestore");
80 item->setText(1, "1");
81 treeWidget->expandItem(topItem);
88 * Connect to Director. If there are more than one, put up
89 * a modal dialog so that the user chooses one.
91 void Console::connect()
95 m_textEdit = textEdit; /* our console screen */
98 mainWin->set_status(" No Director found.");
102 mainWin->set_status(" Already connected.");
106 memset(&jcr, 0, sizeof(jcr));
108 mainWin->set_statusf(_(" Connecting to Director %s:%d"), m_dir->address, m_dir->DIRport);
109 set_textf(_("Connecting to Director %s:%d\n\n"), m_dir->address, m_dir->DIRport);
111 /* Give GUI a chance */
112 app->processEvents();
115 /* If cons==NULL, default console will be used */
116 CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL);
119 m_sock = bnet_connect(NULL, 5, 15, _("Director daemon"), m_dir->address,
120 NULL, m_dir->DIRport, 0);
121 if (m_sock == NULL) {
122 mainWin->set_status("Connection failed");
125 /* Update page selector to green to indicate that Console is connected */
126 mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/connected.png")));
127 QBrush greenBrush(Qt::green);
128 m_consoleItem->setForeground(0, greenBrush);
131 jcr.dir_bsock = m_sock;
133 if (!authenticate_director(&jcr, m_dir, cons)) {
134 set_text(m_sock->msg);
138 /* Give GUI a chance */
139 app->processEvents();
141 mainWin->set_status(_(" Initializing ..."));
143 /* Set up input notifier */
144 m_notifier = new QSocketNotifier(m_sock->fd, QSocketNotifier::Read, 0);
145 QObject::connect(m_notifier, SIGNAL(activated(int)), this, SLOT(read_dir(int)));
147 job_list = get_list(".jobs");
148 client_list = get_list(".clients");
149 fileset_list = get_list(".filesets");
150 messages_list = get_list(".messages");
151 pool_list = get_list(".pools");
152 storage_list = get_list(".storage");
153 type_list = get_list(".types");
154 level_list = get_list(".levels");
156 mainWin->set_status(_(" Connected"));
162 * Send a command to the director, and read all the resulting
163 * output into a list.
165 QStringList Console::get_list(char *cmd)
172 while ((stat = read()) > 0) {
173 strip_trailing_junk(msg());
182 * Send a job name to the director, and read all the resulting
185 bool Console::get_job_defaults(struct job_defaults &job_defs)
192 bsnprintf(cmd, sizeof(cmd), ".defaults job=\"%s\"", job_defs.job_name);
194 while ((stat = read()) > 0) {
195 def = strchr(msg(), '=');
199 /* Pointer to default value */
201 strip_trailing_junk(def);
203 if (strcmp(msg(), "job") == 0) {
204 if (strcmp(def, job_defs.job_name) != 0) {
209 if (strcmp(msg(), "pool") == 0) {
210 bstrncpy(job_defs.pool_name, def, sizeof(job_defs.pool_name));
213 if (strcmp(msg(), "messages") == 0) {
214 bstrncpy(job_defs.messages_name, def, sizeof(job_defs.messages_name));
217 if (strcmp(msg(), "client") == 0) {
218 bstrncpy(job_defs.client_name, def, sizeof(job_defs.client_name));
221 if (strcmp(msg(), "storage") == 0) {
222 bstrncpy(job_defs.store_name, def, sizeof(job_defs.store_name));
225 if (strcmp(msg(), "where") == 0) {
226 bstrncpy(job_defs.where, def, sizeof(job_defs.where));
229 if (strcmp(msg(), "level") == 0) {
230 bstrncpy(job_defs.level, def, sizeof(job_defs.level));
233 if (strcmp(msg(), "type") == 0) {
234 bstrncpy(job_defs.type, def, sizeof(job_defs.type));
237 if (strcmp(msg(), "fileset") == 0) {
238 bstrncpy(job_defs.fileset_name, def, sizeof(job_defs.fileset_name));
241 if (strcmp(msg(), "catalog") == 0) {
242 bstrncpy(job_defs.catalog_name, def, sizeof(job_defs.catalog_name));
245 if (strcmp(msg(), "enabled") == 0) {
246 job_defs.enabled = *def == '1' ? true : false;
250 bsnprintf(cmd, sizeof(cmd), "job=%s pool=%s client=%s storage=%s where=%s\n"
251 "level=%s type=%s fileset=%s catalog=%s enabled=%d\n",
252 job_defs.job_name, job_defs.pool_name, job_defs.client_name,
253 job_defs.pool_name, job_defs.messages_name, job_defs.store_name,
254 job_defs.where, job_defs.level, job_defs.type, job_defs.fileset_name,
255 job_defs.catalog_name, job_defs.enabled);
269 void Console::writeSettings()
271 QFont font = get_font();
273 QSettings settings("bacula.org", "bat");
274 settings.beginGroup("Console");
275 settings.setValue("consoleFont", font.family());
276 settings.setValue("consolePointSize", font.pointSize());
277 settings.setValue("consoleFixedPitch", font.fixedPitch());
282 * Read and restore user settings
284 void Console::readSettings()
286 QFont font = get_font();
288 QSettings settings("bacula.org", "bat");
289 settings.beginGroup("Console");
290 font.setFamily(settings.value("consoleFont", "Courier").value<QString>());
291 font.setPointSize(settings.value("consolePointSize", 10).toInt());
292 font.setFixedPitch(settings.value("consoleFixedPitch", true).toBool());
294 m_textEdit->setFont(font);
298 * Set the console textEdit font
300 void Console::set_font()
303 QFont font = QFontDialog::getFont(&ok, QFont(m_textEdit->font()), this);
305 m_textEdit->setFont(font);
310 * Get the console text edit font
312 const QFont Console::get_font()
314 return m_textEdit->font();
318 void Console::status_dir()
320 write_dir("status dir\n");
324 * Put text into the console window
326 void Console::set_textf(const char *fmt, ...)
331 va_start(arg_ptr, fmt);
332 len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
337 void Console::set_text(const QString buf)
339 m_cursor->movePosition(QTextCursor::End);
340 m_cursor->insertText(buf);
344 void Console::set_text(const char *buf)
346 m_cursor->movePosition(QTextCursor::End);
347 m_cursor->insertText(buf);
350 /* Position cursor to end of screen */
351 void Console::update_cursor()
353 QApplication::restoreOverrideCursor();
354 m_textEdit->moveCursor(QTextCursor::End);
355 m_textEdit->ensureCursorVisible();
359 * This should be moved into a bSocket class
369 /* Send a command to the Director */
370 void Console::write_dir(const char *msg)
374 mainWin->set_status(_(" Processing command ..."));
375 QApplication::setOverrideCursor(Qt::WaitCursor);
376 m_sock->msglen = strlen(msg);
377 pm_strcpy(&m_sock->msg, msg);
380 mainWin->set_status(" Director not connected. Click on connect button.");
381 mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/disconnected.png")));
382 QBrush redBrush(Qt::red);
383 m_consoleItem->setForeground(0, redBrush);
387 int Console::write(const char *msg)
389 m_sock->msglen = strlen(msg);
390 pm_strcpy(&m_sock->msg, msg);
391 return bnet_send(m_sock);
395 * Blocking read from director */
401 stat = bnet_wait_data_intr(m_sock, 1);
405 app->processEvents();
410 return bnet_recv(m_sock);
415 /* Called by signal when the Director has output for us */
416 void Console::read_dir(int fd)
424 stat = bnet_recv(m_sock);
430 set_text(m_sock->msg);
433 if (is_bnet_stop(m_sock)) { /* error or term request */
436 mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/disconnected.png")));
437 QBrush redBrush(Qt::red);
438 m_consoleItem->setForeground(0, redBrush);
439 m_notifier->setEnabled(false);
442 mainWin->set_status(_(" Director disconnected."));
443 QApplication::restoreOverrideCursor();
446 /* Must be a signal -- either do something or ignore it */
447 if (m_sock->msglen == BNET_PROMPT) {
449 mainWin->set_status(_(" At prompt waiting for input ..."));
452 if (m_sock->msglen == BNET_EOD) {
453 mainWin->set_status_ready();