source: MondoRescue/trunk/mondo/src/common/newt-specific.c@ 900

Last change on this file since 900 was 900, checked in by Bruno Cornec, 18 years ago

Huge patch to introduce low level functions that will bw used everywhere (mr_free, mr_asprintf, ...)
Nearly linking now due to that.

  • Property svn:keywords set to Id
File size: 43.5 KB
RevLine 
[45]1/* $Id: newt-specific.c 900 2006-10-24 06:49:18Z bruno $
[1]2
3 subroutines which do display-type things
4 and use the newt library to do them
5*/
6
7
8/**
9 * @file
10 * Functions for doing display-type things with the Newt library.
11 */
12
13#define MAX_NEWT_COMMENT_LEN 200
14
[837]15#include <stdio.h>
[688]16#include <unistd.h>
[783]17#include <math.h>
[1]18
19#include "my-stuff.h"
20#include "mondostructures.h"
21#include "newt-specific.h"
22#include "libmondo-string-EXT.h"
23#include "libmondo-files-EXT.h"
24#include "libmondo-devices-EXT.h"
25#include "libmondo-tools-EXT.h"
26#include "libmondo-fork-EXT.h"
[507]27#include "newt-specific-EXT.h"
[900]28#include "mr_mem.h"
[1]29
30/*@unused@*/
[45]31//static char cvsid[] = "$Id: newt-specific.c 900 2006-10-24 06:49:18Z bruno $";
[1]32
[783]33extern pid_t g_mastermind_pid;
34extern char *g_tmpfs_mountpt;
35extern char *g_mondo_home;
[838]36extern char *ps_options;
[1]37
[783]38extern void set_signals(int);
[1]39
40/**
41 * @addtogroup globalGroup
42 * @{
43 */
44/**
45 * Whether we are currently in a nested call of fatal_error().
46 */
[783]47bool g_exiting = FALSE;
[1]48
[783]49newtComponent g_timeline = NULL, ///< The line of the progress form that shows the time elapsed/remaining
50 g_percentline = NULL, ///< The line of the progress form that shows the percent completed/remaining
51 g_scale = NULL, ///< The progress bar component in the progress form
52 g_progressForm = NULL, ///< The progress form component itself
53 g_blurb1 = NULL, ///< The component for line 1 of the blurb in the progress form
54 g_blurb2 = NULL, ///< The component for line 2 of the blurb in the progress form
55 g_blurb3 = NULL, ///< The component for line 3 (updated continuously) of the blurb in the progress form
56 g_label = NULL; ///< ????? @bug ?????
[1]57
58/**
59 * Padding above the Newt components, to overcome bugs in Newt.
60 */
[783]61char **err_log_lines = NULL, ///< The list of log lines to show on the screen.
62 *g_blurb_str_1, ///< The string for line 1 of the blurb in the progress form
63 *g_blurb_str_2, ///< The string for line 2 of the blurb in the progress form
64 *g_blurb_str_3; ///< The string for line 3 (updated continuously) of the blurb in the progress form
[45]65 newtComponent g_isoform_main = NULL, ///< The evalcall form component itself
[783]66 g_isoform_header = NULL, ///< The component for the evalcall form title
67 g_isoform_scale = NULL, ///< The progress bar component in the evalcall form
68 g_isoform_timeline = NULL, ///< The line of the evalcall form that shows the time elapsed/remaining
69 g_isoform_pcline = NULL; ///< The line of the evalcall form that shows the percent completed/remaining
70long g_isoform_starttime; ///< The time (in seconds since the epoch) that the evalcall form was opened.
71int g_isoform_old_progress = -1; ///< The most recent progress update of the evalcall form (percent).
72char *g_isoform_header_str; ///< The string for the evalcall form title.
73int g_mysterious_dot_counter; ///< The counter for the twirling baton (/ | \\ - ...) on percentage less than 3
74int g_noof_log_lines = 6; ///< The number of lines to show in the log at the bottom of the screen.
75int g_noof_rows = 25; ///< The number of rows on the screen.
[1]76
[783]77int g_currentY = 3; ///< The row to write background progress messages to. Incremented each time a message is written.
78extern int g_current_media_number;
[45]79 pid_t g_main_pid = 0; ///< The PID of the main Mondo process.
[783]80long g_maximum_progress = 999; ///< The maximum amount of progress (100%) for the currently opened progress form.
81long g_current_progress = -999; ///< The current amount of progress (filelist #, etc.) for the currently opened progress form.
82long g_start_time = 0; ///< The time (in seconds since the epoch) that the progress form was opened.
83bool g_text_mode = TRUE; ///< If FALSE, use a newt interface; if TRUE, use an ugly (but more compatible) dumb terminal interface.
84bool g_called_by_xmondo = FALSE; ///< @bug Unneeded w/current XMondo.
85char *g_erase_tmpdir_and_scratchdir; ///< The command to run to erase the tmpdir and scratchdir at the end of Mondo.
86char *g_selfmounted_isodir = NULL; ///< Holds the NFS mountpoint if mounted via mondoarchive.
[1]87
88/* @} - end of globalGroup */
89
90//int g_fd_in=-1, g_fd_out=-1;
91
[783]92void popup_and_OK(char *);
[1]93
94
95/**
96 * @addtogroup guiGroup
97 * @{
98 */
99/**
100 * Ask the user a yes/no question.
101 * @param prompt The question to ask the user.
102 * @return TRUE for yes; FALSE for no.
103 */
[59]104 bool ask_me_yes_or_no(char *prompt) {
[1]105
[45]106 /*@ buffers ********************************************************** */
107 char *tmp = NULL;
108 int i;
109 size_t n = 0;
[1]110
[59]111 assert_string_is_neither_NULL_nor_zerolength(prompt);
[1]112
[45]113 if (g_text_mode) {
114 while (1) {
[688]115 sync();
[45]116 printf
117 ("---promptdialogYN---1--- %s\r\n---promptdialogYN---Q--- [yes] [no] ---\r\n--> ",
118 prompt);
[900]119 mr_getline(&tmp, &n, stdin);
[45]120 if (tmp[strlen(tmp) - 1] == '\n')
121 tmp[strlen(tmp) - 1] = '\0';
[1]122
[45]123 i = (int) strlen(tmp);
124 if (i > 0 && tmp[i - 1] < 32) {
125 tmp[i - 1] = '\0';
126 }
[507]127 if (strstr(_("yesYES"), tmp)) {
[900]128 mr_free(tmp);
[45]129 return (TRUE);
[507]130 } else if (strstr(_("NOno"), tmp)) {
[900]131 mr_free(tmp);
[45]132 return (FALSE);
133 } else {
[688]134 sync();
[45]135 printf
[507]136 (_("Please enter either YES or NO (or yes or no, or y or n, or...)\n"));
[45]137 }
138 }
139 } else {
[507]140 return (popup_with_buttons(prompt, _("Yes"), _("No")));
[45]141 }
142 }
[1]143
144
145/**
146 * Give the user the opportunity to continue the current operation (OK)
147 * or cancel it (Cancel).
148 * @param prompt The string to be displayed.
149 * @return TRUE for OK, FALSE for Cancel.
150 */
[45]151 bool ask_me_OK_or_cancel(char *prompt) {
[1]152
[45]153 /*@ buffer *********************************************************** */
154 char *tmp = NULL;
155 int i;
156 size_t n = 0;
[1]157
[45]158 assert_string_is_neither_NULL_nor_zerolength(prompt);
159 if (g_text_mode) {
[688]160 sync();
[45]161 printf
162 ("---promptdialogOKC---1--- %s\r\n---promptdialogOKC---Q--- [OK] [Cancel] ---\r\n--> ",
163 prompt);
[900]164 mr_getline(&tmp, &n, stdin);
[45]165 if (tmp[strlen(tmp) - 1] == '\n')
166 tmp[strlen(tmp) - 1] = '\0';
[1]167
[45]168 i = (int) strlen(tmp);
169 if (i > 0 && tmp[i - 1] < 32) {
170 tmp[i - 1] = '\0';
171 }
[507]172 if (strstr(_("okOKOkYESyes"), tmp)) {
[900]173 mr_free(tmp);
[45]174 return (TRUE);
175 } else {
[900]176 mr_free(tmp);
[45]177 return (FALSE);
178 }
179 } else {
[507]180 return (popup_with_buttons(prompt, _(" Okay "), _("Cancel")));
[45]181 }
[1]182 }
183
184
185/**
186 * Close the currently opened evalcall form.
187 */
[45]188 void
189 close_evalcall_form(void) {
190 if (g_text_mode) {
191 return;
192 }
193 if (g_isoform_main == NULL) {
194 return;
195 }
196 update_evalcall_form(100);
197 usleep(500000);
198 if (g_text_mode) {
199 log_msg(2, "Closing evalcall form");
200 return;
201 }
202 newtPopHelpLine();
203 newtFormDestroy(g_isoform_main);
204 newtPopWindow();
205 g_isoform_main = NULL;
206 g_isoform_old_progress = -1;
207 }
[1]208
209
210/**
211 * Close the currently opened progress form.
212 */
[59]213 void
214 close_progress_form() {
215 if (g_text_mode) {
216 return;
217 }
218 if (g_current_progress == -999) {
219 log_msg(2,
220 "Trying to close the progress form when it ain't open!");
221 return;
222 }
223 g_current_progress = g_maximum_progress;
224 update_progress_form("Complete");
225 sleep(1);
226 if (g_text_mode) {
227 log_msg(2, "Closing progress form");
228 return;
229 }
230 newtPopHelpLine();
231 newtFormDestroy(g_progressForm);
232 newtPopWindow();
233 g_progressForm = NULL;
234 g_current_progress = -999;
[45]235 }
[1]236
[794]237/**
[837]238 * Kill any process containing the string @p str
239 * surrounded by spaces in its commandline.
[794]240 */
[838]241static void
242 kill_anything_like_this(char *str) {
[1]243
[838]244 char *tmp = NULL;
[794]245
[900]246 mr_asprintf(&tmp,"kill `ps %s | grep \" %s \" | awk '{print $1;}' | grep -vx \"\\?\"`", ps_options, str);
[794]247run_program_and_log_output(tmp, TRUE);
[900]248 mr_free(tmp);
[794]249}
250
[1]251/**
252 * Exit Mondo with a fatal error.
253 * @param error_string The error message to present to the user before exiting.
254 * @note This function never returns.
255 */
[45]256 void
257 fatal_error(char *error_string) {
258 /*@ buffers ***************************************************** */
[87]259 char *fatalstr;
[45]260 char *tmp;
[75]261 char *command;
[45]262 static bool already_exiting = FALSE;
263 int i;
[1]264
[45]265 /*@ end vars **************************************************** */
[1]266
[900]267 mr_asprintf(&fatalstr, "-------FATAL ERROR---------");
[45]268 set_signals(FALSE); // link to external func
269 g_exiting = TRUE;
[87]270 log_msg(1, "%s - '%s'", fatalstr, error_string);
271 printf("%s - %s\n", fatalstr, error_string);
[45]272 if (getpid() == g_mastermind_pid) {
273 log_msg(2, "mastermind %d is exiting", (int) getpid());
274 kill(g_main_pid, SIGTERM);
275 finish(1);
276 }
[1]277
[45]278 if (getpid() != g_main_pid) {
279 if (g_mastermind_pid != 0 && getpid() != g_mastermind_pid) {
280 log_msg(2, "non-m/m %d is exiting", (int) getpid());
281 kill(g_main_pid, SIGTERM);
282 finish(1);
283 }
284 }
[1]285
[45]286 log_msg(3, "OK, I think I'm the main PID.");
287 if (already_exiting) {
288 log_msg(3, "...I'm already exiting. Give me time, Julian!");
289 finish(1);
290 }
[1]291
[45]292 already_exiting = TRUE;
293 log_msg(2, "I'm going to do some cleaning up now.");
294 paranoid_system("killall mindi 2> /dev/null");
295 kill_anything_like_this("/mondo/do-not");
[688]296 kill_anything_like_this("mondo.tmp");
[300]297 kill_anything_like_this("ntfsclone");
[45]298 sync();
[783]299 if (g_tmpfs_mountpt != NULL) {
[900]300 mr_asprintf(&tmp, "umount %s", g_tmpfs_mountpt);
[783]301 chdir("/");
302 for (i = 0; i < 10 && run_program_and_log_output(tmp, 5); i++) {
303 log_msg(2, "Waiting for child processes to terminate");
304 sleep(1);
305 run_program_and_log_output(tmp, 5);
306 }
[900]307 mr_free(tmp);
[45]308 }
[1]309
[688]310 if (g_erase_tmpdir_and_scratchdir) {
[45]311 run_program_and_log_output(g_erase_tmpdir_and_scratchdir, 5);
312 }
[1]313
[75]314 if (g_selfmounted_isodir) {
[900]315 mr_asprintf(&command, "umount %s", g_selfmounted_isodir);
[89]316 run_program_and_log_output(command, 5);
[900]317 mr_asprintf(&command, "rmdir %s", g_selfmounted_isodir);
[89]318 run_program_and_log_output(command, 5);
[900]319 mr_free(g_selfmounted_isodir);
[75]320 }
321
[45]322 if (!g_text_mode) {
323 log_msg(0, fatalstr);
324 log_msg(0, error_string);
325 newtFinished();
326 }
[1]327
[219]328 printf
[507]329 (_("If you require technical support, please contact the mailing list.\n"));
330 printf(_("See http://www.mondorescue.org for details.\n"));
[219]331 printf
[507]332 (_("The list's members can help you, if you attach that file to your e-mail.\n"));
333 printf(_("Log file: %s\n"), MONDO_LOGFILE);
334 printf(_("Mondo has aborted.\n"));
[45]335 register_pid(0, "mondo"); // finish() does this too, FYI
336 if (!g_main_pid) {
337 log_msg(3, "FYI - g_main_pid is blank");
338 }
339 finish(254);
340 }
[1]341
342
343
344/**
345 * Exit Mondo normally.
346 * @param signal The exit code (0 indicates a successful backup; 1 for Mondo means the
347 * user aborted; 254 means a fatal error occured).
348 * @note This function never returns.
349 */
[45]350 void
351 finish(int signal) {
[688]352 char *command = NULL;
[1]353
[45]354 register_pid(0, "mondo");
355 chdir("/");
356 run_program_and_log_output("umount " MNT_CDROM, FALSE);
[688]357 run_program_and_log_output("rm -Rf /mondo.scratch.* /mondo.tmp.*",
[45]358 FALSE);
359 if (g_erase_tmpdir_and_scratchdir) {
360 run_program_and_log_output(g_erase_tmpdir_and_scratchdir, 1);
361 }
[75]362 if (g_selfmounted_isodir) {
[900]363 mr_asprintf(&command, "umount %s", g_selfmounted_isodir);
[89]364 run_program_and_log_output(command, 1);
[900]365 mr_asprintf(&command, "rmdir %s", g_selfmounted_isodir);
[89]366 run_program_and_log_output(command, 1);
[900]367 mr_free(g_selfmounted_isodir);
[75]368 }
[45]369 if (!g_text_mode) {
370 if (does_file_exist("/THIS-IS-A-RAMDISK")) {
371 log_msg(1, "Calling newtFinished()");
372 newtFinished();
373 } else {
374 log_msg(1, "Calling newtSuspend()");
375 newtSuspend();
376 }
377 }
[507]378 printf(_("Execution run ended; result=%d\n"), signal);
379 printf(_("Type 'less %s' to see the output log\n"), MONDO_LOGFILE);
[45]380 free_libmondo_global_strings();
381 exit(signal);
382 }
[1]383
384
385
386
387
388/**
389 * Log the last @p g_noof_log_lines lines of @p filename that match @p
390 * grep_for_me to the screen.
391 * @param filename The file to give the end of.
392 * @param grep_for_me If not "", then only give lines in @p filename that match this regular expression.
393 */
[45]394 void
395 log_file_end_to_screen(char *filename, char *grep_for_me) {
[1]396
[45]397 /*@ buffers ********************************************************** */
[688]398 char *command = NULL;
399 char *tmp = NULL;
[1]400
[45]401 /*@ pointers ********************************************************* */
[688]402 FILE *fin = NULL;
[1]403
[45]404 /*@ int ************************************************************** */
405 int i = 0;
[688]406 size_t n = 0;
[1]407
[45]408 assert_string_is_neither_NULL_nor_zerolength(filename);
409 assert(grep_for_me != NULL);
[1]410
[45]411 if (!does_file_exist(filename)) {
412 return;
[1]413 }
[45]414 if (grep_for_me[0] != '\0') {
[900]415 mr_asprintf(&command, "grep '%s' %s | tail -n%d",
[127]416 grep_for_me, filename, g_noof_log_lines);
[45]417 } else {
[900]418 mr_asprintf(&command, "tail -n%d %s", g_noof_log_lines, filename);
[1]419 }
[45]420 fin = popen(command, "r");
421 if (!fin) {
422 log_OS_error(command);
423 } else {
424 for (i = 0; i < g_noof_log_lines; i++) {
[688]425 for (;
426 strlen(err_log_lines[i]) < 2 && !feof(fin);) {
[900]427 mr_getline(&(err_log_lines[i]), &n, fin);
[45]428 strip_spaces(err_log_lines[i]);
429 if (!strncmp(err_log_lines[i], "root:", 5)) {
[900]430 mr_asprintf(&tmp, "%s", err_log_lines[i] + 6);
431 mr_free(err_log_lines[i]);
[688]432 err_log_lines[i] = tmp;
[45]433 }
434 if (feof(fin)) {
435 break;
436 }
437 }
438 }
439 paranoid_pclose(fin);
440 }
441 refresh_log_screen();
[900]442 mr_free(command);
[1]443 }
444
445
446/**
447 * Log a message to the screen.
448 * @param fmt A printf-style format string to write. The following parameters are its arguments.
449 * @note The message is also written to the logfile.
450 */
[45]451 void
452 log_to_screen(const char *fmt, ...) {
[1]453
[45]454 /*@ int ************************************************************** */
455 int i = 0;
456 int j = 0;
457 va_list args;
[1]458
[45]459 /*@ buffers ********************************************************** */
[688]460 char *output = NULL;
[1]461
462
[45]463 va_start(args, fmt);
[900]464 mr_vasprintf(&output, fmt, args);
[45]465 log_msg(0, output);
[58]466 if (strlen(output) > 80) {
[56]467 output[80] = '\0';
468 }
[45]469 va_end(args);
470 i = (int) strlen(output);
471 if (i > 0 && output[i - 1] < 32) {
472 output[i - 1] = '\0';
473 }
[1]474
[45]475 if (err_log_lines) {
[900]476 mr_free(err_log_lines[0]);
[45]477 for (i = 1; i < g_noof_log_lines; i++) {
[688]478 err_log_lines[i - 1] = err_log_lines[i];
[45]479 }
480 }
481 while (strlen(output) > 0 && output[strlen(output) - 1] < 32) {
482 output[strlen(output) - 1] = '\0';
483 }
484 for (j = 0; j < (int) strlen(output); j++) {
485 if (output[j] < 32) {
486 output[j] = ' ';
487 }
488 }
489 if (err_log_lines)
[688]490 err_log_lines[g_noof_log_lines - 1] = output;
[45]491 if (g_text_mode) {
492 printf("%s\n", output);
493 } else {
494 refresh_log_screen();
495 }
[1]496 }
497
498
499/**
500 * Write a string to the root window at (@p x, @p y) and also to the logfile.
501 * @param y The row to write the string to.
502 * @param x The column to write the string to.
503 * @param output The string to write.
504 */
[45]505 void
506 mvaddstr_and_log_it(int y, int x, char *output) {
507 assert_string_is_neither_NULL_nor_zerolength(output);
508 log_msg(0, output);
509 if (g_text_mode) {
510 printf("%s\n", output);
511 } else {
512 newtDrawRootText(x, y, output);
513 newtRefresh();
514 }
515 }
[1]516
517
518
519
520/**
521 * Open an evalcall form with title @p ttl.
522 * @param ttl The title to use for the evalcall form.
523 */
[45]524 void
525 open_evalcall_form(char *ttl) {
[1]526
[45]527 /*@ buffers ********************************************************* */
528 char *title;
529 char *tmp;
[1]530
[45]531 /*@ initialize ****************************************************** */
532 g_isoform_old_progress = -1;
533 g_mysterious_dot_counter = 0;
[1]534
[45]535 assert(ttl != NULL);
[900]536 mr_asprintf(&title, ttl);
[87]537 // BERLIOS: We need to unallocate it somewhere
[900]538 mr_asprintf(&g_isoform_header_str, title);
[87]539 // center_string (title, 80);
[45]540 if (g_text_mode) {
541 log_msg(0, title);
542 } else {
[900]543 mr_asprintf(&tmp, title);
[87]544 /* BERLIOS: center_string is now broken replace it ! */
545 //center_string(tmp, 80);
[45]546 newtPushHelpLine(tmp);
[900]547 mr_free(tmp);
[45]548 }
[87]549 /* BERLIOS: center_string is now broken replace it ! */
550 //center_string(g_isoform_header_str, 36);
[45]551 g_isoform_starttime = get_time();
552 if (g_text_mode) {
553 log_msg(0, g_isoform_header_str);
554 } else {
555 g_isoform_header = newtLabel(1, 1, g_isoform_header_str);
556 g_isoform_scale = newtScale(3, 3, 34, 100);
557 // newtOpenWindow (20, 6, 40, 7, title); // "Please Wait");
558 newtCenteredWindow(40, 7, title);
559 g_isoform_main = newtForm(NULL, NULL, 0);
560 g_isoform_timeline = newtLabel(1, 5, "This is the timeline");
561 g_isoform_pcline = newtLabel(1, 6, "This is the pcline");
562 newtFormAddComponents(g_isoform_main, g_isoform_timeline,
563 g_isoform_pcline, g_isoform_header,
564 g_isoform_scale, NULL);
565 newtRefresh();
566 }
567 update_evalcall_form(0);
[900]568 mr_free(title);
[45]569 }
[1]570
571
572
573/**
574 * Open a progress form with title @p title.
575 * @param title The title to use for the progress form (will be put in the title bar on Newt).
576 * @param b1 The first line of the blurb; generally static.
577 * @param b2 The second line of the blurb; generally static.
578 * @param b3 The third line of the blurb; generally dynamic (it is passed
579 * to update_evalcall_form() every time).
580 * @param max_val The maximum amount of progress (number of filesets, etc.)
581 */
[45]582 void
583 open_progress_form(char *title, char *b1, char *b2, char *b3,
584 long max_val) {
[1]585
[45]586 /*@ buffers ********************************************************* */
587 char *b1c;
588 char *blurb1;
589 char *blurb2;
590 char *blurb3;
[1]591
[45]592 /*@ initialize ****************************************************** */
593 g_mysterious_dot_counter = 0;
[1]594
[45]595 assert(title != NULL);
596 assert(b1 != NULL);
597 assert(b2 != NULL);
598 assert(b3 != NULL);
[1]599
[900]600 mr_asprintf(&blurb1, b1);
601 mr_asprintf(&blurb2, b2);
602 mr_asprintf(&blurb3, b3);
603 mr_asprintf(&b1c, b1);
[87]604 /* BERLIOS: center_string is now broken replace it ! */
605 //center_string(b1c, 80);
[45]606 if (max_val <= 0) {
607 max_val = 1;
608 }
[1]609
[45]610 g_start_time = get_time();
611 g_maximum_progress = max_val;
612 g_current_progress = 0;
[87]613 // BERLIOS: We need to unallocate them
[900]614 mr_asprintf(&g_blurb_str_1, blurb1);
615 mr_asprintf(&g_blurb_str_2, blurb3);
616 mr_asprintf(&g_blurb_str_3, blurb2);
[45]617 if (g_text_mode) {
618 log_msg(0, blurb1);
619 log_msg(0, blurb2);
620 log_msg(0, blurb3);
621 } else {
622 g_blurb1 = newtLabel(2, 1, blurb1);
623 g_blurb2 = newtLabel(2, 2, blurb3);
624 g_blurb3 = newtLabel(2, 4, blurb2);
625 // newtOpenWindow (10, 4, 60, 11, title);
626 newtCenteredWindow(60, 11, title);
627 g_scale = newtScale(3, 6, 54, g_maximum_progress);
628 g_progressForm = newtForm(NULL, NULL, 0);
629 g_percentline = newtLabel(10, 9, "This is the percentline");
630 g_timeline = newtLabel(10, 8, "This is the timeline");
631 newtFormAddComponents(g_progressForm, g_percentline,
632 g_timeline, g_scale, g_blurb1, g_blurb3,
633 g_blurb2, NULL);
634 newtPushHelpLine(b1c);
635 newtRefresh();
636 }
637 update_progress_form_full(blurb1, blurb2, blurb3);
[900]638 mr_free(b1c);
639 mr_free(blurb1);
640 mr_free(blurb2);
641 mr_free(blurb3);
[45]642 }
643
[1]644/**
645 * Give a message to the user in the form of a dialog box (under Newt).
646 * @param prompt The message.
647 */
[45]648 void
649 popup_and_OK(char *prompt) {
650 char ch;
[1]651
[45]652 assert_string_is_neither_NULL_nor_zerolength(prompt);
[1]653
[45]654 log_msg(0, prompt);
655 if (g_text_mode) {
656 printf
657 ("---promptpopup---1--- %s\r\n---promptpopup---Q--- [OK] ---\r\n--> ",
658 prompt);
659 while (((ch = getchar()) != '\n') && (ch != EOF));
660 } else {
[507]661 (void) popup_with_buttons(prompt, _(" OK "), "");
[45]662 }
663 }
[1]664
665/**
666 * Ask the user to enter a value.
667 * @param title The title of the dialog box.
668 * @param b The blurb (e.g. what you want the user to enter).
[146]669 * @param output The string to put the user's answer in. It has to be freed by the caller
[1]670 * @return TRUE if the user pressed OK, FALSE if they pressed Cancel.
671 */
[688]672 bool popup_and_get_string(char *title, char *b, char *output) {
[1]673
[45]674 /*@ newt ************************************************************ */
675 newtComponent myForm;
676 newtComponent b_1;
677 newtComponent b_2;
678 newtComponent b_res;
679 newtComponent text;
680 newtComponent type_here;
[1]681
[45]682 /*@ pointers ********************************************************* */
[783]683 char **entry_value = NULL;
[1]684
[45]685 /*@ buffers ********************************************************** */
[688]686 char *blurb = NULL;
[171]687 size_t n = 0;
[688]688 bool ret = TRUE;
[1]689
[45]690 assert_string_is_neither_NULL_nor_zerolength(title);
691 assert(b != NULL);
[1]692
[45]693 if (g_text_mode) {
694 printf
695 ("---promptstring---1--- %s\r\n---promptstring---2--- %s\r\n---promptstring---Q---\r\n--> ",
696 title, b);
[900]697 mr_free(output);
698 mr_getline(&output, &n, stdin);
[45]699 if (output[strlen(output) - 1] == '\n')
700 output[strlen(output) - 1] = '\0';
[688]701 return (ret);
[45]702 }
[900]703 mr_asprintf(&blurb, b);
[45]704 text = newtTextboxReflowed(2, 1, blurb, 48, 5, 5, 0);
[146]705
[45]706 type_here =
707 newtEntry(2, newtTextboxGetNumLines(text) + 2,
[688]708 output, 50,
[837]709 (void *)entry_value, NEWT_FLAG_RETURNEXIT
[45]710 );
[507]711 b_1 = newtButton(6, newtTextboxGetNumLines(text) + 4, _(" OK "));
712 b_2 = newtButton(18, newtTextboxGetNumLines(text) + 4, _("Cancel"));
[45]713 newtCenteredWindow(54, newtTextboxGetNumLines(text) + 9, title);
714 myForm = newtForm(NULL, NULL, 0);
715 newtFormAddComponents(myForm, text, type_here, b_1, b_2, NULL);
[87]716 /* BERLIOS: center_string is now broken replace it ! */
717 //center_string(blurb, 80);
[45]718 newtPushHelpLine(blurb);
[900]719 mr_free(blurb);
[688]720
[45]721 b_res = newtRunForm(myForm);
722 newtPopHelpLine();
723 if (b_res == b_2) {
[688]724 ret = FALSE;
[45]725 } else {
[688]726 // Copy entry_value before destroying the form
727 // clearing potentially output before
[900]728 mr_allocstr(output,*entry_value);
[45]729 }
[688]730 newtFormDestroy(myForm);
731 newtPopWindow();
732 return(ret);
[45]733 }
[1]734
735
736/**
737 * Pop up a dialog box with user-defined buttons.
738 * @param p The text to put in the dialog box.
739 * @param button1 The label on the first button.
740 * @param button2 The label on the second button, or "" if you only want one button.
741 * @return TRUE if @p button1 was pushed, FALSE otherwise.
742 */
[45]743 bool popup_with_buttons(char *p, char *button1, char *button2) {
[1]744
[45]745 /*@ buffers *********************************************************** */
[87]746 char *prompt;
747 char *tmp = NULL;
748 size_t n = 0;
[1]749
[45]750 /*@ newt ************************************************************** */
751 newtComponent myForm;
752 newtComponent b_1;
753 newtComponent b_2;
754 newtComponent b_res;
755 newtComponent text;
[1]756
[45]757 assert_string_is_neither_NULL_nor_zerolength(p);
758 assert(button1 != NULL);
759 assert(button2 != NULL);
760 if (g_text_mode) {
761 if (strlen(button2) == 0) {
762 printf("%s (%s) --> ", p, button1);
763 } else {
764 printf("%s (%s or %s) --> ", p, button1, button2);
765 }
[900]766 for (mr_asprintf(&tmp, " ");
[45]767 strcmp(tmp, button1) && (strlen(button2) == 0
768 || strcmp(tmp, button2));) {
769 printf("--> ");
[900]770 mr_free(tmp);
771 mr_getline(&tmp, &n, stdin);
[45]772 }
773 if (!strcmp(tmp, button1)) {
[900]774 mr_free(tmp);
[45]775 return (TRUE);
776 } else {
[900]777 mr_free(tmp);
[45]778 return (FALSE);
779 }
780 }
[1]781
[900]782 mr_asprintf(&prompt, p);
[45]783 text = newtTextboxReflowed(1, 1, prompt, 40, 5, 5, 0);
784 b_1 =
785 newtButton(20 -
786 ((button2[0] !=
787 '\0') ? strlen(button1) +
788 2 : strlen(button1) / 2),
789 newtTextboxGetNumLines(text) + 3, button1);
790 if (button2[0] != '\0') {
791 b_2 =
792 newtButton(24, newtTextboxGetNumLines(text) + 3, button2);
793 } else {
794 b_2 = NULL;
795 }
796 // newtOpenWindow (25, 5, 46, newtTextboxGetNumLines (text) + 7, "Alert");
[507]797 newtCenteredWindow(46, newtTextboxGetNumLines(text) + 7, _("Alert"));
[45]798 myForm = newtForm(NULL, NULL, 0);
799 newtFormAddComponents(myForm, text, b_1, b_2, NULL);
[87]800 /* BERLIOS: center_string is now broken replace it ! */
801 //center_string(prompt, 80);
[45]802 newtPushHelpLine(prompt);
[900]803 mr_free(prompt);
[45]804 b_res = newtRunForm(myForm);
805 newtPopHelpLine();
806 newtFormDestroy(myForm);
807 newtPopWindow();
808 if (b_res == b_1) {
809 return (TRUE);
810 } else {
811 return (FALSE);
812 }
813 }
[1]814
815
816
[45]817
[1]818/**
819 * Synchronize the log messages stored in @p err_log_lines with those shown
820 * on the screen.
821 */
[45]822 void
823 refresh_log_screen() {
[1]824
[45]825 /*@ int *********************************************************** */
826 int i = 0;
[1]827
828
[45]829 if (g_text_mode || !err_log_lines) {
830 return;
831 }
832 for (i = g_noof_log_lines - 1; i >= 0; i--) {
833 newtDrawRootText(0, i + g_noof_rows - 1 - g_noof_log_lines,
834 " ");
835 }
836 newtRefresh();
837 for (i = g_noof_log_lines - 1; i >= 0; i--) {
[688]838 //BERLIOS : removed for now, Think it's useless : err_log_lines[i][79] = '\0';
[45]839 newtDrawRootText(0, i + g_noof_rows - 1 - g_noof_log_lines,
840 err_log_lines[i]);
841 }
842 newtRefresh();
843 }
[1]844
845
846/**
847 * Set up the Newt graphical environment. If @p g_text_mode is TRUE, then
848 * only allocate some memory.
849 */
[45]850 void
851 setup_newt_stuff() {
[1]852
[45]853 /*@ int *********************************************************** */
854 int i = 0;
855 int cols;
[1]856
[45]857 if (!g_text_mode) {
858 newtInit();
859 newtCls();
860 newtPushHelpLine
[588]861 (_("Welcome to Mondo Rescue, by Dev Team and the Internet. All rights reversed."));
[45]862 /* newtDrawRootText(28,0,"Welcome to Mondo Rescue"); */
863 newtDrawRootText(18, 0, WELCOME_STRING);
864 newtRefresh();
865 newtGetScreenSize(&cols, &g_noof_rows);
866 g_noof_log_lines = (g_noof_rows / 5) + 1;
867 }
[1]868
[45]869 err_log_lines =
870 (char **) malloc(sizeof(char *) * g_noof_log_lines);
871 if (!err_log_lines) {
872 fatal_error("Out of memory");
873 }
[1]874
[45]875 for (i = 0; i < g_noof_log_lines; i++) {
[688]876 err_log_lines[i] = NULL;
[45]877 }
878 }
[1]879
880
881/**
[87]882 * Update the evalcall form to show <tt>num</tt> %.
[1]883 * @param num The numerator of the ratio.
884 */
[45]885 void
[87]886 update_evalcall_form(int num) {
[1]887
[45]888 /*@ long ************************************************************ */
889 long current_time = 0;
890 long time_taken = 0;
891 long time_total_est = 0;
892 long time_remaining = 0;
[1]893
[45]894 /*@ buffers ********************************************************** */
895 char *timeline_str;
896 char *pcline_str;
897 char *taskprogress;
[87]898 char *tmp1;
899 char *tmp2;
900 char *p;
[1]901
[45]902 /*@ int ************************************************************** */
903 int percentage = 0;
904 int i = 0;
905 int j = 0;
[1]906
[87]907 //log_it("update_eval_call_form called");
908 if (num < 1) {
[45]909 percentage = 1;
910 } else {
[89]911 percentage = (int) trunc(num);
[45]912 }
913
914 current_time = get_time();
915 time_taken = current_time - g_isoform_starttime;
916 if (num) {
[87]917 time_total_est = time_taken * 100 / num;
[45]918 time_remaining = time_total_est - time_taken;
919 } else {
920 time_remaining = 0;
921 }
922 if (!g_text_mode) {
923 newtLabelSetText(g_isoform_header, g_isoform_header_str);
924 }
[87]925 /* BERLIOS: 27 should be a parameter */
[45]926 g_mysterious_dot_counter = (g_mysterious_dot_counter + 1) % 27;
927 if ((percentage < 3 && g_isoform_old_progress < 3)
928 || percentage > g_isoform_old_progress) {
929 g_isoform_old_progress = percentage;
[900]930 mr_asprintf(&timeline_str,
[507]931 _("%2ld:%02ld taken %2ld:%02ld remaining"),
[89]932 time_taken / 60, time_taken % 60, time_remaining / 60,
933 time_remaining % 60);
[45]934 if (percentage < 3) {
[89]935 tmp1 =
936 (char *) malloc(g_mysterious_dot_counter *
937 sizeof(char));
938 for (i = 0, p = tmp1; i < g_mysterious_dot_counter - 1;
939 i++, p++) {
940 *p = '.';
[45]941 }
[87]942 *p = '\0';
943
944 /* BERLIOS: 27 should be a parameter */
[89]945 tmp2 =
946 (char *) malloc(27 -
947 g_mysterious_dot_counter *
948 sizeof(char));
949 for (i = 0, p = tmp2;
950 i < 27 - g_mysterious_dot_counter - 1; i++, p++) {
951 *p = ' ';
[45]952 }
[87]953 *p = '\0';
954
[900]955 mr_asprintf(&pcline_str, " Working%s%s %c", tmp1, tmp2,
[89]956 special_dot_char(g_mysterious_dot_counter));
[900]957 mr_free(tmp1);
958 mr_free(tmp2);
[45]959 } else {
[900]960 mr_asprintf(&pcline_str,
[507]961 _(" %3d%% done %3d%% to go"),
[89]962 percentage, 100 - percentage);
[45]963 }
964 if (g_text_mode) {
[89]965 j = trunc(percentage / 5);
966 tmp1 = (char *) malloc((j + 1) * sizeof(char));
967 for (i = 0, p = tmp1; i < j; i++, p++) {
968 *p = '*';
[45]969 }
[87]970 *p = '\0';
971
[89]972 tmp2 = (char *) malloc((20 - j + 1) * sizeof(char));
973 for (i = 0, p = tmp2; i < 20 - j; i++, p++) {
974 *p = '.';
[45]975 }
[87]976 *p = '\0';
977
[45]978 if (percentage >= 3) {
[900]979 mr_asprintf(&taskprogress,
[89]980 "TASK: [%s%s] %3d%% done; %2ld:%02ld to go",
981 tmp1, tmp2, percentage, time_remaining / 60,
982 time_remaining % 60);
[45]983 printf("---evalcall---1--- %s\r\n",
984 g_isoform_header_str);
985 printf("---evalcall---2--- %s\r\n", taskprogress);
986 printf("---evalcall---E---\r\n");
[900]987 mr_free(taskprogress);
[45]988 }
989 } else {
990 newtScaleSet(g_isoform_scale,
991 (unsigned long long) percentage);
992 newtLabelSetText(g_isoform_pcline, pcline_str);
993 if (percentage >= 3) {
994 newtLabelSetText(g_isoform_timeline, timeline_str);
995 }
996 }
[900]997 mr_free(timeline_str);
998 mr_free(pcline_str);
[45]999 }
1000 if (!g_text_mode) {
1001// log_it("refreshing");
1002 newtRefresh();
1003 }
[1]1004 }
1005
1006
1007/**
1008 * Update the progress form to show @p blurb3 and the current value of
1009 * @p g_maximum_progress.
1010 * @param blurb3 The new third line of the blurb; use @p g_blurb_str_2 (no, that's not a typo) to keep it the same.
1011 */
[45]1012 void
1013 update_progress_form(char *blurb3) {
1014 /* log_it("update_progress_form --- called"); */
1015 if (g_current_progress == -999) {
1016 /* log_it("You're trying to update progress form when it ain't open. Aww, that's OK. I'll let it go. It's a bit naughty but it's a nonfatal error. No prob, Bob."); */
1017 return;
1018 }
[900]1019 mr_free(g_blurb_str_2);
1020 mr_asprintf(&g_blurb_str_2, blurb3);
[45]1021 update_progress_form_full(g_blurb_str_1, g_blurb_str_2,
1022 g_blurb_str_3);
1023 }
[1]1024
1025
1026/**
1027 * Update the progress form's complete blurb and show @p g_current_progress.
1028 * @param blurb1 The first line of the blurb. Use @p g_blurb_str_1 to keep it unchanged.
1029 * @param blurb2 The second line of the blurb. Use @p g_blurb_str_3 (no, that's not a typo) to keep it the same.
1030 * @param blurb3 The third line of the blurb. Use @p g_blurb_str_2 (no, that's not a typo either) to keep it the same.
1031 */
[45]1032 void
1033 update_progress_form_full(char *blurb1, char *blurb2, char *blurb3) {
1034 /*@ long ***************************************************** */
1035 long current_time = 0;
1036 long time_taken = 0;
1037 long time_remaining = 0;
1038 long time_total_est = 0;
[1]1039
[45]1040 /*@ int ******************************************************* */
1041 int percentage = 0;
1042 int i = 0;
[87]1043 int j = 0;
[1]1044
[45]1045 /*@ buffers *************************************************** */
1046 char *percentline_str;
1047 char *timeline_str;
1048 char *taskprogress;
1049 char *tmp;
[87]1050 char *tmp1;
1051 char *tmp2;
1052 char *p;
[1]1053
1054// log_msg(1, "'%s' '%s' '%s'", blurb1, blurb2, blurb3);
[45]1055 if (!g_text_mode) {
1056 assert(blurb1 != NULL);
1057 assert(blurb2 != NULL);
1058 assert(blurb3 != NULL);
1059 assert(g_timeline != NULL);
1060 }
[1]1061
[45]1062 current_time = get_time();
1063 time_taken = current_time - g_start_time;
1064 if (g_maximum_progress == 0) {
1065 percentage = 0;
1066 } else {
1067 if (g_current_progress > g_maximum_progress) {
[900]1068 mr_asprintf(&tmp,
[89]1069 "update_progress_form_full(%s,%s,%s) --- g_current_progress=%ld; g_maximum_progress=%ld",
1070 blurb1, blurb2, blurb3, g_current_progress,
1071 g_maximum_progress);
[45]1072 log_msg(0, tmp);
[900]1073 mr_free(tmp);
[45]1074 g_current_progress = g_maximum_progress;
1075 }
1076 percentage =
1077 (int) ((g_current_progress * 100L) / g_maximum_progress);
1078 }
1079 if (percentage < 1) {
1080 percentage = 1;
1081 }
1082 if (percentage > 100) {
1083 percentage = 100;
1084 }
1085 if (g_current_progress) {
1086 time_total_est =
1087 time_taken * (long) g_maximum_progress /
1088 (long) (g_current_progress);
1089 time_remaining = time_total_est - time_taken;
1090 } else {
1091 time_remaining = 0;
1092 }
[87]1093 /* BERLIOS/ Is it useful here ? */
1094 //g_mysterious_dot_counter = (g_mysterious_dot_counter + 1) % 27;
[900]1095 mr_asprintf(&timeline_str,
[89]1096 "%2ld:%02ld taken %2ld:%02ld remaining ",
1097 time_taken / 60, time_taken % 60, time_remaining / 60,
1098 time_remaining % 60);
[900]1099 mr_asprintf(&percentline_str,
[89]1100 " %3d%% done %3d%% to go", percentage,
1101 100 - percentage);
[1]1102
[45]1103 if (g_text_mode) {
[507]1104 printf(_("---progress-form---1--- %s%s"), blurb1, "\r\n");
1105 printf(_("---progress-form---2--- %s%s"), blurb2, "\r\n");
1106 printf(_("---progress-form---3--- %s%s"), blurb3, "\r\n");
1107 printf(_("---progress-form---E---\n"));
[87]1108
[89]1109 j = trunc(percentage / 5);
1110 tmp1 = (char *) malloc((j + 1) * sizeof(char));
1111 for (i = 0, p = tmp1; i < j; i++, p++) {
1112 *p = '*';
[45]1113 }
[87]1114 *p = '\0';
1115
[89]1116 tmp2 = (char *) malloc((20 - j + 1) * sizeof(char));
1117 for (i = 0, p = tmp2; i < 20 - j; i++, p++) {
1118 *p = '.';
[45]1119 }
[87]1120 *p = '\0';
1121
[45]1122 if (percentage > 100) {
[507]1123 log_msg(2, _("percentage = %d"), percentage);
[45]1124 }
[900]1125 mr_asprintf(&taskprogress,
[507]1126 _("TASK: [%s%s] %3d%% done; %2ld:%02ld to go"), tmp1,
[89]1127 tmp2, percentage, time_remaining / 60,
1128 time_remaining % 60);
[87]1129
[507]1130 printf(_("---progress-form---4--- %s\r\n"), taskprogress);
[900]1131 mr_free(taskprogress);
[45]1132 } else {
[87]1133 /* BERLIOS: center_string is now broken replace it ! */
1134 //center_string(blurb1, 54);
1135 /* BERLIOS: center_string is now broken replace it ! */
1136 //center_string(blurb2, 54);
1137 /* BERLIOS: center_string is now broken replace it ! */
1138 //center_string(blurb3, 54);
[45]1139 newtLabelSetText(g_blurb1, blurb1);
1140 newtLabelSetText(g_blurb2, blurb3);
1141 newtLabelSetText(g_blurb3, blurb2);
1142 newtScaleSet(g_scale, (unsigned long long) g_current_progress);
1143 if (percentage >= 2) {
1144 newtLabelSetText(g_timeline, timeline_str);
1145 }
1146 newtLabelSetText(g_percentline, percentline_str);
1147 newtRefresh();
1148 }
[900]1149 mr_free(percentline_str);
1150 mr_free(timeline_str);
[1]1151 }
1152
1153
1154/**
1155 * Ask the user which backup media type they would like to use.
1156 * The choices are @p none (exit to shell), @c cdr, @c cdrw, @c dvd,
1157 * @c tape, @c cdstream, @c udev (only when @p g_text_mode is TRUE), @c nfs,
1158 * and @c iso.
1159 * @param restoring TRUE if we're restoring, FALSE if we're backing up.
1160 * @return The backup type chosen, or @c none if the user chose "Exit to shell".
1161 */
[45]1162 t_bkptype which_backup_media_type(bool restoring) {
[1]1163
[45]1164 /*@ char ************************************************************ */
1165 t_bkptype output;
[1]1166
1167
[45]1168 /*@ newt ************************************************************ */
1169 char *title_sz;
1170 char *minimsg_sz;
1171 static t_bkptype possible_bkptypes[] =
1172 { none, cdr, cdrw, dvd, tape, cdstream, udev, nfs, iso };
1173 static char *possible_responses[] =
1174 { "none", "cdr", "cdrw", "dvd", "tape", "cdstream", "udev",
[59]1175 "nfs", "iso", NULL
1176 };
[87]1177 char *outstr = NULL;
[45]1178 t_bkptype backup_type;
1179 int i;
[87]1180 size_t n = 0;
[1]1181
[45]1182 newtComponent b1;
1183 newtComponent b2;
1184 newtComponent b3;
1185 newtComponent b4;
1186 newtComponent b5;
1187 newtComponent b6;
1188 newtComponent b7;
1189 newtComponent b8;
1190 newtComponent b_res;
1191 newtComponent myForm;
[1]1192
[45]1193 if (g_text_mode) {
1194 for (backup_type = none; backup_type == none;) {
[507]1195 printf(_("Backup type ("));
[45]1196 for (i = 0; possible_responses[i]; i++) {
1197 printf("%c%s", (i == 0) ? '\0' : ' ',
1198 possible_responses[i]);
1199 }
1200 printf(")\n--> ");
[900]1201 mr_getline(&outstr, &n, stdin);
[45]1202 strip_spaces(outstr);
1203 for (i = 0; possible_responses[i]; i++) {
1204 if (!strcmp(possible_responses[i], outstr)) {
1205 backup_type = possible_bkptypes[i];
1206 }
1207 }
1208 }
[900]1209 mr_free(outstr);
[45]1210 return (backup_type);
1211 }
1212 newtDrawRootText(18, 0, WELCOME_STRING);
1213 if (restoring) {
[900]1214 mr_asprintf(&title_sz,
[507]1215 _("Please choose the backup media from which you want to read data."));
[900]1216 mr_asprintf(&minimsg_sz, _("Read from:"));
[45]1217 } else {
[900]1218 mr_asprintf(&title_sz,
[507]1219 _("Please choose the backup media to which you want to archive data."));
[900]1220 mr_asprintf(&minimsg_sz, _("Backup to:"));
[45]1221 }
1222 newtPushHelpLine(title_sz);
[900]1223 mr_free(title_sz);
[87]1224
[45]1225 // newtOpenWindow (23, 3, 34, 17, minimsg_sz);
1226 newtCenteredWindow(34, 17, minimsg_sz);
[900]1227 mr_free(minimsg_sz);
[87]1228
[507]1229 b1 = newtButton(1, 1, _("CD-R disks "));
1230 b2 = newtButton(17, 1, _("CD-RW disks"));
1231 b3 = newtButton(1, 9, _("Tape drive "));
1232 b4 = newtButton(17, 5, _("CD streamer"));
1233 b5 = newtButton(1, 5, _(" DVD disks "));
1234 b6 = newtButton(17, 9, _(" NFS mount "));
1235 b7 = newtButton(1, 13, _(" Hard disk "));
1236 b8 = newtButton(17, 13, _(" Exit "));
[45]1237 myForm = newtForm(NULL, NULL, 0);
1238 newtFormAddComponents(myForm, b1, b5, b3, b7, b2, b4, b6, b8,
1239 NULL);
1240 b_res = newtRunForm(myForm);
1241 newtFormDestroy(myForm);
1242 newtPopWindow();
1243 if (b_res == b1) {
1244 output = cdr;
1245 } else if (b_res == b2) {
1246 output = cdrw;
1247 } else if (b_res == b3) {
1248 output = tape;
1249 } else if (b_res == b4) {
1250 output = cdstream;
1251 } else if (b_res == b5) {
1252 output = dvd;
1253 } else if (b_res == b6) {
1254 output = nfs;
1255 } else if (b_res == b7) {
1256 output = iso;
1257 } else {
1258 output = none;
1259 }
1260 newtPopHelpLine();
1261 return (output);
1262 }
[1]1263
1264
1265/**
1266 * Ask the user how much compression they would like to use.
1267 * The choices are "None" (0), "Minimum" (1), "Average" (4), and "Maximum" (9).
1268 * @return The compression level (0-9) chosen, or -1 for "Exit".
1269 */
[45]1270 int
1271 which_compression_level() {
[1]1272
[45]1273 /*@ char ************************************************************ */
1274 int output = none;
[1]1275
1276
[45]1277 /*@ newt ************************************************************ */
[1]1278
[45]1279 newtComponent b1;
1280 newtComponent b2;
1281 newtComponent b3;
1282 newtComponent b4;
1283 newtComponent b5;
1284 newtComponent b_res;
1285 newtComponent myForm;
[1]1286
[45]1287 newtDrawRootText(18, 0, WELCOME_STRING);
1288 newtPushHelpLine
[507]1289 (_(" Please specify the level of compression that you want."));
[45]1290 // newtOpenWindow (23, 3, 34, 13, "How much compression?");
[507]1291 newtCenteredWindow(34, 13, _("How much compression?"));
1292 b1 = newtButton(4, 1, _("Maximum"));
1293 b2 = newtButton(18, 1, _("Average"));
1294 b3 = newtButton(4, 5, _("Minimum"));
1295 b4 = newtButton(18, 5, _(" None "));
1296 b5 = newtButton(4, 9, _(" Exit "));
[45]1297 myForm = newtForm(NULL, NULL, 0);
1298 newtFormAddComponents(myForm, b1, b3, b2, b4, b5, NULL);
1299 b_res = newtRunForm(myForm);
1300 newtFormDestroy(myForm);
1301 newtPopWindow();
1302 if (b_res == b1) {
1303 output = 9;
1304 } else if (b_res == b2) {
1305 output = 4;
1306 } else if (b_res == b3) {
1307 output = 1;
1308 } else if (b_res == b4) {
1309 output = 0;
1310 } else if (b_res == b5) {
1311 output = -1;
1312 }
1313 newtPopHelpLine();
1314 return (output);
1315 }
[1]1316
1317
1318/**
1319 * Load @p source_file (a list of files) into @p filelist. There can be no more than
1320 * @p ARBITRARY_MAXIMUM entries.
1321 * @param filelist The filelist structure to load @p source_file into.
1322 * @param source_file The file containing a list of filenames to load into @p filelist.
1323 */
[45]1324 int load_filelist_into_array(struct s_filelist *filelist,
1325 char *source_file) {
1326 int i;
1327 bool done;
[87]1328 char *reason = NULL;
1329 char *tmp = NULL;
1330 size_t n = 0;
[45]1331 FILE *fin;
1332 struct s_filelist_entry dummy_fle;
[1]1333
[45]1334 assert(filelist != NULL);
1335 assert_string_is_neither_NULL_nor_zerolength(source_file);
[1]1336
[45]1337 iamhere("entering");
1338 if (!(fin = fopen(source_file, "r"))) {
1339 log_OS_error(source_file);
1340 log_msg(2, "Can't open %s; therefore, cannot popup list",
1341 source_file);
1342 return (1);
1343 }
1344 log_msg(2, "Loading %s", source_file);
1345 for (filelist->entries = 0; filelist->entries <= ARBITRARY_MAXIMUM;
1346 filelist->entries++) {
1347 if (feof(fin)) {
1348 break;
1349 }
[900]1350 mr_getline(&tmp, &n, fin);
[45]1351 i = (int) strlen(tmp);
1352 if (i < 2) {
[121]1353 if (feof(fin)) {
1354 break;
1355 }
[45]1356 }
1357 if (tmp[i - 1] < 32) {
1358 tmp[--i] = '\0';
1359 }
1360 if (i < 2) {
[121]1361 if (feof(fin)) {
1362 break;
1363 }
[45]1364 }
1365 if (!does_file_exist(tmp)) {
[121]1366 if (feof(fin)) {
1367 break;
1368 }
[45]1369 }
1370 filelist->el[filelist->entries].severity =
[87]1371 severity_of_difference(tmp, reason);
[900]1372 mr_free(reason);
[45]1373 strcpy(filelist->el[filelist->entries].filename, tmp);
1374 if (feof(fin)) {
1375 break;
1376 }
1377 }
1378 paranoid_fclose(fin);
1379 if (filelist->entries >= ARBITRARY_MAXIMUM) {
[507]1380 log_to_screen(_("Arbitrary limits suck, man!"));
[900]1381 mr_free(tmp);
[45]1382 return (1);
1383 }
[900]1384 mr_free(tmp);
[87]1385
[45]1386 for (done = FALSE; !done;) {
1387 done = TRUE;
1388 for (i = 0; i < filelist->entries - 1; i++) {
[1]1389// if (strcmp(filelist->el[i].filename, filelist->el[i+1].filename) > 0)
[45]1390 if (filelist->el[i].severity < filelist->el[i + 1].severity
1391 || (filelist->el[i].severity ==
1392 filelist->el[i + 1].severity
1393 && strcmp(filelist->el[i].filename,
1394 filelist->el[i + 1].filename) > 0)) {
1395 memcpy((void *) &dummy_fle,
1396 (void *) &(filelist->el[i]),
1397 sizeof(struct s_filelist_entry));
1398 memcpy((void *) &(filelist->el[i]),
1399 (void *) &(filelist->el[i + 1]),
1400 sizeof(struct s_filelist_entry));
1401 memcpy((void *) &(filelist->el[i + 1]),
1402 (void *) &dummy_fle,
1403 sizeof(struct s_filelist_entry));
1404 log_msg(2, "Swapping %s and %s",
1405 filelist->el[i].filename,
1406 filelist->el[i + 1].filename);
1407 done = FALSE;
1408 }
1409 }
1410 }
1411 iamhere("leaving");
1412 return (0);
1413 }
[1]1414
1415
1416
1417/**
1418 * Generate a pretty string based on @p flentry.
1419 * @param flentry The filelist entry to stringify.
1420 * @return The string form of @p flentry.
1421 * @note The returned value points to static storage that will be overwritten with each call.
1422 */
[45]1423 char *filelist_entry_to_string(struct s_filelist_entry *flentry) {
[87]1424 char *comment;
[1]1425
[45]1426 iamhere("entering");
1427 assert(flentry != NULL);
1428 if (flentry->severity == 0) {
[900]1429 mr_asprintf(&comment, "0 %93s", flentry->filename);
[45]1430 } else if (flentry->severity == 1) {
[900]1431 mr_asprintf(&comment, "low %93s", flentry->filename);
[45]1432 } else if (flentry->severity == 2) {
[900]1433 mr_asprintf(&comment, "med %93s", flentry->filename);
[45]1434 } else {
[900]1435 mr_asprintf(&comment, "high %93s", flentry->filename);
[45]1436 }
1437 iamhere("leaving");
1438 return (comment);
1439 }
[1]1440
1441
1442
1443
1444
1445/**
1446 * Pop up a list containing the filenames in @p source_file and the severity if they have changed since the
1447 * last backup. There can be no more than @p ARBITRARY_MAXIMUM files in @p source_file.
1448 * @param source_file The file containing a list of changed files.
1449 */
[45]1450 void popup_changelist_from_file(char *source_file) {
[87]1451 char *reason = NULL;
[45]1452 newtComponent myForm;
1453 newtComponent bClose;
1454 newtComponent bSelect;
1455 newtComponent b_res;
1456 newtComponent fileListbox;
1457 newtComponent headerMsg;
[1]1458
[45]1459 /*@ ???? ************************************************************ */
1460 void *curr_choice;
1461 void *keylist[ARBITRARY_MAXIMUM];
[1]1462
[45]1463 /*@ int ************************************************************* */
1464 int currline = 0;
1465 int finished = FALSE;
[764]1466
1467 /*@ long ************************************************************ */
1468 long i = 0;
[45]1469 long lng = 0;
[1]1470
[45]1471 /*@ buffers ********************************************************* */
1472 char *tmp;
1473 char *differ_sz;
[1]1474
[45]1475 struct s_filelist *filelist;
1476 assert_string_is_neither_NULL_nor_zerolength(source_file);
1477 if (g_text_mode) {
1478 log_msg(2, "Text mode. Therefore, no popup list.");
[87]1479 return;
[45]1480 }
1481 log_msg(2, "Examining file %s", source_file);
[1]1482
[45]1483 lng = count_lines_in_file(source_file);
1484 if (lng < 1) {
1485 log_msg(2, "No lines in file. Therefore, no popup list.");
[87]1486 return;
[45]1487 } else if (lng >= ARBITRARY_MAXIMUM) {
1488 log_msg(2, "Too many files differ for me to list.");
[87]1489 return;
[45]1490 }
[1]1491
[45]1492 filelist = (struct s_filelist *) malloc(sizeof(struct s_filelist));
1493 fileListbox =
1494 newtListbox(2, 2, 12, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
1495 newtListboxClear(fileListbox);
[1]1496
[45]1497 if (load_filelist_into_array(filelist, source_file)) {
1498 log_msg(2, "Can't open %s; therefore, cannot popup list",
1499 source_file);
1500 return;
1501 }
1502 log_msg(2, "%d files loaded into filelist array",
1503 filelist->entries);
1504 for (i = 0; i < filelist->entries; i++) {
1505 keylist[i] = (void *) i;
1506 newtListboxAppendEntry(fileListbox,
1507 filelist_entry_to_string(&
1508 (filelist->
1509 el[i])),
1510 keylist[i]);
1511 }
[900]1512 mr_asprintf(&differ_sz,
[764]1513 _(" %ld files differ. Hit 'Select' to pick a file. Hit 'Close' to quit the list."),
[89]1514 i);
[45]1515 newtPushHelpLine(differ_sz);
[900]1516 mr_free(differ_sz);
[87]1517
[507]1518 bClose = newtCompactButton(10, 15, _(" Close "));
1519 bSelect = newtCompactButton(30, 15, _(" Select "));
[900]1520 mr_asprintf(&tmp, "%-10s %-20s", _("Priority"),
[507]1521 _("Filename"));
[45]1522 headerMsg = newtLabel(2, 1, tmp);
[900]1523 mr_free(tmp);
[87]1524
[507]1525 newtOpenWindow(5, 4, 70, 16, _("Non-matching files"));
[45]1526 myForm = newtForm(NULL, NULL, 0);
1527 newtFormAddComponents(myForm, headerMsg, fileListbox, bClose,
1528 bSelect, NULL);
1529 while (!finished) {
1530 b_res = newtRunForm(myForm);
1531 if (b_res == bClose) {
1532 finished = TRUE;
1533 } else {
1534 curr_choice = newtListboxGetCurrent(fileListbox);
1535 for (i = 0;
1536 i < filelist->entries && keylist[i] != curr_choice;
1537 i++);
1538 if (i == filelist->entries && filelist->entries > 0) {
[507]1539 log_to_screen(_("I don't know what that button does!"));
[45]1540 } else {
1541 currline = i;
1542 if (filelist->entries > 0) {
1543 severity_of_difference(filelist->el[currline].
1544 filename, reason);
[900]1545 mr_asprintf(&tmp, "%s --- %s",
[89]1546 filelist->el[currline].filename, reason);
[45]1547 popup_and_OK(tmp);
[900]1548 mr_free(tmp);
1549 mr_free(reason);
[45]1550 }
1551 }
1552 }
1553 }
1554 newtFormDestroy(myForm);
1555 newtPopWindow();
1556 newtPopHelpLine();
[1]1557 }
1558
1559/* @} - end of guiGroup */
1560
1561
[45]1562void wait_until_software_raids_are_prepped(char *mdstat_file,
1563 int wait_for_percentage);
Note: See TracBrowser for help on using the repository browser.