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);
87 /* Terminate any open socket */
88 void Console::terminate()
97 * Connect to Director. If there are more than one, put up
98 * a modal dialog so that the user chooses one.
100 void Console::connect()
104 m_textEdit = textEdit; /* our console screen */
107 mainWin->set_status("No Director found.");
111 mainWin->set_status("Already connected.");
115 memset(&jcr, 0, sizeof(jcr));
117 mainWin->set_statusf(_("Connecting to Director %s:%d"), m_dir->address, m_dir->DIRport);
118 display_textf(_("Connecting to Director %s:%d\n\n"), m_dir->address, m_dir->DIRport);
120 /* Give GUI a chance */
121 app->processEvents();
124 /* If cons==NULL, default console will be used */
125 CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL);
128 m_sock = bnet_connect(NULL, 5, 15, _("Director daemon"), m_dir->address,
129 NULL, m_dir->DIRport, 0);
130 if (m_sock == NULL) {
131 mainWin->set_status("Connection failed");
134 /* Update page selector to green to indicate that Console is connected */
135 mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/connected.png")));
136 QBrush greenBrush(Qt::green);
137 m_consoleItem->setForeground(0, greenBrush);
140 jcr.dir_bsock = m_sock;
142 if (!authenticate_director(&jcr, m_dir, cons)) {
143 display_text(m_sock->msg);
147 /* Give GUI a chance */
148 app->processEvents();
150 mainWin->set_status(_("Initializing ..."));
152 /* Set up input notifier */
153 m_notifier = new QSocketNotifier(m_sock->fd, QSocketNotifier::Read, 0);
154 QObject::connect(m_notifier, SIGNAL(activated(int)), this, SLOT(read_dir(int)));
157 job_list = get_list(".jobs");
158 client_list = get_list(".clients");
159 fileset_list = get_list(".filesets");
160 messages_list = get_list(".messages");
161 pool_list = get_list(".pools");
162 storage_list = get_list(".storage");
163 type_list = get_list(".types");
164 level_list = get_list(".levels");
166 mainWin->set_status(_("Connected"));
172 * Send a command to the director, and read all the resulting
173 * output into a list.
175 QStringList Console::get_list(char *cmd)
182 while ((stat = read()) > 0) {
183 strip_trailing_junk(msg());
192 * Send a job name to the director, and read all the resulting
195 bool Console::get_job_defaults(struct job_defaults &job_defs)
204 scmd = QString(".defaults job=\"%1\"").arg(job_defs.job_name);
206 while ((stat = read()) > 0) {
207 def = strchr(msg(), '=');
211 /* Pointer to default value */
213 strip_trailing_junk(def);
215 if (strcmp(msg(), "job") == 0) {
216 if (strcmp(def, job_defs.job_name.toUtf8().data()) != 0) {
221 if (strcmp(msg(), "pool") == 0) {
222 job_defs.pool_name = def;
225 if (strcmp(msg(), "messages") == 0) {
226 job_defs.messages_name = def;
229 if (strcmp(msg(), "client") == 0) {
230 job_defs.client_name = def;
233 if (strcmp(msg(), "storage") == 0) {
234 job_defs.store_name = def;
237 if (strcmp(msg(), "where") == 0) {
238 job_defs.where = def;
241 if (strcmp(msg(), "level") == 0) {
242 job_defs.level = def;
245 if (strcmp(msg(), "type") == 0) {
249 if (strcmp(msg(), "fileset") == 0) {
250 job_defs.fileset_name = def;
253 if (strcmp(msg(), "catalog") == 0) {
254 job_defs.catalog_name = def;
257 if (strcmp(msg(), "enabled") == 0) {
258 job_defs.enabled = *def == '1' ? true : false;
262 bsnprintf(cmd, sizeof(cmd), "job=%s pool=%s client=%s storage=%s where=%s\n"
263 "level=%s type=%s fileset=%s catalog=%s enabled=%d\n",
264 job_defs.job_name.toUtf8().data(), job_defs.pool_name.toUtf8().data(),
265 job_defs.client_name.toUtf8().data(),
266 job_defs.pool_name.toUtf8().data(), job_defs.messages_name.toUtf8().data(),
267 job_defs.store_name.toUtf8().data(),
268 job_defs.where.toUtf8().data(), job_defs.level.toUtf8().data(),
269 job_defs.type.toUtf8().data(), job_defs.fileset_name.toUtf8().data(),
270 job_defs.catalog_name.toUtf8().data(), job_defs.enabled);
282 * Save user settings associated with this console
284 void Console::writeSettings()
286 QFont font = get_font();
288 QSettings settings("bacula.org", "bat");
289 /* ***FIXME*** make console name unique */
290 settings.beginGroup("Console");
291 settings.setValue("consoleFont", font.family());
292 settings.setValue("consolePointSize", font.pointSize());
293 settings.setValue("consoleFixedPitch", font.fixedPitch());
298 * Read and restore user settings associated with this console
300 void Console::readSettings()
302 QFont font = get_font();
304 QSettings settings("bacula.org", "bat");
305 settings.beginGroup("Console");
306 font.setFamily(settings.value("consoleFont", "Courier").value<QString>());
307 font.setPointSize(settings.value("consolePointSize", 10).toInt());
308 font.setFixedPitch(settings.value("consoleFixedPitch", true).toBool());
310 m_textEdit->setFont(font);
314 * Set the console textEdit font
316 void Console::set_font()
319 QFont font = QFontDialog::getFont(&ok, QFont(m_textEdit->font()), this);
321 m_textEdit->setFont(font);
326 * Get the console text edit font
328 const QFont Console::get_font()
330 return m_textEdit->font();
334 void Console::status_dir()
336 write_dir("status dir\n");
340 * Put text into the console window
342 void Console::display_textf(const char *fmt, ...)
347 va_start(arg_ptr, fmt);
348 len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
353 void Console::display_text(const QString buf)
355 m_cursor->movePosition(QTextCursor::End);
356 m_cursor->insertText(buf);
360 void Console::display_text(const char *buf)
362 m_cursor->movePosition(QTextCursor::End);
363 m_cursor->insertText(buf);
366 /* Position cursor to end of screen */
367 void Console::update_cursor()
369 QApplication::restoreOverrideCursor();
370 m_textEdit->moveCursor(QTextCursor::End);
371 m_textEdit->ensureCursorVisible();
375 * This should be moved into a bSocket class
385 /* Send a command to the Director */
386 void Console::write_dir(const char *msg)
390 mainWin->set_status(_("Processing command ..."));
391 QApplication::setOverrideCursor(Qt::WaitCursor);
392 m_sock->msglen = strlen(msg);
393 pm_strcpy(&m_sock->msg, msg);
396 mainWin->set_status(" Director not connected. Click on connect button.");
397 mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/disconnected.png")));
398 QBrush redBrush(Qt::red);
399 m_consoleItem->setForeground(0, redBrush);
403 int Console::write(const QString msg)
405 return write(msg.toUtf8().data());
408 int Console::write(const char *msg)
410 m_sock->msglen = strlen(msg);
411 pm_strcpy(&m_sock->msg, msg);
412 return m_sock->send();
416 * Get to main command prompt
418 void Console::beginNewCommand()
420 // displayToPrompt();
433 void Console::displayToPrompt()
442 * Blocking read from director */
448 stat = bnet_wait_data_intr(m_sock, 1);
452 app->processEvents();
457 return m_sock->recv();
462 /* Called by signal when the Director has output for us */
463 void Console::read_dir(int fd)
480 if (is_bnet_stop(m_sock)) { /* error or term request */
483 mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/disconnected.png")));
484 QBrush redBrush(Qt::red);
485 m_consoleItem->setForeground(0, redBrush);
486 m_notifier->setEnabled(false);
489 mainWin->set_status(_("Director disconnected."));
490 QApplication::restoreOverrideCursor();
493 /* Must be a signal -- either do something or ignore it */
494 if (m_sock->msglen == BNET_PROMPT) {
496 mainWin->set_status(_("At prompt waiting for input ..."));
499 if (m_sock->msglen == BNET_EOD) {
500 mainWin->set_status_ready();