source: trunk/mondo/mondo/common/X-specific.cpp @ 1

Last change on this file since 1 was 1, checked in by bcornec, 14 years ago

Initial import from latest mondo-2.04_cvs_20050503/mindi-1.04_cvs_20050503 on http://www.mondorescue.org

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 ("cat /var/log/mondo-archive.log | gzip -9 > /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, "cat %s | grep \"%s\" | tail -n%d", filename,
255           grep_for_me, NOOF_ERR_LINES);
256    }
257  else
258    {
259      sprintf (command, "cat %s | tail -n%d", filename, NOOF_ERR_LINES);
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.