source: MondoRescue/branches/stable/mondo/mondo/common/libmondo-fork.c@ 541

Last change on this file since 541 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: 22.3 KB
Line 
1/* libmondo-fork.c
2 $Id: libmondo-fork.c 541 2006-05-13 18:47:23Z bcornec $
3
4- subroutines for handling forking/pthreads/etc.
5
6
701/20/2006
8- replaced partimagehack with ntfsclone
9
1006/20/2004
11- create fifo /var/log/partimagehack-debug.log and empty it
12 to keep ramdisk from filling up
13
1404/13/2004
15- >= should be <= g_loglevel
16
1711/15/2003
18- changed a few []s to char*s
19
2010/12
21- rewrote partimagehack handling (multiple fifos, chunks, etc.)
22
2310/11
24- partimagehack now has debug level of N (set in my-stuff.h)
25
2610/08
27- call to partimagehack when restoring will now log errors to /var/log/....log
28
2910/06
30- cleaned up logging a bit
31
3209/30
33- line 735 - missing char* cmd in sprintf()
34
3509/28
36- added run_external_binary_with_percentage_indicator()
37- rewritten eval_call_to_make_ISO()
38
3909/18
40- call mkstemp instead of mktemp
41
4209/13
43- major NTFS hackage
44
4509/12
46- paranoid_system("rm -f /tmp/ *PARTIMAGE*") before calling partimagehack
47
4809/11
49- forward-ported unbroken feed_*_partimage() subroutines
50 from early August 2003
51
5209/08
53- detect & use partimagehack if it exists
54
5509/05
56- finally finished partimagehack hack :)
57
5807/04
59- added subroutines to wrap around partimagehack
60
6104/27
62- don't echo (...res=%d...) at end of log_it()
63 unnecessarily
64- replace newtFinished() and newtInit() with
65 newtSuspend() and newtResume()
66
6704/24
68- added some assert()'s and log_OS_error()'s
69
7004/09
71- cleaned up run_program_and_log_output()
72
7304/07
74- cleaned up code a bit
75- let run_program_and_log_output() accept -1 (only log if _no error_)
76
7701/02/2003
78- in eval_call_to_make_ISO(), append output to MONDO_LOGFILE
79 instead of a temporary stderr text file
80
8112/10
82- patch by Heiko Schlittermann to handle % chars in issue.net
83
8411/18
85- if mkisofs in eval_call_to_make_ISO() returns an error then return it,
86 whether ISO was created or not
87
8810/30
89- if mkisofs in eval_call_to_make_ISO() returns an error then find out if
90 the output (ISO) file has been created; if it has then return 0 anyway
91
9208/01 - 09/30
93- run_program_and_log_output() now takes boolean operator to specify
94 whether it will log its activities in the event of _success_
95- system() now includes 2>/dev/null
96- enlarged some tmp[]'s
97- added run_program_and_log_to_screen() and run_program_and_log_output()
98
9907/24
100- created
101*/
102
103
104#include "my-stuff.h"
105#include "mondostructures.h"
106#include "libmondo-fork.h"
107#include "libmondo-string-EXT.h"
108#include "libmondo-gui-EXT.h"
109#include "libmondo-files-EXT.h"
110#include "libmondo-tools-EXT.h"
111#include "lib-common-externs.h"
112
113/*@unused@*/
114//static char cvsid[] = "$Id: libmondo-fork.c 541 2006-05-13 18:47:23Z bcornec $";
115
116extern char *g_tmpfs_mountpt;
117extern t_bkptype g_backup_media_type;
118extern bool g_text_mode;
119pid_t g_buffer_pid = 0;
120
121
122/**
123 * Call a program and retrieve its last line of output.
124 * @param call The program to run.
125 * @return The last line of its output.
126 * @note The returned value points to static storage that will be overwritten with each call.
127 */
128char *call_program_and_get_last_line_of_output(char *call)
129{
130 /*@ buffers ***************************************************** */
131 static char result[512];
132 char *tmp;
133
134 /*@ pointers **************************************************** */
135 FILE *fin;
136
137 /*@ initialize data ********************************************* */
138 malloc_string(tmp);
139 result[0] = '\0';
140 tmp[0] = '\0';
141
142 /*@******************************************************************** */
143
144 assert_string_is_neither_NULL_nor_zerolength(call);
145 if ((fin = popen(call, "r"))) {
146 for (fgets(tmp, MAX_STR_LEN, fin); !feof(fin);
147 fgets(tmp, MAX_STR_LEN, fin)) {
148 if (strlen(tmp) > 1) {
149 strcpy(result, tmp);
150 }
151 }
152 paranoid_pclose(fin);
153 } else {
154 log_OS_error("Unable to popen call");
155 }
156 strip_spaces(result);
157 return (result);
158}
159
160
161
162
163
164
165#define MONDO_POPMSG "Your PC will not retract the CD tray automatically. Please call mondoarchive with the -m (manual CD tray) flag."
166
167/**
168 * Call mkisofs to create an ISO image.
169 * @param bkpinfo The backup information structure. Fields used:
170 * - @c bkpinfo->manual_cd_tray
171 * - @c bkpinfo->backup_media_type
172 * - @c bkpinfo->please_dont_eject_when_restoring
173 * @param basic_call The call to mkisofs. May contain tokens that will be resolved to actual data. The tokens are:
174 * - @c _ISO_ will become the ISO file (@p isofile)
175 * - @c _CD#_ becomes the CD number (@p cd_no)
176 * - @c _ERR_ becomes the logfile (@p g_logfile)
177 * @param isofile Replaces @c _ISO_ in @p basic_call. Should probably be the ISO image to create (-o parameter to mkisofs).
178 * @param cd_no Replaces @c _CD#_ in @p basic_call. Should probably be the CD number.
179 * @param logstub Unused.
180 * @param what_i_am_doing The action taking place (e.g. "Making ISO #1"). Used as the title of the progress dialog.
181 * @return Exit code of @c mkisofs (0 is success, anything else indicates failure).
182 * @bug @p logstub is unused.
183 */
184int
185eval_call_to_make_ISO(struct s_bkpinfo *bkpinfo,
186 char *basic_call, char *isofile,
187 int cd_no, char *logstub, char *what_i_am_doing)
188{
189
190 /*@ int's *** */
191 int retval = 0;
192
193
194 /*@ buffers *** */
195 char *midway_call, *ultimate_call, *tmp, *command, *incoming,
196 *old_stderr, *cd_number_str;
197 char *p;
198
199/*@*********** End Variables ***************************************/
200
201 log_msg(3, "Starting");
202 assert(bkpinfo != NULL);
203 assert_string_is_neither_NULL_nor_zerolength(basic_call);
204 assert_string_is_neither_NULL_nor_zerolength(isofile);
205 assert_string_is_neither_NULL_nor_zerolength(logstub);
206 if (!(midway_call = malloc(1200))) {
207 fatal_error("Cannot malloc midway_call");
208 }
209 if (!(ultimate_call = malloc(1200))) {
210 fatal_error("Cannot malloc ultimate_call");
211 }
212 if (!(tmp = malloc(1200))) {
213 fatal_error("Cannot malloc tmp");
214 }
215 if (!(command = malloc(1200))) {
216 fatal_error("Cannot malloc command");
217 }
218 malloc_string(incoming);
219 malloc_string(old_stderr);
220 malloc_string(cd_number_str);
221
222 incoming[0] = '\0';
223 old_stderr[0] = '\0';
224
225 sprintf(cd_number_str, "%d", cd_no);
226 resolve_naff_tokens(midway_call, basic_call, isofile, "_ISO_");
227 resolve_naff_tokens(tmp, midway_call, cd_number_str, "_CD#_");
228 resolve_naff_tokens(ultimate_call, tmp, MONDO_LOGFILE, "_ERR_");
229 log_msg(4, "basic call = '%s'", basic_call);
230 log_msg(4, "midway_call = '%s'", midway_call);
231 log_msg(4, "tmp = '%s'", tmp);
232 log_msg(4, "ultimate call = '%s'", ultimate_call);
233 sprintf(command, "%s >> %s", ultimate_call, MONDO_LOGFILE);
234
235 log_to_screen
236 ("Please be patient. Do not be alarmed by on-screen inactivity.");
237 log_msg(4, "Calling open_evalcall_form() with what_i_am_doing='%s'",
238 what_i_am_doing);
239 strcpy(tmp, command);
240 if (bkpinfo->manual_cd_tray) {
241 p = strstr(tmp, "2>>");
242 if (p) {
243 sprintf(p, " ");
244 while (*p == ' ') {
245 p++;
246 }
247 for (; *p != ' '; p++) {
248 *p = ' ';
249 }
250 }
251 strcpy(command, tmp);
252#ifndef _XWIN
253 if (!g_text_mode) {
254 newtSuspend();
255 }
256#endif
257 log_msg(1, "command = '%s'", command);
258 retval += system(command);
259 if (!g_text_mode) {
260 newtResume();
261 }
262 if (retval) {
263 log_msg(2, "Basic call '%s' returned an error.", basic_call);
264 popup_and_OK("Press ENTER to continue.");
265 popup_and_OK
266 ("mkisofs and/or cdrecord returned an error. CD was not created");
267 }
268 }
269 /* if text mode then do the above & RETURN; if not text mode, do this... */
270 else {
271 log_msg(3, "command = '%s'", command);
272// yes_this_is_a_goto:
273 retval =
274 run_external_binary_with_percentage_indicator_NEW
275 (what_i_am_doing, command);
276 }
277
278 paranoid_free(midway_call);
279 paranoid_free(ultimate_call);
280 paranoid_free(tmp);
281 paranoid_free(command);
282 paranoid_free(incoming);
283 paranoid_free(old_stderr);
284 paranoid_free(cd_number_str);
285/*
286 if (bkpinfo->backup_media_type == dvd && !bkpinfo->please_dont_eject_when_restoring)
287 {
288 log_msg(3, "Ejecting DVD device");
289 eject_device(bkpinfo->media_device);
290 }
291*/
292 return (retval);
293}
294
295
296
297
298/**
299 * Run a program and log its output (stdout and stderr) to the logfile.
300 * @param program The program to run. Passed to the shell, so you can use pipes etc.
301 * @param debug_level If @p g_loglevel is higher than this, do not log the output.
302 * @return The exit code of @p program (depends on the command, but 0 almost always indicates success).
303 */
304int run_program_and_log_output(char *program, int debug_level)
305{
306 /*@ buffer ****************************************************** */
307 char callstr[MAX_STR_LEN * 2];
308 char incoming[MAX_STR_LEN * 2];
309 char tmp[MAX_STR_LEN * 2];
310 char initial_label[MAX_STR_LEN * 2];
311
312 /*@ int ********************************************************* */
313 int res;
314 int i;
315 int len;
316 bool log_if_failure = FALSE;
317 bool log_if_success = FALSE;
318
319 /*@ pointers *************************************************** */
320 FILE *fin;
321 char *p;
322
323 /*@ end vars *************************************************** */
324
325 assert(program != NULL);
326 if (!program[0]) {
327 log_msg(2, "Warning - asked to run zerolength program");
328 return (1);
329 }
330// if (debug_level == TRUE) { debug_level=5; }
331
332 // assert_string_is_neither_NULL_nor_zerolength(program);
333
334 if (debug_level <= g_loglevel) {
335 log_if_success = TRUE;
336 log_if_failure = TRUE;
337 }
338 sprintf(callstr,
339 "%s > /tmp/mondo-run-prog-thing.tmp 2> /tmp/mondo-run-prog-thing.err",
340 program);
341 while ((p = strchr(callstr, '\r'))) {
342 *p = ' ';
343 }
344 while ((p = strchr(callstr, '\n'))) {
345 *p = ' ';
346 } /* single '=' is intentional */
347
348
349 len = (int) strlen(program);
350 for (i = 0; i < 35 - len / 2; i++) {
351 tmp[i] = '-';
352 }
353 tmp[i] = '\0';
354 strcat(tmp, " ");
355 strcat(tmp, program);
356 strcat(tmp, " ");
357 for (i = 0; i < 35 - len / 2; i++) {
358 strcat(tmp, "-");
359 }
360 strcpy(initial_label, tmp);
361 res = system(callstr);
362 if (((res == 0) && log_if_success) || ((res != 0) && log_if_failure)) {
363 log_msg(0, "running: %s", callstr);
364 log_msg(0,
365 "--------------------------------start of output-----------------------------");
366 }
367 if (log_if_failure
368 &&
369 system
370 ("cat /tmp/mondo-run-prog-thing.err >> /tmp/mondo-run-prog-thing.tmp 2> /dev/null"))
371 {
372 log_OS_error("Command failed");
373 }
374 unlink("/tmp/mondo-run-prog-thing.err");
375 fin = fopen("/tmp/mondo-run-prog-thing.tmp", "r");
376 if (fin) {
377 for (fgets(incoming, MAX_STR_LEN, fin); !feof(fin);
378 fgets(incoming, MAX_STR_LEN, fin)) {
379 /* patch by Heiko Schlittermann */
380 p = incoming;
381 while (p && *p) {
382 if ((p = strchr(p, '%'))) {
383 memmove(p, p + 1, strlen(p) + 1);
384 p += 2;
385 }
386 }
387 /* end of patch */
388 strip_spaces(incoming);
389 if ((res == 0 && log_if_success)
390 || (res != 0 && log_if_failure)) {
391 log_msg(0, incoming);
392 }
393 }
394 paranoid_fclose(fin);
395 }
396 unlink("/tmp/mondo-run-prog-thing.tmp");
397 if ((res == 0 && log_if_success) || (res != 0 && log_if_failure)) {
398 log_msg(0,
399 "--------------------------------end of output------------------------------");
400 if (res) {
401 log_msg(0, "...ran with res=%d", res);
402 } else {
403 log_msg(0, "...ran just fine. :-)");
404 }
405 }
406// else
407// { log_msg (0, "-------------------------------ran w/ res=%d------------------------------", res); }
408 return (res);
409}
410
411
412
413/**
414 * Run a program and log its output to the screen.
415 * @param basic_call The program to run.
416 * @param what_i_am_doing The title of the evalcall form.
417 * @return The return value of the command (varies, but 0 almost always means success).
418 * @see run_program_and_log_output
419 * @see log_to_screen
420 */
421int run_program_and_log_to_screen(char *basic_call, char *what_i_am_doing)
422{
423 /*@ int ******************************************************** */
424 int retval = 0;
425 int res = 0;
426 int i;
427
428 /*@ pointers **************************************************** */
429 FILE *fin;
430
431 /*@ buffers **************************************************** */
432 char tmp[MAX_STR_LEN * 2];
433 char command[MAX_STR_LEN * 2];
434 char lockfile[MAX_STR_LEN];
435
436 /*@ end vars *************************************************** */
437
438 assert_string_is_neither_NULL_nor_zerolength(basic_call);
439
440 sprintf(lockfile, "/tmp/mojo-jojo.blah.XXXXXX");
441 mkstemp(lockfile);
442 sprintf(command,
443 "echo hi > %s ; %s >> %s 2>> %s; res=$?; sleep 1; rm -f %s; exit $res",
444 lockfile, basic_call, MONDO_LOGFILE, MONDO_LOGFILE, lockfile);
445 open_evalcall_form(what_i_am_doing);
446 sprintf(tmp, "Executing %s", basic_call);
447 log_msg(2, tmp);
448 if (!(fin = popen(command, "r"))) {
449 log_OS_error("Unable to popen-in command");
450 sprintf(tmp, "Failed utterly to call '%s'", command);
451 log_to_screen(tmp);
452 return (1);
453 }
454 if (!does_file_exist(lockfile)) {
455 log_to_screen("Waiting for external binary to start");
456 for (i = 0; i < 60 && !does_file_exist(lockfile); sleep(1), i++) {
457 log_msg(3, "Waiting for lockfile %s to exist", lockfile);
458 }
459 }
460#ifdef _XWIN
461 /* This only can update when newline goes into the file,
462 but it's *much* prettier/faster on Qt. */
463 while (does_file_exist(lockfile)) {
464 while (!feof(fin)) {
465 if (!fgets(tmp, 512, fin))
466 break;
467 log_to_screen(tmp);
468 }
469 usleep(500000);
470 }
471#else
472 /* This works on Newt, and it gives quicker updates. */
473 for (; does_file_exist(lockfile); sleep(1)) {
474 log_file_end_to_screen(MONDO_LOGFILE, "");
475 update_evalcall_form(1);
476 }
477#endif
478 /* Evaluate the status returned by pclose to get the exit code of the called program. */
479 errno = 0;
480 res = pclose(fin);
481 /* Log actual pclose errors. */
482 if (errno) log_msg(5, "pclose err: %d", errno);
483 /* Check if we have a valid status. If we do, extract the called program's exit code. */
484 /* If we don't, highlight this fact by returning -1. */
485 if (WIFEXITED(res)) {
486 retval = WEXITSTATUS(res);
487 } else {
488 retval = -1;
489 }
490 close_evalcall_form();
491 unlink(lockfile);
492 return (retval);
493}
494
495
496
497
498/**
499 * Apparently unused. @bug This has a purpose, but what?
500 */
501#define PIMP_START_SZ "STARTSTARTSTART9ff3kff9a82gv34r7fghbkaBBC2T231hc81h42vws8"
502#define PIMP_END_SZ "ENDENDEND0xBBC10xBBC2T231hc81h42vws89ff3kff9a82gv34r7fghbka"
503
504
505
506
507int copy_from_src_to_dest(FILE * f_orig, FILE * f_archived, char direction)
508{
509// if dir=='w' then copy from orig to archived
510// if dir=='r' then copy from archived to orig
511 char *tmp;
512 char *buf;
513 long int bytes_to_be_read, bytes_read_in, bytes_written_out =
514 0, bufcap, subsliceno = 0;
515 int retval = 0;
516 FILE *fin;
517 FILE *fout;
518 FILE *ftmp;
519
520 log_msg(5, "Opening.");
521 malloc_string(tmp);
522 tmp[0] = '\0';
523 bufcap = 256L * 1024L;
524 if (!(buf = malloc(bufcap))) {
525 fatal_error("Failed to malloc() buf");
526 }
527
528 if (direction == 'w') {
529 fin = f_orig;
530 fout = f_archived;
531 sprintf(tmp, "%-64s", PIMP_START_SZ);
532 if (fwrite(tmp, 1, 64, fout) != 64) {
533 fatal_error("Can't write the introductory block");
534 }
535 while (1) {
536 bytes_to_be_read = bytes_read_in = fread(buf, 1, bufcap, fin);
537 if (bytes_read_in == 0) {
538 break;
539 }
540 sprintf(tmp, "%-64ld", bytes_read_in);
541 if (fwrite(tmp, 1, 64, fout) != 64) {
542 fatal_error("Cannot write introductory block");
543 }
544 log_msg(7,
545 "subslice #%ld --- I have read %ld of %ld bytes in from f_orig",
546 subsliceno, bytes_read_in, bytes_to_be_read);
547 bytes_written_out += fwrite(buf, 1, bytes_read_in, fout);
548 sprintf(tmp, "%-64ld", subsliceno);
549 if (fwrite(tmp, 1, 64, fout) != 64) {
550 fatal_error("Cannot write post-thingy block");
551 }
552 log_msg(7, "Subslice #%d written OK", subsliceno);
553 subsliceno++;
554 }
555 sprintf(tmp, "%-64ld", 0L);
556 if (fwrite(tmp, 1, 64L, fout) != 64L) {
557 fatal_error("Cannot write final introductory block");
558 }
559 } else {
560 fin = f_archived;
561 fout = f_orig;
562 if (fread(tmp, 1, 64L, fin) != 64L) {
563 fatal_error("Cannot read the introductory block");
564 }
565 log_msg(5, "tmp is %s", tmp);
566 if (!strstr(tmp, PIMP_START_SZ)) {
567 fatal_error("Can't find intro blk");
568 }
569 if (fread(tmp, 1, 64L, fin) != 64L) {
570 fatal_error("Cannot read introductory blk");
571 }
572 bytes_to_be_read = atol(tmp);
573 while (bytes_to_be_read > 0) {
574 log_msg(7, "subslice#%ld, bytes=%ld", subsliceno,
575 bytes_to_be_read);
576 bytes_read_in = fread(buf, 1, bytes_to_be_read, fin);
577 if (bytes_read_in != bytes_to_be_read) {
578 fatal_error
579 ("Danger, WIll Robinson. Failed to read whole subvol from archives.");
580 }
581 bytes_written_out += fwrite(buf, 1, bytes_read_in, fout);
582 if (fread(tmp, 1, 64, fin) != 64) {
583 fatal_error("Cannot read post-thingy block");
584 }
585 if (atol(tmp) != subsliceno) {
586 log_msg(1, "Wanted subslice %ld but got %ld ('%s')",
587 subsliceno, atol(tmp), tmp);
588 }
589 log_msg(7, "Subslice #%ld read OK", subsliceno);
590 subsliceno++;
591 if (fread(tmp, 1, 64, fin) != 64) {
592 fatal_error("Cannot read introductory block");
593 }
594 bytes_to_be_read = atol(tmp);
595 }
596 }
597
598// log_msg(4, "Written %ld of %ld bytes", bytes_written_out, bytes_read_in);
599
600 if (direction == 'w') {
601 sprintf(tmp, "%-64s", PIMP_END_SZ);
602 if (fwrite(tmp, 1, 64, fout) != 64) {
603 fatal_error("Can't write the final block");
604 }
605 } else {
606 log_msg(1, "tmpA is %s", tmp);
607 if (!strstr(tmp, PIMP_END_SZ)) {
608 if (fread(tmp, 1, 64, fin) != 64) {
609 fatal_error("Can't read the final block");
610 }
611 log_msg(5, "tmpB is %s", tmp);
612 if (!strstr(tmp, PIMP_END_SZ)) {
613 ftmp = fopen("/tmp/out.leftover", "w");
614 bytes_read_in = fread(tmp, 1, 64, fin);
615 log_msg(1, "bytes_read_in = %ld", bytes_read_in);
616// if (bytes_read_in!=128+64) { fatal_error("Can't read the terminating block"); }
617 fwrite(tmp, 1, bytes_read_in, ftmp);
618 sprintf(tmp, "I am here - %ld", ftell(fin));
619// log_msg(0, tmp);
620 fread(tmp, 1, 512, fin);
621 log_msg(0, "tmp = '%s'", tmp);
622 fwrite(tmp, 1, 512, ftmp);
623 fclose(ftmp);
624 fatal_error("Missing terminating block");
625 }
626 }
627 }
628
629 paranoid_free(buf);
630 paranoid_free(tmp);
631 log_msg(3, "Successfully copied %ld bytes", bytes_written_out);
632 return (retval);
633}
634
635
636
637
638/**
639 * Feed @p input_device through ntfsclone to @p output_fname.
640 * @param input_device The device to image.
641 * @param output_fname The file to write.
642 * @return 0 for success, nonzero for failure.
643 */
644int feed_into_ntfsprog(char *input_device, char *output_fname)
645{
646// BACKUP
647 int res = -1;
648 char*command;
649
650 if (!does_file_exist(input_device)) {
651 fatal_error("input device does not exist");
652 }
653 if ( !find_home_of_exe("ntfsclone")) {
654 fatal_error("ntfsclone not found");
655 }
656 malloc_string(command);
657 sprintf(command, "ntfsclone --force --save-image --overwrite %s %s", output_fname, input_device);
658 res = run_program_and_log_output(command, 5);
659 paranoid_free(command);
660 unlink(output_fname);
661 return (res);
662}
663
664
665
666
667
668int run_external_binary_with_percentage_indicator_OLD(char *tt, char *cmd)
669{
670
671 /*@ int *************************************************************** */
672 int res = 0;
673 int percentage = 0;
674 int maxpc = 0;
675 int pcno = 0;
676 int last_pcno = 0;
677
678 /*@ buffers *********************************************************** */
679 char *command;
680 char *tempfile;
681 char *title;
682 /*@ pointers ********************************************************** */
683 FILE *pin;
684
685 malloc_string(title);
686 malloc_string(command);
687 malloc_string(tempfile);
688 assert_string_is_neither_NULL_nor_zerolength(cmd);
689 assert_string_is_neither_NULL_nor_zerolength(title);
690
691 strcpy(title, tt);
692 strcpy(tempfile,
693 call_program_and_get_last_line_of_output
694 ("mktemp -q /tmp/mondo.XXXXXXXX"));
695 sprintf(command, "%s >> %s 2>> %s; rm -f %s", cmd, tempfile, tempfile,
696 tempfile);
697 log_msg(3, command);
698 open_evalcall_form(title);
699 if (!(pin = popen(command, "r"))) {
700 log_OS_error("fmt err");
701 return (1);
702 }
703 maxpc = 100;
704// OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD
705 for (sleep(1); does_file_exist(tempfile); sleep(1)) {
706 pcno = grab_percentage_from_last_line_of_file(MONDO_LOGFILE);
707 if (pcno < 0 || pcno > 100) {
708 log_msg(5, "Weird pc#");
709 continue;
710 }
711 percentage = pcno * 100 / maxpc;
712 if (pcno <= 5 && last_pcno > 40) {
713 close_evalcall_form();
714 strcpy(title, "Verifying...");
715 open_evalcall_form(title);
716 }
717 last_pcno = pcno;
718 update_evalcall_form(percentage);
719 }
720// OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD
721 close_evalcall_form();
722 if (pclose(pin)) {
723 res++;
724 log_OS_error("Unable to pclose");
725 }
726 unlink(tempfile);
727 paranoid_free(command);
728 paranoid_free(tempfile);
729 paranoid_free(title);
730 return (res);
731}
732
733
734
735
736void *run_prog_in_bkgd_then_exit(void *info)
737{
738 char *sz_command;
739 static int res = 4444;
740
741 res = 999;
742 sz_command = (char *) info;
743 log_msg(4, "sz_command = '%s'", sz_command);
744 res = system(sz_command);
745 if (res > 256 && res != 4444) {
746 res = res / 256;
747 }
748 log_msg(4, "child res = %d", res);
749 sz_command[0] = '\0';
750 pthread_exit((void *) (&res));
751}
752
753
754
755
756int run_external_binary_with_percentage_indicator_NEW(char *tt, char *cmd)
757{
758
759 /*@ int *************************************************************** */
760 int res = 0;
761 int percentage = 0;
762 int maxpc = 100;
763 int pcno = 0;
764 int last_pcno = 0;
765 int counter = 0;
766
767 /*@ buffers *********************************************************** */
768 char *command;
769 char *title;
770 /*@ pointers ********************************************************** */
771 static int chldres = 0;
772 int *pchild_result;
773 pthread_t childthread;
774
775 pchild_result = &chldres;
776 assert_string_is_neither_NULL_nor_zerolength(cmd);
777 assert_string_is_neither_NULL_nor_zerolength(tt);
778 *pchild_result = 999;
779
780 malloc_string(title);
781 malloc_string(command);
782 strcpy(title, tt);
783 sprintf(command, "%s 2>> %s", cmd, MONDO_LOGFILE);
784 log_msg(3, "command = '%s'", command);
785 if ((res =
786 pthread_create(&childthread, NULL, run_prog_in_bkgd_then_exit,
787 (void *) command))) {
788 fatal_error("Unable to create an archival thread");
789 }
790
791 log_msg(8, "Parent running");
792 open_evalcall_form(title);
793 for (sleep(1); command[0] != '\0'; sleep(1)) {
794 pcno = grab_percentage_from_last_line_of_file(MONDO_LOGFILE);
795 if (pcno <= 0 || pcno > 100) {
796 log_msg(8, "Weird pc#");
797 continue;
798 }
799 percentage = pcno * 100 / maxpc;
800 if (pcno <= 5 && last_pcno >= 40) {
801 close_evalcall_form();
802 strcpy(title, "Verifying...");
803 open_evalcall_form(title);
804 }
805 if (counter++ >= 5) {
806 counter = 0;
807 log_file_end_to_screen(MONDO_LOGFILE, "");
808 }
809 last_pcno = pcno;
810 update_evalcall_form(percentage);
811 }
812 log_file_end_to_screen(MONDO_LOGFILE, "");
813 close_evalcall_form();
814 pthread_join(childthread, (void *) (&pchild_result));
815 if (pchild_result) {
816 res = *pchild_result;
817 } else {
818 res = 666;
819 }
820 log_msg(3, "Parent res = %d", res);
821 paranoid_free(command);
822 paranoid_free(title);
823 return (res);
824}
825
826
827
828
829/**
830 * Feed @p input_fifo through ntfsclone (restore) to @p output_device.
831 * @param input_fifo The ntfsclone file to read.
832 * @param output_device Where to put the output.
833 * @return The return value of ntfsclone (0 for success).
834 */
835int feed_outfrom_ntfsprog(char *output_device, char *input_fifo)
836{
837// RESTORE
838 int res = -1;
839 char *command;
840
841 if ( !find_home_of_exe("ntfsclone")) {
842 fatal_error("ntfsclone not found");
843 }
844 malloc_string(command);
845 sprintf(command, "ntfsclone --force --restore-image --overwrite %s %s", output_device, input_fifo);
846 res = run_program_and_log_output(command, 5);
847 paranoid_free(command);
848 return (res);
849}
Note: See TracBrowser for help on using the repository browser.