]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/console/console.cpp
5af0c86096c1b5d1666cdeaea1d9e6ef0dfa43bc
[bacula/bacula] / bacula / src / qt-console / console / console.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2000-2007 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 plus additions
11    that are listed 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 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.
27 */
28  
29 /*
30  *  Console Class
31  *
32  *   Kern Sibbald, January MMVI
33  *
34  */ 
35
36 #include <QAbstractEventDispatcher>
37 #include "bat.h"
38 #include "console.h"
39
40 Console::Console()
41 {
42    QFont font;
43    QTreeWidgetItem *item, *topItem;
44    QTreeWidget *treeWidget = mainWin->treeWidget;
45
46    m_sock = NULL;
47    m_at_prompt = false;
48    m_textEdit = mainWin->textEdit;   /* our console screen */
49    m_cursor = new QTextCursor(m_textEdit->document());
50    mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/disconnected.png")));
51
52    /* ***FIXME*** make this configurable */
53    font.setFamily("Courier");
54    font.setFixedPitch(true);
55    font.setPointSize(10);
56    m_textEdit->setFont(font);
57
58    /* Just take the first Director */
59    LockRes();
60    m_dir = (DIRRES *)GetNextRes(R_DIRECTOR, NULL);
61    UnlockRes();
62
63    /* Dummy setup of treeWidget */
64    treeWidget->clear();
65    treeWidget->setColumnCount(1);
66    treeWidget->setHeaderLabel("Selection");
67    topItem = new QTreeWidgetItem(treeWidget);
68    topItem->setText(0, m_dir->name());
69    topItem->setIcon(0, QIcon(QString::fromUtf8("images/server.png")));
70    item = new QTreeWidgetItem(topItem);
71    m_consoleItem = item;
72    item->setText(0, "Console");
73    item->setText(1, "0");
74    QBrush redBrush(Qt::red);
75    item->setForeground(0, redBrush);
76    item = new QTreeWidgetItem(topItem);
77    item->setText(0, "Restore");
78    item->setText(1, "1");
79    treeWidget->expandItem(topItem);
80 }
81
82 /*
83  * Connect to Director. If there are more than one, put up
84  * a modal dialog so that the user chooses one.
85  */
86 void Console::connect()
87 {
88    JCR jcr;
89
90    m_textEdit = mainWin->textEdit;   /* our console screen */
91
92    if (!m_dir) {          
93       mainWin->set_status("No Director found.");
94       return;
95    }
96    if (m_sock) {
97       mainWin->set_status("Already connected.");
98       return;
99    }
100
101    memset(&jcr, 0, sizeof(jcr));
102
103    mainWin->set_statusf(_(" Connecting to Director %s:%d"), m_dir->address, m_dir->DIRport);
104    set_textf(_("Connecting to Director %s:%d\n\n"), m_dir->address, m_dir->DIRport);
105
106    /* Give GUI a chance */
107    app->processEvents();
108    
109    LockRes();
110    /* If cons==NULL, default console will be used */
111    CONRES *cons = (CONRES *)GetNextRes(R_CONSOLE, (RES *)NULL);
112    UnlockRes();
113
114    m_sock = bnet_connect(NULL, 5, 15, _("Director daemon"), m_dir->address,
115                           NULL, m_dir->DIRport, 0);
116    if (m_sock == NULL) {
117       mainWin->set_status("Connection failed");
118       return;
119    } else {
120       /* Update page selector to green to indicate that Console is connected */
121       mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/connected.png")));
122       QBrush greenBrush(Qt::green);
123       m_consoleItem->setForeground(0, greenBrush);
124    }
125
126    jcr.dir_bsock = m_sock;
127
128    if (!authenticate_director(&jcr, m_dir, cons)) {
129       set_text(m_sock->msg);
130       return;
131    }
132
133    /* Give GUI a chance */
134    app->processEvents();
135
136    mainWin->set_status(_(" Initializing ..."));
137
138    bnet_fsend(m_sock, "autodisplay on");
139
140    /* Set up input notifier */
141    m_notifier = new QSocketNotifier(m_sock->fd, QSocketNotifier::Read, 0);
142    QObject::connect(m_notifier, SIGNAL(activated(int)), this, SLOT(read_dir(int)));
143
144    /* Give GUI a chance */
145    app->processEvents();
146
147    /*  *** FIXME *** 
148     * Query Directory for .jobs, .clients, .filesets, .msgs,
149     *  .pools, .storage, .types, .levels, ...
150     */
151
152    mainWin->set_status(_(" Connected"));
153    return;
154 }
155
156 void Console::status_dir()
157 {
158    write_dir("status dir\n");
159 }
160
161 void Console::set_textf(const char *fmt, ...)
162 {
163    va_list arg_ptr;
164    char buf[1000];
165    int len;
166    va_start(arg_ptr, fmt);
167    len = bvsnprintf(buf, sizeof(buf), fmt, arg_ptr);
168    va_end(arg_ptr);
169    set_text(buf);
170 }
171
172 void Console::set_text(const QString buf)
173 {
174    m_cursor->movePosition(QTextCursor::End);
175    m_cursor->insertText(buf);
176 }
177
178
179 void Console::set_text(const char *buf)
180 {
181    m_cursor->movePosition(QTextCursor::End);
182    m_cursor->insertText(buf);
183 }
184
185 /* Position cursor to end of screen */
186 void Console::update_cursor()
187 {
188    QApplication::restoreOverrideCursor();
189    m_textEdit->moveCursor(QTextCursor::End);
190    m_textEdit->ensureCursorVisible();
191 }
192
193
194 /* Send a command to the Director */
195 void Console::write_dir(const char *msg)
196 {
197    if (m_sock) {
198       m_at_prompt = false;
199       mainWin->set_status(_(" Processing command ..."));
200       QApplication::setOverrideCursor(Qt::WaitCursor);
201       m_sock->msglen = strlen(msg);
202       pm_strcpy(&m_sock->msg, msg);
203       bnet_send(m_sock);
204    } else {
205       mainWin->set_status(" Director not connected. Click on connect button.");
206       mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/disconnected.png")));
207       QBrush redBrush(Qt::red);
208       m_consoleItem->setForeground(0, redBrush);
209    }
210 }
211
212 /* Called by signal when the Director has output for us */
213 void Console::read_dir(int fd)
214 {
215    int stat;
216    (void)fd;
217
218    if (!m_sock) {
219       return;
220    }
221    stat = bnet_recv(m_sock);
222    if (stat >= 0) {
223       if (m_at_prompt) {
224          set_text("\n");
225          m_at_prompt = false;
226       }
227       set_text(m_sock->msg);
228       return;
229    }
230    if (is_bnet_stop(m_sock)) {         /* error or term request */
231       bnet_close(m_sock);
232       m_sock = NULL;
233       mainWin->actionConnect->setIcon(QIcon(QString::fromUtf8("images/disconnected.png")));
234       QBrush redBrush(Qt::red);
235       m_consoleItem->setForeground(0, redBrush);
236       m_notifier->setEnabled(false);
237       delete m_notifier;
238       m_notifier = NULL;
239       mainWin->set_status(_(" Director disconnected."));
240       QApplication::restoreOverrideCursor();
241       return;
242    }
243    /* Must be a signal -- either do something or ignore it */
244    if (m_sock->msglen == BNET_PROMPT) {
245       m_at_prompt = true;
246       mainWin->set_status(_(" At prompt waiting for input ..."));
247       update_cursor();
248    }
249    if (m_sock->msglen == BNET_EOD) {
250       mainWin->set_status_ready();
251       update_cursor();
252    }
253    return;
254 }
255
256 #ifdef xxx
257
258 static gint tag;
259
260 void start_director_reader(gpointer data)
261 {
262
263    if (director_reader_running || !UA_sock) {
264       return;
265    }
266    tag = gdk_input_add(UA_sock->fd, GDK_INPUT_READ, read_director, NULL);
267    director_reader_running = true;
268 }
269
270 void stop_director_reader(gpointer data)
271 {
272    if (!director_reader_running) {
273       return;
274    }
275    gdk_input_remove(tag);
276    director_reader_running = false;
277 }
278 #endif