source: MondoRescue/branches/stable/mondo/mondo/common/X-specific.cpp@ 684

Last change on this file since 684 was 541, checked in by bcornec, 18 years ago

Stable is reverted to r436 (2.0.7) to put it in line with 2.0.8 and start from there over

  • Property svn:keywords set to Id
File size: 13.0 KB
Line 
1/* X-specific.c
2
3
4- subroutines which do display-type things
5 and use the Qt library to do them
6
710/04
8- took out the newt-related subroutines
9
1009/12
11- created
12*/
13
14#include <config.h>
15
16#if !WITH_X
17#warning "*** You are compiling X-specific.cpp without X support!"
18#warning "*** Compiling newt-specific.c instead."
19#include "newt-specific.c"
20#else
21
22#include <qmessagebox.h>
23#include <qprogressbar.h>
24#include <qmultilineedit.h>
25#include <qvaluelist.h>
26#include <qstringlist.h>
27#include <qstring.h>
28#include <qinputdialog.h>
29#include <qlabel.h>
30#include <kapp.h>
31#include <sys/time.h>
32
33extern "C" {
34 #include <unistd.h>
35 #include "my-stuff.h"
36 #include "mondostructures.h"
37 #include "X-specific.h"
38 #include "libmondo-string-EXT.h"
39 #include "libmondo-files-EXT.h"
40 #include "libmondo-tools-EXT.h"
41 #include "libmondo-fork-EXT.h"
42 #include "libmondo-gui-EXT.h"
43 #include "lib-common-externs.h"
44}
45
46extern QProgressBar *XMondoProgress;
47extern QLabel *XMondoProgressWhat, *XMondoProgressWhat2, *XMondoProgressWhat3;
48extern QMultiLineEdit *XMondoLog;
49extern QLabel *XMondoStatus;
50extern QLabel *XMondoTimeTaken, *XMondoTimeToGo, *XMondoProgressPercent;
51extern XMEventHolder events;
52extern int g_operation_in_progress;
53
54#include <pthread.h>
55
56void *run_evalcall_updater_thread (void *wasted_electrons) {
57 while (1) {
58 usleep (500000);
59 update_evalcall_form (0);
60 }
61 return wasted_electrons;
62}
63
64extern "C" {
65
66pthread_t updater;
67bool updater_running = false;
68
69extern pid_t g_mastermind_pid;
70pid_t g_main_pid;
71
72char err_log_lines[NOOF_ERR_LINES][MAX_STR_LEN], g_blurb_str_1[MAX_STR_LEN] =
73 "", g_blurb_str_2[MAX_STR_LEN] = "", g_blurb_str_3[MAX_STR_LEN] = "";
74
75int g_result_of_last_event = -1;
76long g_isoform_starttime;
77int g_isoform_old_progress = -1;
78char g_isoform_header_str[MAX_STR_LEN];
79int g_mysterious_dot_counter;
80extern FILE *g_f_logfile_out;
81
82int g_currentY = 3; /* purpose */
83extern int g_current_media_number;
84
85long g_maximum_progress = 999; /* purpose */
86long g_current_progress = -999; /* purpose */
87long g_start_time = 0; /* purpose */
88int g_text_mode = TRUE;
89
90int g_exiting = FALSE;
91char *g_erase_tmpdir_and_scratchdir;
92extern char g_tmpfs_mountpt[];
93
94int ask_me_yes_or_no (char *prompt) { return popup_with_buttons (prompt, "Yes", "No"); }
95int ask_me_OK_or_cancel (char *prompt) { return popup_with_buttons (prompt, "OK", "Cancel"); }
96
97int
98popup_with_buttons (char *prompt, char *button1, char *button2)
99{
100 if (!g_operation_in_progress) return popup_with_buttons_sub (prompt, button1, button2);
101
102 int res;
103 events.popupWithButtons (prompt, button1, button2);
104 while (g_result_of_last_event == -1);
105 res = g_result_of_last_event;
106 g_result_of_last_event = -1;
107 return res;
108}
109
110int
111popup_with_buttons_sub (char *prompt, char *button1, char *button2)
112{
113 switch (QMessageBox::information (0, "XMondo", prompt, button2, button1, 0, 0, 1)) {
114 case 0:
115 return 1;
116 break;
117 case 1:
118 return 0;
119 break;
120 default:
121 return 2;
122 break;
123 }
124}
125
126void
127fatal_error (char *error)
128{
129 if (!g_operation_in_progress) fatal_error_sub (error);
130 events.errorMsg (error);
131 while(1);
132}
133
134void
135fatal_error_sub (char *error)
136{
137 static bool already_exiting = false;
138 char tmp[MAX_STR_LEN];
139 g_exiting = TRUE;
140
141 log_it ("Fatal error received - '%s'", error);
142 printf ("Fatal error... %s\n", error);
143 if (getpid() == g_mastermind_pid)
144 {
145 log_it ("(FE) mastermind %d is exiting", (int)getpid());
146 kill (g_main_pid, SIGTERM);
147 finish (1);
148 }
149
150 if (getpid() != g_main_pid)
151 {
152 if (g_mastermind_pid != 0 && getpid() != g_mastermind_pid)
153 {
154 log_it ("(FE) non-m/m %d is exiting", (int)getpid());
155 kill (g_main_pid, SIGTERM);
156 finish (1);
157 }
158
159 if (getpid() != g_main_pid)
160 {
161 log_it ("(FE) aux pid %d is exiting", (int)getpid());
162 kill (g_main_pid, SIGTERM);
163 finish (1);
164 }
165 }
166
167 log_it ("OK, I think I'm the main PID.");
168 if (already_exiting)
169 {
170 log_it ("...I'm already exiting. Give me time, Julian!");
171 finish (1);
172 }
173
174 already_exiting = TRUE;
175 log_it ("I'm going to do some cleaning up now.");
176 kill_anything_like_this ("mondoarchive");
177 kill_anything_like_this ("/mondo/do-not");
178 kill_anything_like_this ("tmp.mondo");
179 sync();
180
181 sprintf (tmp, "umount %s", g_tmpfs_mountpt);
182 chdir ("/");
183 for(int i=0; i<10 && run_program_and_log_output (tmp, TRUE); i++)
184 {
185 log_it ("Waiting for child processes to terminate");
186 sleep (1);
187 run_program_and_log_output (tmp, TRUE);
188 }
189
190 if (g_erase_tmpdir_and_scratchdir[0])
191 {
192 run_program_and_log_output (g_erase_tmpdir_and_scratchdir, TRUE);
193 }
194
195 QMessageBox::critical (0, "XMondo", QString ("<font color=\"red\"><b>FATAL ERROR</b></font><br>%1").arg (error),
196 "Quit", 0, 0, 0, 0);
197 kapp->quit();
198 printf ("---FATAL ERROR--- %s\n", error);
199 system ("gzip -9c /var/log/mondo-archive.log > /tmp/MA.log.gz 2> /dev/null");
200 printf ("If you require technical support, please contact the mailing list.\n");
201 printf ("See http://www.mondorescue.org for details.\n");
202 printf ("Log file: %s\n", MONDO_LOGFILE);
203
204 if (does_file_exist ("/tmp/MA.log.gz"))
205 {
206 printf ("FYI, I have gzipped the log and saved it to /tmp/MA.log.gz\n");
207 printf ("The list's members can help you, if you attach that file to your e-mail.\n");
208 }
209
210 printf ("Mondo has aborted.\n");
211 register_pid (0, "mondo");
212
213 if (!g_main_pid) {
214 log_it ("FYI - g_main_pid is blank");
215 }
216
217 finish (254);
218 /*NOTREACHED*/
219}
220
221void
222finish (int eval)
223{
224 register_pid (0, "mondo");
225 chdir ("/");
226 run_program_and_log_output (static_cast <char*> ("umount /mnt/cdrom"), true);
227 printf ("See %s for details of backup run.", MONDO_LOGFILE);
228 exit (eval);
229 /*NOTREACHED*/
230}
231
232void
233log_file_end_to_screen (char *filename, char *grep_for_me)
234{
235
236 /** buffers ***********************************************************/
237 char command[MAX_STR_LEN + 1];
238 char tmp[MAX_STR_LEN + 1];
239
240 /** pointers **********************************************************/
241 FILE *fin;
242
243 /** int ***************************************************************/
244 int i = 0;
245
246
247
248 if (!does_file_exist (filename))
249 {
250 return;
251 }
252 if (grep_for_me[0] != '\0')
253 {
254 sprintf (command, "grep \"%s\" %s | tail -n%d",
255 grep_for_me, filename, NOOF_ERR_LINES);
256 }
257 else
258 {
259 sprintf (command, "tail -n%d %s", NOOF_ERR_LINES, filename);
260 }
261 fin = popen (command, "r");
262 if (fin)
263 {
264 for (i = 0; i < NOOF_ERR_LINES; i++)
265 {
266 char tmp[MAX_STR_LEN];
267 fgets (tmp, MAX_STR_LEN, fin);
268 events.insertLine (XMondoLog, tmp);
269 }
270 }
271 pclose (fin);
272}
273
274void
275log_to_screen (const char *line, ...)
276{
277 char *output = new char [MAX_STR_LEN];
278 va_list ap;
279 va_start (ap, line);
280 vsprintf (output, line, ap);
281 va_end (ap);
282 standard_log_debug_msg (0, __FILE__, __FUNCTION__, __LINE__, output);
283 events.insertLine (XMondoLog, output);
284 delete[] output;
285}
286
287void
288mvaddstr_and_log_it (int y, int x, char *line)
289{
290 if ((x != 0) && (strcmp (line, "Done.") == 0)) {
291 return;
292 }
293
294 XMondoStatus->setText (line);
295 usleep (250000);
296}
297
298void
299popup_and_OK (char *msg)
300{
301 if (!g_operation_in_progress) return popup_and_OK_sub (msg);
302 events.infoMsg (msg);
303 while (g_result_of_last_event == -1);
304 g_result_of_last_event = -1;
305}
306
307void
308popup_and_OK_sub (char *msg)
309{
310 QMessageBox::information (0, "XMondo", msg, "OK", 0, 0, 0, 0);
311}
312
313int
314popup_and_get_string (char *title, char *msg, char *output, int maxlen)
315{
316 if (!g_operation_in_progress) return popup_and_get_string_sub (title, msg, output, maxlen);
317
318 int res;
319 events.getInfo (title, msg, output, maxlen);
320 while (g_result_of_last_event == -1);
321 res = g_result_of_last_event;
322 g_result_of_last_event = -1;
323 return res;
324}
325
326int
327popup_and_get_string_sub (char *title, char *msg, char *output, int maxlen)
328{
329 bool ok;
330
331 (void) maxlen;
332 QString out = QInputDialog::getText (title, msg, QLineEdit::Normal, QString::null, &ok);
333 if (ok) {
334 strcpy (output, out.ascii());
335 return 1;
336 }
337 return 0;
338}
339
340void
341refresh_log_screen()
342{}
343
344void
345setup_newt_stuff()
346{}
347
348void
349open_evalcall_form (char *ttl)
350{
351 g_isoform_starttime = get_time();
352 events.setTotalSteps (XMondoProgress, 100);
353 events.setProgress (XMondoProgress, 0);
354 events.show (XMondoProgress);
355 events.setText (XMondoProgressWhat, ttl);
356 events.show (XMondoProgressWhat);
357 events.setText (XMondoTimeTaken, "");
358 events.setText (XMondoTimeToGo, "");
359 update_evalcall_form (0);
360}
361
362void
363open_progress_form (char *title, char *line1, char *line2, char *line3, long maxval)
364{
365 g_start_time = get_time();
366 g_maximum_progress = maxval;
367 g_current_progress = 0;
368 events.setTotalSteps (XMondoProgress, maxval);
369 events.setProgress (XMondoProgress, 0);
370 events.show (XMondoProgress);
371 events.setText (XMondoProgressWhat, title);
372 events.show (XMondoProgressWhat);
373 events.setText (XMondoTimeTaken, "");
374 events.setText (XMondoTimeToGo, "");
375 update_progress_form_full (line1, line2, line3);
376}
377
378void
379update_evalcall_form_ratio (int num, int denom)
380{
381 int timeTaken, timeTotal, timeToGo;
382 int percent;
383
384 timeTaken = get_time() - g_isoform_starttime;
385
386 if (num * 100 / denom <= 1) {
387 struct timeval tv;
388 gettimeofday (&tv, 0);
389
390 if (!updater_running) {
391 pthread_create (&updater, 0, run_evalcall_updater_thread, 0);
392 updater_running = true;
393 }
394 QString ttaken;
395 ttaken.sprintf ("%2ld:%02ld taken", timeTaken / 60, timeTaken % 60);
396 events.setTotalSteps (XMondoProgress, 0);
397 events.setProgress (XMondoProgress, (timeTaken * 50) + ((tv.tv_usec / 100000) * 5));
398 events.show (XMondoProgress);
399 events.show (XMondoTimeTaken);
400 events.setText (XMondoTimeTaken, ttaken);
401 events.hide (XMondoTimeToGo);
402 }
403 else {
404 if (updater_running) {
405 pthread_cancel (updater);
406 updater_running = false;
407 }
408 QString ttaken, ttogo;
409 timeTotal = timeTaken * denom / num;
410 timeToGo = timeTotal - timeTaken;
411 ttaken.sprintf ("%2ld:%02ld taken", timeTaken / 60, timeTaken % 60);
412 ttogo.sprintf ("%2ld:%02ld to go", timeToGo / 60, timeToGo % 60);
413 percent = (num * 100 + denom / 2) / denom;
414 events.setTotalSteps (XMondoProgress, 100);
415 events.setProgress (XMondoProgress, percent);
416 events.show (XMondoProgress);
417 events.setText (XMondoTimeTaken, ttaken);
418 events.show (XMondoTimeTaken);
419 events.setText (XMondoTimeToGo, ttogo);
420 events.show (XMondoTimeToGo);
421 }
422}
423
424void update_evalcall_form (int percent)
425{
426 update_evalcall_form_ratio (percent, 100);
427}
428
429void
430update_progress_form (char *b3)
431{
432 if (g_current_progress < -900) {
433 log_it ("Ignoring update_progress_form (it's not open)");
434 return;
435 }
436 events.setText (XMondoProgressWhat3, b3);
437 update_progress_form_full (g_blurb_str_1, g_blurb_str_2, b3);
438}
439
440void
441update_progress_form_full (char *b1, char *b2, char *b3)
442{
443 strcpy (g_blurb_str_1, b1);
444 strcpy (g_blurb_str_2, b2);
445 strcpy (g_blurb_str_3, b3);
446
447 int timeTaken, timeTotal, timeToGo;
448 timeTaken = get_time() - g_start_time;
449 if (g_current_progress) {
450 timeTotal = timeTaken * g_maximum_progress / g_current_progress;
451 timeToGo = timeTotal - timeTaken;
452
453 QString ttaken, ttogo;
454 ttaken.sprintf ("%2ld:%02ld taken", timeTaken / 60, timeTaken % 60);
455 ttogo.sprintf ("%2ld:%02ld to go", timeToGo / 60, timeToGo % 60);
456
457 events.setTotalSteps (XMondoProgress, g_maximum_progress);
458 events.setProgress (XMondoProgress, g_current_progress);
459 events.setText (XMondoTimeTaken, ttaken);
460 events.setText (XMondoTimeToGo, ttogo);
461 events.setText (XMondoProgressWhat, b1);
462 events.setText (XMondoProgressWhat2, b2);
463 events.setText (XMondoProgressWhat3, b3);
464 events.show (XMondoProgressWhat3);
465 events.show (XMondoProgress);
466 events.show (XMondoTimeTaken);
467 events.show (XMondoTimeToGo);
468 events.show (XMondoProgressWhat);
469 events.show (XMondoProgressWhat2);
470 }
471 else {
472 events.setTotalSteps (XMondoProgress, 0);
473 events.setProgress (XMondoProgress, timeTaken * 100);
474 events.show (XMondoProgress);
475 events.hide (XMondoTimeTaken);
476 events.hide (XMondoTimeToGo);
477 events.setText (XMondoProgressWhat, b1);
478 events.show (XMondoProgressWhat);
479 events.setText (XMondoProgressWhat2, b2);
480 events.show (XMondoProgressWhat2);
481 events.setText (XMondoProgressWhat3, b3);
482 events.show (XMondoProgressWhat3);
483 }
484}
485
486void
487close_evalcall_form()
488{
489 if (updater_running) {
490 pthread_cancel (updater);
491 updater_running = false;
492 }
493 update_evalcall_form (100);
494 usleep (500000);
495 events.hide (XMondoProgress);
496 events.hide (XMondoTimeTaken);
497 events.hide (XMondoTimeToGo);
498 events.hide (XMondoProgressWhat);
499 events.hide (XMondoProgressWhat2);
500 events.hide (XMondoProgressWhat3);
501}
502
503void
504close_progress_form()
505{
506 update_progress_form ("Complete");
507 usleep (1000000);
508 events.hide (XMondoProgress);
509 events.hide (XMondoTimeTaken);
510 events.hide (XMondoTimeToGo);
511 events.hide (XMondoProgressWhat);
512 events.hide (XMondoProgressWhat2);
513 events.hide (XMondoProgressWhat3);
514}
515
516t_bkptype which_backup_media_type (bool restoring) {}
517int which_compression_level() {}
518void popup_changelist_from_file (char *file) {}
519
520} /* extern "C" */
521#endif /* WITH_X */
Note: See TracBrowser for help on using the repository browser.