1 | /*************************************************************************** |
---|
2 | xmondorestore.cpp - restore functions |
---|
3 | ------------------------------------- |
---|
4 | begin : Sun Nov 22 2003 |
---|
5 | copyright : (C) 2003 by Joshua Oreman |
---|
6 | email : oremanj@get-linux.org |
---|
7 | cvsid : $Id: xmondorestore.cpp 273 2006-01-03 15:09:12Z bcornec $ |
---|
8 | ***************************************************************************/ |
---|
9 | |
---|
10 | /*************************************************************************** |
---|
11 | * * |
---|
12 | * This program is free software; you can redistribute it and/or modify * |
---|
13 | * it under the terms of the GNU General Public License as published by * |
---|
14 | * the Free Software Foundation; either version 2 of the License, or * |
---|
15 | * (at your option) any later version. * |
---|
16 | * * |
---|
17 | ***************************************************************************/ |
---|
18 | |
---|
19 | #include <qbuttongroup.h> |
---|
20 | #include <qlineedit.h> |
---|
21 | #include <qlabel.h> |
---|
22 | #include <qlayout.h> |
---|
23 | #include <qlistview.h> |
---|
24 | #include <qstringlist.h> |
---|
25 | #include <qmessagebox.h> |
---|
26 | |
---|
27 | #include "xmondo.h" |
---|
28 | #include "xmondorestore.h" |
---|
29 | #include <X-specific.h> |
---|
30 | extern "C" { |
---|
31 | #define bool int |
---|
32 | #include <libmondo-devices-EXT.h> |
---|
33 | #include <libmondo-filelist-EXT.h> |
---|
34 | #include <libmondo-files-EXT.h> |
---|
35 | #include <libmondo-fork-EXT.h> |
---|
36 | #include <libmondo-tools-EXT.h> |
---|
37 | #undef bool |
---|
38 | int restore_everything (struct s_bkpinfo *bkpinfo, struct s_node *filelist); |
---|
39 | int get_cfg_file_from_archive (struct s_bkpinfo *bkpinfo); |
---|
40 | int read_cfg_file_into_bkpinfo (char *cfg_file, struct s_bkpinfo *bkpinfo); |
---|
41 | int mount_cdrom (struct s_bkpinfo *bkpinfo); |
---|
42 | void setup_MR_global_filenames (struct s_bkpinfo *bkpinfo); |
---|
43 | extern char *g_mondo_cfg_file; |
---|
44 | extern char *g_filelist_full; |
---|
45 | extern int g_current_media_number; |
---|
46 | extern int g_text_mode; |
---|
47 | } |
---|
48 | |
---|
49 | extern QProgressBar *XMondoProgress; |
---|
50 | extern QLabel *XMondoProgressWhat, *XMondoProgressWhat2, *XMondoProgressWhat3; |
---|
51 | extern QCheckBox *XMondoVerbose; |
---|
52 | extern QMultiLineEdit *XMondoLog; |
---|
53 | extern QLabel *XMondoStatus; |
---|
54 | extern QLabel *XMondoTimeTaken, *XMondoTimeToGo, *XMondoProgressPercent; |
---|
55 | extern QPushButton *XMondoCancel; |
---|
56 | extern XMEventHolder events; |
---|
57 | |
---|
58 | class XMCheckListItem : public QCheckListItem |
---|
59 | { |
---|
60 | public: |
---|
61 | XMCheckListItem (QCheckListItem * parent, const QString & text, Type tt = CheckBox) |
---|
62 | : QCheckListItem (parent, text, tt), _text (text) |
---|
63 | { |
---|
64 | } |
---|
65 | |
---|
66 | XMCheckListItem (QListViewItem * parent, const QString & text, Type tt = CheckBox) |
---|
67 | : QCheckListItem (parent, text, tt), _text (text) |
---|
68 | { |
---|
69 | } |
---|
70 | |
---|
71 | XMCheckListItem (QListView * parent, const QString & text, Type tt = CheckBox) |
---|
72 | : QCheckListItem (parent, text, tt), _text (text) |
---|
73 | { |
---|
74 | } |
---|
75 | |
---|
76 | virtual ~XMCheckListItem() {} |
---|
77 | |
---|
78 | virtual int rtti() { return 1001; } |
---|
79 | |
---|
80 | virtual void setOn (bool on) { |
---|
81 | QCheckListItem::setOn (on); |
---|
82 | } |
---|
83 | |
---|
84 | static QLabel *progressDisplay; |
---|
85 | static bool *doneSetup; |
---|
86 | static bool selecting; |
---|
87 | static int counter; |
---|
88 | static int depth; |
---|
89 | |
---|
90 | protected: |
---|
91 | virtual void stateChange (bool on) { |
---|
92 | if (firstChild()) { |
---|
93 | if (!selecting) { |
---|
94 | progressDisplay->setText (QString ("%1electing %2...").arg (on? "S" : "Des").arg (_text)); |
---|
95 | counter = depth = 0; |
---|
96 | selecting = true; |
---|
97 | if (doneSetup) *doneSetup = false; |
---|
98 | } |
---|
99 | |
---|
100 | for (QListViewItem *lvi = firstChild(); lvi; lvi = lvi->nextSibling()) { |
---|
101 | XMCheckListItem *cli; |
---|
102 | if ((cli = dynamic_cast <XMCheckListItem *> (lvi)) != 0) { |
---|
103 | if (!(++counter % 10000)) { |
---|
104 | progressDisplay->setText (progressDisplay->text() + "."); |
---|
105 | } |
---|
106 | if (!(counter % 1000)) { |
---|
107 | kapp->processEvents(); |
---|
108 | } |
---|
109 | depth++; |
---|
110 | cli->setOn (on); |
---|
111 | depth--; |
---|
112 | } |
---|
113 | } |
---|
114 | |
---|
115 | if (depth == 0) { |
---|
116 | selecting = false; |
---|
117 | progressDisplay->setText ("Please select files and directories to be restored."); |
---|
118 | if (doneSetup) *doneSetup = true; |
---|
119 | } |
---|
120 | } |
---|
121 | } |
---|
122 | |
---|
123 | private: |
---|
124 | // Ugly hack, but it works: fix segfault |
---|
125 | QString _text; |
---|
126 | }; |
---|
127 | |
---|
128 | QLabel *XMCheckListItem::progressDisplay = 0; |
---|
129 | bool XMCheckListItem::selecting = false; |
---|
130 | bool *XMCheckListItem::doneSetup = 0; |
---|
131 | int XMCheckListItem::counter = 0; |
---|
132 | int XMCheckListItem::depth = 0; |
---|
133 | |
---|
134 | struct XM_node |
---|
135 | { |
---|
136 | QString s; |
---|
137 | XM_node *firstChild; |
---|
138 | XM_node *nextSibling; |
---|
139 | }; |
---|
140 | |
---|
141 | #define XMLF_OK 0 |
---|
142 | #define XMLF_CANTOPEN 1 |
---|
143 | |
---|
144 | // Requirements: |
---|
145 | // - File must be sorted |
---|
146 | // - Entry for a directory must come directly before entries for its files |
---|
147 | void XM_load_filelist_sub (FILE *fp, QStringList first, XMCheckListItem *top, QLabel *status, int numlines) |
---|
148 | { |
---|
149 | static int depth = 0; |
---|
150 | static int lino = 0; |
---|
151 | bool tristated = false; |
---|
152 | |
---|
153 | char line[4095]; |
---|
154 | while (fgets (line, 4095, fp)) { |
---|
155 | bool chomped = false; |
---|
156 | |
---|
157 | if (line[strlen (line) - 1] == '\n') { |
---|
158 | line[strlen (line) - 1] = 0; |
---|
159 | chomped = true; |
---|
160 | } |
---|
161 | |
---|
162 | QStringList dirComponents = QStringList::split ("/", line); |
---|
163 | if (dirComponents.size() == 0) continue; |
---|
164 | if (depth > 0) { |
---|
165 | bool good = true; |
---|
166 | for (int i = 0; (i < dirComponents.size()) && (i < first.size()) && (i < depth); ++i) |
---|
167 | if (dirComponents[i] != first[i]) |
---|
168 | good = false; |
---|
169 | if (!good) { |
---|
170 | fseek (fp, -(strlen (line) + chomped), SEEK_CUR); // equivalent of "pushback" |
---|
171 | return; |
---|
172 | } |
---|
173 | } |
---|
174 | XMCheckListItem *newitem = new XMCheckListItem (top, dirComponents[dirComponents.size() - 1]); |
---|
175 | if (!(++lino % 1111)) { |
---|
176 | status->setText (QString ("Loading filelist - %1% done").arg (lino * 100 / numlines)); |
---|
177 | } |
---|
178 | |
---|
179 | depth++; |
---|
180 | XM_load_filelist_sub (fp, dirComponents, newitem, status, numlines); |
---|
181 | depth--; |
---|
182 | } |
---|
183 | } |
---|
184 | |
---|
185 | int XM_load_filelist (const char *filelist_fname, QListView *list, QLabel *status, QStringList first = QStringList(), FILE *fp = 0) |
---|
186 | { |
---|
187 | fp = fopen (filelist_fname, "r"); |
---|
188 | if (!fp) return XMLF_CANTOPEN; |
---|
189 | |
---|
190 | XMCheckListItem *top = new XMCheckListItem (list, "/"); |
---|
191 | |
---|
192 | status->setText ("Loading filelist - 0% done"); |
---|
193 | XM_load_filelist_sub (fp, QStringList(), top, status, atoi (call_program_and_get_last_line_of_output (const_cast <char*> (QString ("wc -l %1").arg (filelist_fname).ascii())))); |
---|
194 | |
---|
195 | fclose (fp); |
---|
196 | return XMLF_OK; |
---|
197 | } |
---|
198 | |
---|
199 | void *XMondoRestore_preparer_thread (void *arg) |
---|
200 | { |
---|
201 | XMondoRestore *r = static_cast<XMondoRestore*> (arg); |
---|
202 | int i = 0; |
---|
203 | g_current_media_number = 1; |
---|
204 | |
---|
205 | r->fStatusMsg->setText ("Retrieving mondo-restore.cfg from archive..."); |
---|
206 | |
---|
207 | struct s_bkpinfo *bkpinfo = r->bkpinfo; |
---|
208 | reset_bkpinfo (bkpinfo); |
---|
209 | switch (r->rMediaType->id (r->rMediaType->selected())) { |
---|
210 | case 0: |
---|
211 | bkpinfo->backup_media_type = cdr; |
---|
212 | break; |
---|
213 | case 1: |
---|
214 | bkpinfo->backup_media_type = cdrw; |
---|
215 | bkpinfo->wipe_media_first = 1; |
---|
216 | break; |
---|
217 | case 2: |
---|
218 | bkpinfo->backup_media_type = cdstream; |
---|
219 | break; |
---|
220 | case 3: |
---|
221 | bkpinfo->backup_media_type = dvd; |
---|
222 | break; |
---|
223 | case 4: |
---|
224 | bkpinfo->backup_media_type = iso; |
---|
225 | break; |
---|
226 | case 5: |
---|
227 | bkpinfo->backup_media_type = nfs; |
---|
228 | break; |
---|
229 | case 6: |
---|
230 | bkpinfo->backup_media_type = tape; |
---|
231 | break; |
---|
232 | case 7: |
---|
233 | bkpinfo->backup_media_type = udev; |
---|
234 | break; |
---|
235 | } |
---|
236 | |
---|
237 | strcpy (bkpinfo->media_device, r->rDevice->text()); |
---|
238 | if (bkpinfo->backup_media_type == nfs) strcpy (bkpinfo->nfs_mount, r->rDevice->text()); |
---|
239 | if (bkpinfo->backup_media_type == nfs) strcpy (bkpinfo->nfs_remote_dir, r->rNFSRemoteDir->text()); |
---|
240 | if (bkpinfo->backup_media_type == iso) strcpy (bkpinfo->isodir, r->rDevice->text()); |
---|
241 | strcpy (bkpinfo->tmpdir, r->tempdir.ascii()); |
---|
242 | |
---|
243 | setup_MR_global_filenames (bkpinfo); |
---|
244 | |
---|
245 | if (get_cfg_file_from_archive (bkpinfo) != 0) { |
---|
246 | r->fStatusMsg->setText ("Unable to retrieve mondo-restore.cfg. Please choose another archive source."); |
---|
247 | r->ok = false; |
---|
248 | return 0; |
---|
249 | } |
---|
250 | read_cfg_file_into_bkpinfo (g_mondo_cfg_file, bkpinfo); |
---|
251 | if (!does_file_exist (g_mondo_cfg_file)) { |
---|
252 | r->fStatusMsg->setText ("Unable to retrieve mondo-restore.cfg. Internal error."); |
---|
253 | r->ok = false; |
---|
254 | return 0; |
---|
255 | } |
---|
256 | if (!does_file_exist (g_filelist_full)) { |
---|
257 | chdir (bkpinfo->tmpdir); |
---|
258 | r->fStatusMsg->setText ("Retrieving filelist..."); |
---|
259 | if ((bkpinfo->backup_media_type == tape) || (bkpinfo->backup_media_type == udev) || |
---|
260 | (bkpinfo->backup_media_type == cdstream)) { |
---|
261 | unlink (g_filelist_full); |
---|
262 | system (QString ("tar -zxf %1 tmp/filelist.full").arg (bkpinfo->media_device).ascii()); |
---|
263 | } else { |
---|
264 | mount_cdrom (bkpinfo); |
---|
265 | unlink (g_filelist_full); |
---|
266 | system ("tar -zxf /mnt/cdrom/images/all.tar.gz tmp/filelist.full"); |
---|
267 | } |
---|
268 | |
---|
269 | if (!does_file_exist (g_filelist_full)) { |
---|
270 | r->fStatusMsg->setText ("Filelist could not be retrieved!"); |
---|
271 | r->ok = false; |
---|
272 | return 0; |
---|
273 | } |
---|
274 | } |
---|
275 | if (!r->rFilter->text().isEmpty() && !r->rFilter->text().isNull()) { |
---|
276 | r->fStatusMsg->setText (QString ("Filtering filelist through regexp <tt>%1</tt>...").arg (r->rFilter->text())); |
---|
277 | if (system (QString ("egrep '%2' %1 > %3.FILT").arg (g_filelist_full).arg (r->rFilter->text()).arg (g_filelist_full).ascii()) != 0) { |
---|
278 | r->fStatusMsg->setText ("Filter failed, using whole filelist"); |
---|
279 | rename (g_filelist_full, QString ("%1.FILT").arg (g_filelist_full).ascii()); |
---|
280 | usleep (500000); |
---|
281 | } |
---|
282 | } else { |
---|
283 | rename (g_filelist_full, QString ("%1.FILT").arg (g_filelist_full).ascii()); |
---|
284 | } |
---|
285 | |
---|
286 | r->fStatusMsg->setText ("Preparing filelist - 0% done"); |
---|
287 | |
---|
288 | int nlines = atoi (call_program_and_get_last_line_of_output (const_cast<char*> (QString ("wc -l %1.FILT").arg (g_filelist_full).ascii()))); |
---|
289 | int curline = 0; |
---|
290 | FILE *fin = fopen (QString ("%1.FILT").arg (g_filelist_full).ascii(), "r"); |
---|
291 | FILE *fout = popen (QString ("sort | uniq > %1").arg (g_filelist_full).ascii(), "w"); |
---|
292 | |
---|
293 | if (!(fin && fout)) { |
---|
294 | r->fStatusMsg->setText ("Can't open filelist"); |
---|
295 | r->ok = false; |
---|
296 | return 0; |
---|
297 | } |
---|
298 | |
---|
299 | char line[4096], tmp[4096]; |
---|
300 | while (fgets (line, 4096, fin)) { |
---|
301 | if (line[strlen (line) - 1] == '\n') |
---|
302 | line[strlen (line) - 1] = '\0'; |
---|
303 | |
---|
304 | for (int pos = 0; line[pos] != '\0'; pos++) { |
---|
305 | if (line[pos] != '/') continue; |
---|
306 | strcpy (tmp, line); |
---|
307 | tmp[pos] = '\0'; |
---|
308 | if (strlen (tmp)) { |
---|
309 | fprintf (fout, "%s\n", tmp); |
---|
310 | } |
---|
311 | } |
---|
312 | fprintf (fout, "%s\n", line); |
---|
313 | if (!(++curline % 1111)) { |
---|
314 | r->fStatusMsg->setText (QString ("Preparing filelist - %1% done").arg (curline * 100 / nlines)); |
---|
315 | } |
---|
316 | } |
---|
317 | |
---|
318 | fclose (fin); |
---|
319 | pclose (fout); |
---|
320 | |
---|
321 | if (XM_load_filelist (g_filelist_full, r->fList, r->fStatusMsg) != XMLF_OK) { |
---|
322 | r->fStatusMsg->setText ("Error loading filelist"); |
---|
323 | r->ok = false; |
---|
324 | return 0; |
---|
325 | } |
---|
326 | r->fStatusMsg->setText ("Filelist loaded OK"); |
---|
327 | |
---|
328 | r->doneSetup = true; |
---|
329 | r->fList->setEnabled (true); |
---|
330 | r->fRestoreDirLabel->setEnabled (true); |
---|
331 | r->fRestoreDir->setEnabled (true); |
---|
332 | sleep (1); |
---|
333 | r->fStatusMsg->setText ("Please select files and directories to be restored."); |
---|
334 | XMCheckListItem::progressDisplay = r->fStatusMsg; |
---|
335 | XMCheckListItem::doneSetup = &(r->doneSetup); |
---|
336 | |
---|
337 | return 0; |
---|
338 | } |
---|
339 | |
---|
340 | XMondoRestore::XMondoRestore (QWidget *parent, QButtonGroup *mediaType, QLineEdit *device, QLineEdit *nfsRemoteDir, QLineEdit *filelistFilter) |
---|
341 | : QObject (0, 0), rMediaType (mediaType), rDevice (device), rNFSRemoteDir (nfsRemoteDir), rFilter (filelistFilter), ok (true), files (parent), doneSetup (false), th (0) |
---|
342 | { |
---|
343 | bkpinfo = new s_bkpinfo; |
---|
344 | |
---|
345 | char tmp[256]; |
---|
346 | strcpy (tmp, "/tmp/xmondo.rstr.XXXXXX"); |
---|
347 | mktemp (tmp); |
---|
348 | tempdir = tmp; |
---|
349 | filelistLocation = tempdir + "/filelist.full"; |
---|
350 | cfgLocation = tempdir + "/mondo-restore.cfg"; |
---|
351 | cdMountpoint = "/mnt/cdrom"; |
---|
352 | |
---|
353 | if (!does_file_exist ("/mnt/cdrom")) { |
---|
354 | if (system ("mkdir -p /mnt/cdrom >/dev/null 2>&1") != 0) { |
---|
355 | popup_and_OK ("Can't create /mnt/cdrom directory. Aborting restore."); |
---|
356 | ok = false; |
---|
357 | return; |
---|
358 | } |
---|
359 | } |
---|
360 | |
---|
361 | QGridLayout *filesGrid; |
---|
362 | filesGrid = new QGridLayout (files, 3, 2, 5, 5, "filesGrid"); |
---|
363 | fStatusMsg = new QLabel ("", files); |
---|
364 | fList = new QListView (files); |
---|
365 | fRestoreDirLabel = new QLabel ("Restore to:", files); |
---|
366 | fRestoreDir = new QLineEdit (files); |
---|
367 | |
---|
368 | fList->addColumn ("Files to restore:"); |
---|
369 | fList->setRootIsDecorated (true); |
---|
370 | fList->setEnabled (false); |
---|
371 | fRestoreDirLabel->setEnabled (false); |
---|
372 | fRestoreDir->setEnabled (false); |
---|
373 | fRestoreDir->setText ("/tmp"); |
---|
374 | filesGrid->addMultiCellWidget (fStatusMsg, 0, 0, 0, 1); |
---|
375 | filesGrid->addMultiCellWidget (fList, 1, 1, 0, 1); |
---|
376 | filesGrid->addWidget (fRestoreDirLabel, 2, 0); |
---|
377 | filesGrid->addWidget (fRestoreDir, 2, 1); |
---|
378 | |
---|
379 | while (system ("mount | grep -q /mnt/cdrom") == 1) { |
---|
380 | if (QMessageBox::warning (0, "XMondo", QString ("CD is mounted. Please unmount it and try again."), "&Retry", "&Cancel") == 1 /* Cancel */) { |
---|
381 | ok = false; |
---|
382 | return; |
---|
383 | } |
---|
384 | } |
---|
385 | |
---|
386 | pthread_create (&preparer_thread, 0, XMondoRestore_preparer_thread, static_cast <void*> (this)); |
---|
387 | ok = true; |
---|
388 | } |
---|
389 | |
---|
390 | XMondoRestore::~XMondoRestore() |
---|
391 | { |
---|
392 | chdir ("/"); |
---|
393 | pthread_cancel (preparer_thread); |
---|
394 | system (QString ("mount | grep xmondo.rstr | cut -d' ' -f3 | xargs umount")); |
---|
395 | system (QString ("umount %1/mount.bootdisk >/dev/null 2>&1").arg (tempdir).ascii()); |
---|
396 | if ((tempdir != "") && (tempdir != "/") && (tempdir != "/tmp") && (tempdir != "/tmp/")) { |
---|
397 | system (QString ("rm -rf %1").arg (tempdir).ascii()); |
---|
398 | } |
---|
399 | system (QString ("umount %1 >/dev/null 2>&1").arg (cdMountpoint).ascii()); |
---|
400 | delete bkpinfo; |
---|
401 | } |
---|
402 | |
---|
403 | int XM_save_filelist (QListViewItem *liTop, const char *fname, QString prefix = QString (""), int numlines = 0, int curline = 0, FILE *fp = 0) |
---|
404 | { |
---|
405 | static int depth = 0; |
---|
406 | |
---|
407 | if (!depth) { |
---|
408 | numlines = atoi (call_program_and_get_last_line_of_output (const_cast<char*> (QString ("wc -l %1").arg (fname).ascii()))); |
---|
409 | fp = fopen (fname, "w"); |
---|
410 | if (!fp) return 1; |
---|
411 | fprintf (fp, "/\n"); |
---|
412 | if (!liTop) { |
---|
413 | popup_and_OK ("Internal error. No entries in filelist."); |
---|
414 | return 255; |
---|
415 | } |
---|
416 | } |
---|
417 | |
---|
418 | XMCheckListItem *top = dynamic_cast<XMCheckListItem*> (liTop); |
---|
419 | if (!top) return 2; |
---|
420 | |
---|
421 | for (; top; top = dynamic_cast<XMCheckListItem*> (top->nextSibling())) { |
---|
422 | if (!top) return 2; |
---|
423 | if (top->isOn()) { |
---|
424 | fprintf (fp, "%s/%s\n", prefix.ascii(), top->text().ascii()); |
---|
425 | } |
---|
426 | if (!(++curline % 1000)) { |
---|
427 | XMondoProgress->setProgress (curline * 100 / numlines); |
---|
428 | kapp->processEvents(); |
---|
429 | } |
---|
430 | if (top->firstChild()) { |
---|
431 | depth++; |
---|
432 | XM_save_filelist (top->firstChild(), "", prefix + "/" + top->text(), numlines, curline, fp); |
---|
433 | depth--; |
---|
434 | } |
---|
435 | } |
---|
436 | |
---|
437 | if (!depth) { |
---|
438 | fclose (fp); |
---|
439 | } |
---|
440 | return 0; |
---|
441 | } |
---|
442 | |
---|
443 | |
---|
444 | void *RestoreThread__run (void *arg); |
---|
445 | |
---|
446 | class RestoreThread |
---|
447 | { |
---|
448 | friend void *RestoreThread__run (void *arg); |
---|
449 | public: |
---|
450 | RestoreThread (struct s_bkpinfo *bkpinfo, struct s_node *filelist) : _bkpinfo (bkpinfo), _filelist (filelist), |
---|
451 | _ret (-1), _aborted (false) {} |
---|
452 | int returns() { |
---|
453 | return _ret; |
---|
454 | } |
---|
455 | void start() { |
---|
456 | _running = true; |
---|
457 | pthread_create (&_thr, 0, RestoreThread__run, this); |
---|
458 | } |
---|
459 | void terminate() { |
---|
460 | _running = false; |
---|
461 | pthread_cancel (_thr); |
---|
462 | _thr = 0; |
---|
463 | } |
---|
464 | bool running() { |
---|
465 | return _running; |
---|
466 | } |
---|
467 | bool aborted() { |
---|
468 | return _aborted; |
---|
469 | } |
---|
470 | protected: |
---|
471 | static void setStop (void *arg) { |
---|
472 | RestoreThread *rt = static_cast <RestoreThread*> (arg); |
---|
473 | if (!rt) return; |
---|
474 | rt->_running = false; |
---|
475 | rt->_ret = -1; |
---|
476 | rt->_aborted = true; |
---|
477 | } |
---|
478 | void run() { |
---|
479 | pthread_cleanup_push (RestoreThread::setStop, this); |
---|
480 | |
---|
481 | log_to_screen ("Restore started on %s", call_program_and_get_last_line_of_output ("date")); |
---|
482 | _ret = restore_everything (_bkpinfo, _filelist); |
---|
483 | log_to_screen ("Restore finished on %s", call_program_and_get_last_line_of_output ("date")); |
---|
484 | pthread_cleanup_pop (FALSE); |
---|
485 | _running = false; |
---|
486 | } |
---|
487 | struct s_bkpinfo *_bkpinfo; |
---|
488 | struct s_node *_filelist; |
---|
489 | int _ret; |
---|
490 | pthread_t _thr; |
---|
491 | bool _running; |
---|
492 | bool _aborted; |
---|
493 | }; |
---|
494 | |
---|
495 | void *RestoreThread__run (void *arg) |
---|
496 | { |
---|
497 | RestoreThread *rt = static_cast <RestoreThread *> (arg); |
---|
498 | if (!rt && (sizeof(void*) >= 4)) return (void *) 0xDEADBEEF; |
---|
499 | rt->run(); |
---|
500 | } |
---|
501 | |
---|
502 | void XMondoRestore::slotAbortRestore() |
---|
503 | { |
---|
504 | if (th) th->terminate(); |
---|
505 | } |
---|
506 | |
---|
507 | void XM_toggle_everything_on (struct s_node *flist) |
---|
508 | { |
---|
509 | for (; flist; flist = flist->right) { |
---|
510 | if (flist->ch == 0) { |
---|
511 | flist->selected = 1; |
---|
512 | } |
---|
513 | if (flist->down) { |
---|
514 | XM_toggle_everything_on (flist->down); |
---|
515 | } |
---|
516 | } |
---|
517 | } |
---|
518 | |
---|
519 | void XMondoRestore::go() |
---|
520 | { |
---|
521 | if (!doneSetup) { |
---|
522 | popup_and_OK ("Please wait for the setup to be completed."); |
---|
523 | ok = false; |
---|
524 | return; |
---|
525 | } |
---|
526 | pthread_cancel (preparer_thread); |
---|
527 | |
---|
528 | |
---|
529 | disconnect (XMondoCancel, SIGNAL(clicked()), 0, 0); |
---|
530 | connect (XMondoCancel, SIGNAL(clicked()), this, SLOT(slotAbortRestore())); |
---|
531 | |
---|
532 | XMondoProgress->show(); |
---|
533 | XMondoProgress->setTotalSteps (100); |
---|
534 | XMondoProgress->setProgress (0); |
---|
535 | XMondoProgressWhat->show(); |
---|
536 | XMondoProgressWhat->setText ("Saving your filelist choices."); |
---|
537 | XMondoProgressWhat2->hide(); |
---|
538 | XMondoProgressWhat3->hide(); |
---|
539 | XMondoTimeTaken->hide(); |
---|
540 | XMondoTimeToGo->hide(); |
---|
541 | XMondoStatus->setText ("Saving filelist"); |
---|
542 | XMondoStatus->show(); |
---|
543 | XMondoLog->setText (""); |
---|
544 | XMondoLog->show(); |
---|
545 | |
---|
546 | if (XM_save_filelist (fList->firstChild()->firstChild(), g_filelist_full) != 0) { |
---|
547 | XMondoStatus->setText ("Error saving filelist"); |
---|
548 | ok = false; |
---|
549 | return; |
---|
550 | } |
---|
551 | |
---|
552 | XMondoStatus->setText ("Reloading filelist"); |
---|
553 | /*DEBUG*/ system (QString ("cp %1 /home/oremanj/filelist.tested").arg (g_filelist_full).ascii()); |
---|
554 | s_node *flist = load_filelist (g_filelist_full); |
---|
555 | if (!flist) { |
---|
556 | XMondoStatus->setText ("Error loading filelist"); |
---|
557 | ok = false; |
---|
558 | return; |
---|
559 | } |
---|
560 | XM_toggle_everything_on (flist); |
---|
561 | |
---|
562 | XMondoProgress->hide(); |
---|
563 | XMondoStatus->setText ("Beginning restore"); |
---|
564 | XMondoProgressWhat->hide(); |
---|
565 | |
---|
566 | strcpy (bkpinfo->restore_path, fRestoreDir->text().ascii()); |
---|
567 | |
---|
568 | g_text_mode = 1; // avoid crashing on NEWT functions |
---|
569 | |
---|
570 | th = new RestoreThread (bkpinfo, flist); |
---|
571 | th->start(); |
---|
572 | while (th->running()) { |
---|
573 | usleep (100000); |
---|
574 | events.send(); |
---|
575 | kapp->processEvents(); |
---|
576 | } |
---|
577 | free_filelist (flist); |
---|
578 | if (th->aborted()) { |
---|
579 | /* do nothing */ |
---|
580 | } else if (th->returns() == 0) { |
---|
581 | popup_and_OK ("Restore completed with no errors."); |
---|
582 | } else { |
---|
583 | popup_and_OK ("Restore completed; however, there were some errors."); |
---|
584 | } |
---|
585 | delete th; th = 0; |
---|
586 | ok = true; // call destructor in caller |
---|
587 | } |
---|