]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/qt-console/restore/restore.cpp
kes Implement posix_fadvise in FD, and for reading spool files in SD.
[bacula/bacula] / bacula / src / qt-console / restore / restore.cpp
1 /*
2    Bacula® - The Network Backup Solution
3
4    Copyright (C) 2007-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  *   Version $Id$
31  *
32  *  Restore Class 
33  *
34  *   Kern Sibbald, February MMVII
35  *
36  */ 
37
38 #include "bat.h"
39 #include "restore.h"
40
41 restoreDialog::restoreDialog(Console *console )
42 {
43    QStringList titles;
44
45    m_console = console;
46    m_console->notify(false);          /* this should already be off */
47
48    setupUi(this);
49    connect(fileWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), 
50            this, SLOT(fileDoubleClicked(QTreeWidgetItem *, int)));
51    connect(upButton, SIGNAL(pressed()), this, SLOT(upButtonPushed()));
52    connect(markButton, SIGNAL(pressed()), this, SLOT(markButtonPushed()));
53    connect(unmarkButton, SIGNAL(pressed()), this, SLOT(unmarkButtonPushed()));
54    setFont(m_console->get_font());
55    m_console->displayToPrompt();
56
57
58    titles << "Mark" << "File" << "Mode" << "User" << "Group" << "Size" << "Date";
59    fileWidget->setHeaderLabels(titles);
60
61    get_cwd();
62    fillDirectory();
63    this->show();
64 }
65
66 /*
67  * Fill the fileWidget box with the contents of the current directory
68  */
69 void restoreDialog::fillDirectory()
70 {
71    char modes[20], user[20], group[20], size[20], date[30];
72    char marked[10];
73    int pnl, fnl;
74    POOLMEM *file = get_pool_memory(PM_FNAME);
75    POOLMEM *path = get_pool_memory(PM_FNAME);
76
77    fileWidget->clear();
78    m_console->write_dir("dir");
79    QList<QTreeWidgetItem *> items;
80    QStringList item;
81    while (m_console->read() > 0) {
82       char *p = m_console->msg();
83       char *l;
84       strip_trailing_junk(p);
85       if (*p == '$' || !*p) {
86          continue;
87       }
88       l = p;
89       skip_nonspaces(&p);             /* permissions */
90       *p++ = 0;
91       bstrncpy(modes, l, sizeof(modes));
92       skip_spaces(&p);
93       skip_nonspaces(&p);             /* link count */
94       *p++ = 0;
95       skip_spaces(&p);
96       l = p;
97       skip_nonspaces(&p);             /* user */
98       *p++ = 0;
99       skip_spaces(&p);
100       bstrncpy(user, l, sizeof(user));
101       l = p;
102       skip_nonspaces(&p);             /* group */
103       *p++ = 0;
104       bstrncpy(group, l, sizeof(group));
105       skip_spaces(&p);
106       l = p;
107       skip_nonspaces(&p);             /* size */
108       *p++ = 0;
109       bstrncpy(size, l, sizeof(size));
110       skip_spaces(&p);
111       l = p;
112       skip_nonspaces(&p);             /* date/time */
113       skip_spaces(&p);
114       skip_nonspaces(&p);
115       *p++ = 0;
116       bstrncpy(date, l, sizeof(date));
117       skip_spaces(&p);
118       if (*p == '*') {
119          bstrncpy(marked, "*", sizeof(marked));
120          p++;
121       } else {
122          bstrncpy(marked, " ", sizeof(marked));
123       }
124       split_path_and_filename(p, &path, &pnl, &file, &fnl);
125       item.clear();
126       item << marked << file << modes << user << group << size << date;
127       QTreeWidgetItem *ti = new QTreeWidgetItem((QTreeWidget *)0, item);
128       ti->setTextAlignment(5, Qt::AlignRight); /* right align size */
129       items.append(ti);
130    }
131    fileWidget->clear();
132    fileWidget->insertTopLevelItems(0, items);
133    for (int i=0; i<7; i++) {
134       fileWidget->resizeColumnToContents(i);
135    }
136
137    free_pool_memory(file);
138    free_pool_memory(path);
139 }
140
141 void restoreDialog::accept()
142 {
143    this->hide();
144    m_console->write("done");
145    m_console->notify(true);
146    delete this;
147    mainWin->resetFocus();
148 }
149
150
151 void restoreDialog::reject()
152 {
153    this->hide();
154    m_console->write("quit");
155    mainWin->set_status("Canceled");
156    delete this;
157    m_console->notify(true);
158    mainWin->resetFocus();
159 }
160
161 void restoreDialog::fileDoubleClicked(QTreeWidgetItem *item, int column)
162 {
163    char cmd[1000];
164    if (column == 0) {                 /* mark/unmark */
165       if (item->text(0) == "*") {
166          bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
167          item->setText(0, " ");
168       } else {
169          bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
170          item->setText(0, "*");
171       }
172       m_console->write_dir(cmd);
173       if (m_console->read() > 0) {
174          strip_trailing_junk(m_console->msg());
175          statusLine->setText(m_console->msg());
176       }
177       m_console->displayToPrompt();
178       return;
179    }    
180    /* 
181     * Double clicking other than column 0 means to decend into
182     *  the directory -- or nothing if it is not a directory.
183     */
184    if (item->text(1).endsWith("/")) {
185       cwd(item->text(1).toUtf8().data());
186       fillDirectory();
187    }
188 }
189
190 void restoreDialog::upButtonPushed()
191 {
192    cwd("..");
193    fillDirectory();
194 }
195
196 void restoreDialog::markButtonPushed()
197 {
198    QList<QTreeWidgetItem *> items = fileWidget->selectedItems();
199    QTreeWidgetItem *item;
200    char cmd[1000];
201    foreach (item, items) {
202       bsnprintf(cmd, sizeof(cmd), "mark \"%s\"", item->text(1).toUtf8().data());
203       item->setText(0, "*");
204       m_console->write_dir(cmd);
205       if (m_console->read() > 0) {
206          strip_trailing_junk(m_console->msg());
207          statusLine->setText(m_console->msg());
208       }
209       Dmsg1(100, "cmd=%s\n", cmd);
210       m_console->discardToPrompt();
211    }
212 }
213
214 void restoreDialog::unmarkButtonPushed()
215 {
216    QList<QTreeWidgetItem *> items = fileWidget->selectedItems();
217    QTreeWidgetItem *item;
218    char cmd[1000];
219    foreach (item, items) {
220       bsnprintf(cmd, sizeof(cmd), "unmark \"%s\"", item->text(1).toUtf8().data());
221       item->setText(0, " ");
222       m_console->write_dir(cmd);
223       if (m_console->read() > 0) {
224          strip_trailing_junk(m_console->msg());
225          statusLine->setText(m_console->msg());
226       }
227       Dmsg1(100, "cmd=%s\n", cmd);
228       m_console->discardToPrompt();
229    }
230 }
231
232 /*
233  * Change current working directory 
234  */
235 bool restoreDialog::cwd(const char *dir)
236 {
237    int stat;
238    char cd_cmd[MAXSTRING];
239
240    bsnprintf(cd_cmd, sizeof(cd_cmd), "cd \"%s\"", dir);
241    Dmsg2(100, "dir=%s cmd=%s\n", dir, cd_cmd);
242    m_console->write_dir(cd_cmd);
243    lineEdit->clear();
244    if ((stat = m_console->read()) > 0) {
245       m_cwd = m_console->msg();
246       lineEdit->insert(m_cwd);
247       Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
248    } else {
249       Dmsg1(000, "stat=%d\n", stat);
250       QMessageBox::critical(this, "Error", "cd command failed", QMessageBox::Ok);
251    }
252    m_console->discardToPrompt();
253    return true;  /* ***FIXME*** return real status */
254 }
255
256 /*
257  * Return cwd when in tree restore mode 
258  */
259 char *restoreDialog::get_cwd()
260 {
261    int stat;
262    m_console->write_dir(".pwd");
263    Dmsg0(100, "send: .pwd\n");
264    if ((stat = m_console->read()) > 0) {
265       m_cwd = m_console->msg();
266       Dmsg2(100, "cwd=%s msg=%s\n", m_cwd.toUtf8().data(), m_console->msg());
267    } else {
268       Dmsg1(000, "stat=%d\n", stat);
269       QMessageBox::critical(this, "Error", ".pwd command failed", QMessageBox::Ok);
270       Dmsg1(000, "stat=%d\n", stat);
271    }
272    m_console->discardToPrompt(); 
273    return m_cwd.toUtf8().data();
274 }