source: MondoRescue/trunk/mondo/mondo/mondorestore/mondo-rstr-compare.c@ 729

Last change on this file since 729 was 689, checked in by bcornec, 18 years ago

Still other memory management improvements ( I hope :-)

  • Property svn:keywords set to Id
File size: 20.3 KB
Line 
1/***************************************************************************
2 * $Id: mondo-rstr-compare.c 689 2006-07-17 17:43:58Z bcornec $ - compares mondoarchive data
3**/
4
5
6#include "../common/my-stuff.h"
7#include "../common/mondostructures.h"
8#include "../common/libmondo.h"
9#include "mr-externs.h"
10#include "mondo-rstr-compare.h"
11#include "mondo-restore-EXT.h"
12#include "mondo-rstr-tools-EXT.h"
13#ifndef S_SPLINT_S
14#include <pthread.h>
15#endif
16
17void popup_changelist_from_file(char *);
18
19
20/**
21 * @addtogroup LLcompareGroup
22 * @{
23 */
24/**
25 * Compare biggiefile number @p bigfileno with the filesystem mounted on @p MNT_RESTORING.
26 * @param bkpinfo The backup information structure. Only used in insist_on_this_cd_number().
27 * @param bigfileno The biggiefile number (starting from 0) to compare.
28 * @note This function uses an MD5 checksum.
29 */
30int compare_a_biggiefile(struct s_bkpinfo *bkpinfo, long bigfileno)
31{
32
33 FILE *fin;
34 FILE *fout;
35
36 /** needs malloc *******/
37 char *checksum = NULL;
38 char *original_cksum = NULL;
39 char *bigfile_fname = NULL;
40 char *tmp = NULL;
41 char *tmp1 = NULL;
42 char *command = NULL;
43
44 char *p = NULL;
45 int i = 0;
46 int n = 0;
47 int retval = 0;
48
49 struct s_filename_and_lstat_info biggiestruct;
50
51 assert(bkpinfo != NULL);
52
53 tmp1 = slice_fname(bigfileno, 0, ARCHIVES_PATH, "");
54 if (!does_file_exist(tmp1)) {
55 if (does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST")) {
56 insist_on_this_cd_number(bkpinfo, (++g_current_media_number));
57 } else {
58 log_msg(2, "No CD's left. No biggiefiles left. No problem.");
59 return (0);
60 }
61 }
62 if (!(fin = fopen(tmp1, "r"))) {
63 asprintf(&tmp, _("Cannot open bigfile %ld (%s)'s info file"),
64 bigfileno + 1, tmp);
65 log_to_screen(tmp);
66 paranoid_free(tmp);
67 paranoid_free(tmp1);
68 return (1);
69 }
70 paranoid_free(tmp1);
71
72 fread((void *) &biggiestruct, 1, sizeof(biggiestruct), fin);
73 paranoid_fclose(fin);
74
75 asprintf(&checksum, biggiestruct.checksum);
76 asprintf(&bigfile_fname, biggiestruct.filename);
77
78 log_msg(2, "biggiestruct.filename = %s", bigfile_fname);
79 log_msg(2, "biggiestruct.checksum = %s", checksum);
80
81 if (!g_text_mode) {
82 asprintf(&tmp, _("Comparing %s"), bigfile_fname);
83 newtDrawRootText(0, 22, tmp);
84 newtRefresh();
85 paranoid_free(tmp);
86 }
87 /* BERLIOS: Useless ?
88 if (!checksum[0]) {
89 log_msg(2, "Warning - %s has no checksum", bigfile_fname_ptr);
90 } */
91 if (!strncmp(bigfile_fname, "/dev/", 5)) {
92 log_msg(2, _("Ignoring device %s"), bigfile_fname);
93 return(0);
94 } else {
95 asprintf(&command,
96 "md5sum \"%s%s\" > /tmp/md5sum.txt 2> /tmp/errors.txt",
97 MNT_RESTORING, bigfile_fname);
98 }
99 log_msg(2, command);
100 paranoid_system("cat /tmp/errors >> /tmp/mondo-restore.log 2> /dev/null");
101 if (system(command)) {
102 log_OS_error("Warning - command failed");
103 paranoid_free(command);
104 paranoid_free(bigfile_fname);
105 return (1);
106 } else {
107 paranoid_free(command);
108 if (!(fin = fopen("/tmp/md5sum.txt", "r"))) {
109 log_msg(2, "Unable to open /tmp/md5sum.txt; can't get live checksum");
110 paranoid_free(bigfile_fname);
111 return (1);
112 } else {
113 getline(&original_cksum, &n, fin);
114 paranoid_fclose(fin);
115 for (i = strlen(original_cksum);
116 i > 0 && original_cksum[i - 1] < 32; i--);
117 original_cksum[i] = '\0';
118 p = (char *) strchr(original_cksum, ' ');
119 if (p) {
120 *p = '\0';
121 }
122 }
123 }
124 if (!strcmp(checksum, original_cksum) != 0) {
125 log_msg(1, "bigfile #%ld ('%s') ... OK", bigfileno + 1, bigfile_fname);
126 } else {
127 log_msg(1, "bigfile #%ld ('%s') ... changed", bigfileno + 1, bigfile_fname);
128 retval++;
129 }
130 paranoid_free(original_cksum);
131 paranoid_free(checksum);
132
133 if (retval) {
134 if (!(fout = fopen("/tmp/changed.txt", "a"))) {
135 fatal_error("Cannot openout changed.txt");
136 }
137 fprintf(fout, "%s\n", bigfile_fname);
138 paranoid_fclose(fout);
139 }
140 paranoid_free(bigfile_fname);
141
142 return (retval);
143}
144
145/**************************************************************************
146 *END_COMPARE_A_BIGGIEFILE *
147 **************************************************************************/
148
149
150/**
151 * Compare all biggiefiles in the backup.
152 * @param bkpinfo The backup information structure. Used only in compare_a_biggiefile().
153 * @return 0 for success, nonzero for failure.
154 */
155int compare_all_biggiefiles(struct s_bkpinfo *bkpinfo)
156{
157 int retval = 0;
158 int res;
159 long noof_biggiefiles, bigfileno = 0;
160 char *tmp;
161
162 assert(bkpinfo != NULL);
163 log_msg(1, "Comparing biggiefiles");
164
165 if (length_of_file(BIGGIELIST) < 6) {
166 log_msg(1,
167 "OK, really teeny-tiny biggielist; not comparing biggiefiles");
168 return (0);
169 }
170 noof_biggiefiles = count_lines_in_file(BIGGIELIST);
171 if (noof_biggiefiles <= 0) {
172 log_msg(1, "OK, no biggiefiles; not comparing biggiefiles");
173 return (0);
174 }
175 mvaddstr_and_log_it(g_currentY, 0,
176 _
177 ("Comparing large files "));
178 open_progress_form(_("Comparing large files"),
179 _("I am now comparing the large files"),
180 _("against the filesystem. Please wait."), "",
181 noof_biggiefiles);
182 for (bigfileno = 0; bigfileno < noof_biggiefiles; bigfileno++) {
183 asprintf(&tmp, "Comparing big file #%ld", bigfileno + 1);
184 log_msg(1, tmp);
185 update_progress_form(tmp);
186 paranoid_free(tmp);
187 res = compare_a_biggiefile(bkpinfo, bigfileno);
188 retval += res;
189 g_current_progress++;
190 }
191 close_progress_form();
192 /* BERLIOS: useless ?
193 return (0);
194 */
195 if (retval) {
196 mvaddstr_and_log_it(g_currentY++, 74, _("Errors."));
197 } else {
198 mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
199 }
200 return (retval);
201}
202
203/**************************************************************************
204 *END_COMPARE_ALL_BIGGIEFILES *
205 **************************************************************************/
206
207
208/**
209 * Compare afioball @p tarball_fname against the filesystem.
210 * You must be chdir()ed to the directory where the filesystem is mounted
211 * before you call this function.
212 * @param tarball_fname The filename of the tarball to compare.
213 * @param current_tarball_number The fileset number contained in @p tarball_fname.
214 * @return 0 for success, nonzero for failure.
215 */
216int compare_a_tarball(char *tarball_fname, int current_tarball_number)
217{
218 int retval = 0;
219 int res;
220 long noof_lines;
221 long archiver_errors;
222 bool use_star;
223
224 /*** needs malloc *********/
225 char *command = NULL;
226 char *tmp = NULL;
227 char *filelist_name = NULL;
228 char *logfile = NULL;
229 char *archiver_exe = NULL;
230 char *compressor_exe = NULL;
231
232 use_star = (strstr(tarball_fname, ".star")) ? TRUE : FALSE;
233 assert_string_is_neither_NULL_nor_zerolength(tarball_fname);
234 asprintf(&filelist_name, MNT_CDROM "/archives/filelist.%d",
235 current_tarball_number);
236
237 noof_lines = count_lines_in_file(filelist_name);
238 paranoid_free(filelist_name);
239
240 if (strstr(tarball_fname, ".bz2")) {
241 asprintf(&compressor_exe, "bzip2");
242 } else if (strstr(tarball_fname, ".lzo")) {
243 asprintf(&compressor_exe, "lzop");
244 } else {
245 compressor_exe = NULL;
246 }
247
248 if (use_star) {
249 asprintf(&archiver_exe, "star -bz");
250 } else {
251 asprintf(&archiver_exe, "afio");
252 }
253
254 if (compressor_exe != NULL) {
255 tmp = find_home_of_exe(compressor_exe);
256 if (!tmp) {
257 fatal_error("(compare_a_tarball) Compression program missing");
258 }
259 paranoid_free(tmp);
260 if (use_star) {
261 if (strcmp(compressor_exe, "bzip2")) {
262 fatal_error
263 ("(compare_a_tarball) Please use only bzip2 with star");
264 }
265 } else {
266 asprintf(&tmp, compressor_exe);
267 sprintf(compressor_exe, "-P %s -Z", tmp);
268 paranoid_free(tmp);
269 }
270 }
271// star -diff H=star -bz file=....
272
273#ifdef __FreeBSD__
274#define BUFSIZE 512L
275#else
276#define BUFSIZE (1024L*1024L)/TAPE_BLOCK_SIZE
277#endif
278
279 asprintf(&logfile, "/tmp/afio.log.%d", current_tarball_number);
280 if (use_star) // doesn't use compressor_exe
281 {
282 asprintf(&command,
283 "%s -diff H=star file=%s >> %s 2>> %s",
284 archiver_exe, tarball_fname, logfile, logfile);
285 } else {
286 asprintf(&command,
287 "%s -r -b %ld -M 16m -c %ld %s %s >> %s 2>> %s",
288 archiver_exe,
289 TAPE_BLOCK_SIZE,
290 BUFSIZE, compressor_exe, tarball_fname, logfile, logfile);
291 }
292#undef BUFSIZE
293 paranoid_free(archiver_exe);
294 paranoid_free(compressor_exe);
295
296 res = system(command);
297 retval += res;
298 if (res) {
299 log_OS_error(command);
300 }
301 if (length_of_file(logfile) > 5) {
302 sprintf(command,
303 "sed s/': \\\"'/\\|/ %s | sed s/'\\\": '/\\|/ | cut -d'|' -f2 | sort -u | grep -vx \"dev/.*\" >> /tmp/changed.txt",
304 logfile);
305 system(command);
306 archiver_errors = count_lines_in_file(logfile);
307 } else {
308 archiver_errors = 0;
309 }
310 paranoid_free(command);
311
312 if (archiver_errors) {
313 asprintf(&tmp,
314 "Differences found while processing fileset #%d ",
315 current_tarball_number);
316 log_msg(1, tmp);
317 paranoid_free(tmp);
318 }
319 unlink(logfile);
320 paranoid_free(logfile);
321 return (retval);
322}
323
324/**************************************************************************
325 *END_COMPARE_A_TARBALL *
326 **************************************************************************/
327
328
329/**
330 * Compare all afioballs in this backup.
331 * @param bkpinfo The backup media structure. Passed to other functions.
332 * @return 0 for success, nonzero for failure.
333 */
334int compare_all_tarballs(struct s_bkpinfo *bkpinfo)
335{
336 int retval = 0;
337 int res;
338 int current_tarball_number = 0;
339
340 /** needs malloc **********/
341
342 char *tarball_fname = NULL;
343 char *progress_str = NULL;
344 char *tmp = NULL;
345 long max_val;
346
347 assert(bkpinfo != NULL);
348 mvaddstr_and_log_it(g_currentY, 0, _("Comparing archives"));
349 read_cfg_var(g_mondo_cfg_file, "last-filelist-number", tmp);
350
351 max_val = atol(tmp);
352 paranoid_free(tmp);
353
354 asprintf(&progress_str, _("Comparing with %s #%d "),
355 media_descriptor_string(bkpinfo->backup_media_type),
356 g_current_media_number);
357
358 open_progress_form(_("Comparing files"),
359 _("Comparing tarballs against filesystem."),
360 _("Please wait. This may take some time."),
361 progress_str, max_val);
362
363 log_to_screen(progress_str);
364
365 for (;;) {
366 insist_on_this_cd_number(bkpinfo, g_current_media_number);
367 update_progress_form(progress_str);
368 asprintf(&tarball_fname,
369 MNT_CDROM "/archives/%d.afio.bz2", current_tarball_number);
370
371 if (!does_file_exist(tarball_fname)) {
372 paranoid_free(tarball_fname);
373 asprintf(&tarball_fname, MNT_CDROM "/archives/%d.afio.lzo",
374 current_tarball_number);
375 }
376 if (!does_file_exist(tarball_fname)) {
377 paranoid_free(tarball_fname);
378 asprintf(&tarball_fname, MNT_CDROM "/archives/%d.afio.",
379 current_tarball_number);
380 }
381 if (!does_file_exist(tarball_fname)) {
382 paranoid_free(tarball_fname);
383 asprintf(&tarball_fname, MNT_CDROM "/archives/%d.star.bz2",
384 current_tarball_number);
385 }
386 if (!does_file_exist(tarball_fname)) {
387 paranoid_free(tarball_fname);
388 asprintf(&tarball_fname, MNT_CDROM "/archives/%d.star.",
389 current_tarball_number);
390 }
391 if (!does_file_exist(tarball_fname)) {
392 if (!does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST") ||
393 system("find " MNT_CDROM
394 "/archives/slice* > /dev/null 2> /dev/null")
395 == 0) {
396 log_msg(2, "OK, I think I'm done with tarballs...");
397 paranoid_free(tarball_fname);
398 break;
399 }
400 log_msg(2, "OK, I think it's time for another CD...");
401 g_current_media_number++;
402 paranoid_free(progress_str);
403 asprintf(&progress_str, _("Comparing with %s #%d "),
404 media_descriptor_string(bkpinfo->backup_media_type),
405 g_current_media_number);
406 log_to_screen(progress_str);
407 } else {
408 res = compare_a_tarball(tarball_fname, current_tarball_number);
409 paranoid_free(tarball_fname);
410
411 g_current_progress++;
412 current_tarball_number++;
413 }
414 }
415 paranoid_free(progress_str);
416 close_progress_form();
417
418 if (retval) {
419 mvaddstr_and_log_it(g_currentY++, 74, _("Errors."));
420 } else {
421 mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
422 }
423 return (retval);
424}
425
426/**************************************************************************
427 *END_COMPARE_ALL_TARBALLS *
428 **************************************************************************/
429
430/* @} - end LLcompareGroup */
431
432
433/**
434 * @addtogroup compareGroup
435 * @{
436 */
437/**
438 * Compare all data on a CD-R/CD-RW/DVD/ISO/NFS-based backup.
439 * @param bkpinfo The backup information structure. Passed to other functions.
440 * @return 0 for success, nonzero for failure.
441 */
442int compare_to_CD(struct s_bkpinfo *bkpinfo)
443{
444 /** needs malloc *********/
445 char *tmp = NULL;
446 char *cwd = NULL;
447 char *new = NULL;
448 char *command = NULL;
449 int resA = 0;
450 int resB = 0;
451 long noof_changed_files;
452
453 malloc_string(cwd);
454 malloc_string(new);
455
456 assert(bkpinfo != NULL);
457
458 getcwd(cwd, MAX_STR_LEN - 1);
459 chdir(bkpinfo->restore_path);
460 getcwd(new, MAX_STR_LEN - 1);
461 insist_on_this_cd_number(bkpinfo, g_current_media_number);
462 unlink("/tmp/changed.txt");
463
464 resA = compare_all_tarballs(bkpinfo);
465 resB = compare_all_biggiefiles(bkpinfo);
466 chdir(cwd);
467 noof_changed_files = count_lines_in_file("/tmp/changed.txt");
468 if (noof_changed_files) {
469 asprintf(&tmp, _("%ld files do not match the backup "),
470 noof_changed_files);
471 // mvaddstr_and_log_it( g_currentY++, 0, tmp );
472 log_to_screen(tmp);
473 paranoid_free(tmp);
474
475 asprintf(&command, "cat /tmp/changed.txt >> %s", MONDO_LOGFILE);
476 paranoid_system(command);
477 paranoid_free(command);
478 } else {
479 asprintf(&tmp, _("All files match the backup "));
480 mvaddstr_and_log_it(g_currentY++, 0, tmp);
481 log_to_screen(tmp);
482 paranoid_free(tmp);
483 }
484
485 paranoid_free(cwd);
486 paranoid_free(new);
487
488 return (resA + resB);
489}
490
491/**************************************************************************
492 *END_COMPARE_TO_CD *
493 **************************************************************************/
494
495
496/**
497 * Compare all data in the user's backup.
498 * This function will mount filesystems, compare afioballs and biggiefiles,
499 * and show the user the differences.
500 * @param bkpinfo The backup information structure. Passed to other functions.
501 * @param mountlist The mountlist containing partitions to mount.
502 * @param raidlist The raidlist containing the user's RAID devices.
503 * @return The number of errors/differences found.
504 */
505int
506compare_mode(struct s_bkpinfo *bkpinfo,
507 struct mountlist_itself *mountlist,
508 struct raidlist_itself *raidlist)
509{
510 int retval = 0;
511 long q;
512 char *tmp;
513
514 /**************************************************************************
515 * also deletes tmp/filelist.full & tmp/biggielist.txt _and_ tries to *
516 * restore them from start of tape, if available *
517 **************************************************************************/
518 assert(bkpinfo != NULL);
519 assert(mountlist != NULL);
520 assert(raidlist != NULL);
521
522 while (get_cfg_file_from_archive(bkpinfo)) {
523 if (!ask_me_yes_or_no
524 (_
525 ("Failed to find config file/archives. Choose another source?")))
526 {
527 fatal_error("Unable to find config file/archives. Aborting.");
528 }
529 interactively_obtain_media_parameters_from_user(bkpinfo, FALSE);
530 }
531
532 read_cfg_file_into_bkpinfo(g_mondo_cfg_file, bkpinfo);
533 g_current_media_number = 1;
534 mvaddstr_and_log_it(1, 30, _("Comparing Automatically"));
535 iamhere("Pre-MAD");
536 retval = mount_all_devices(mountlist, FALSE);
537 iamhere("Post-MAD");
538 if (retval) {
539 unmount_all_devices(mountlist);
540 return (retval);
541 }
542 if (bkpinfo->backup_media_type == tape
543 || bkpinfo->backup_media_type == udev) {
544 retval += compare_to_tape(bkpinfo);
545 } else if (bkpinfo->backup_media_type == cdstream) {
546 retval += compare_to_cdstream(bkpinfo);
547 } else {
548 retval += compare_to_CD(bkpinfo);
549 }
550 if (retval) {
551 mvaddstr_and_log_it(g_currentY++,
552 0,
553 _
554 ("Warning - differences found during the compare phase"));
555 }
556
557 retval += unmount_all_devices(mountlist);
558
559 if (count_lines_in_file("/tmp/changed.txt") > 0) {
560 mvaddstr_and_log_it(g_currentY++, 0,
561 _
562 ("Differences found while files were being compared."));
563 streamline_changes_file("/tmp/changed.files", "/tmp/changed.txt");
564 if (count_lines_in_file("/tmp/changed.files") <= 0) {
565 mvaddstr_and_log_it(g_currentY++, 0,
566 _
567 ("...but they were logfiles and temporary files. Your archives are fine."));
568 log_to_screen(_
569 ("The differences were logfiles and temporary files. Your archives are fine."));
570 } else {
571 q = count_lines_in_file("/tmp/changed.files");
572 asprintf(&tmp, _("%ld significant difference%s found."), q,
573 (q != 1) ? "s" : "");
574 mvaddstr_and_log_it(g_currentY++, 0, tmp);
575 log_to_screen(tmp);
576 paranoid_free(tmp);
577
578 asprintf(&tmp,
579 _("Type 'less /tmp/changed.files' for a list of non-matching files"));
580 mvaddstr_and_log_it(g_currentY++, 0, tmp);
581 log_to_screen(tmp);
582 paranoid_free(tmp);
583
584 log_msg(2, "calling popup_changelist_from_file()");
585 popup_changelist_from_file("/tmp/changed.files");
586 log_msg(2, "Returning from popup_changelist_from_file()");
587 }
588 } else {
589 log_to_screen
590 (_
591 ("No significant differences were found. Your backup is perfect."));
592 }
593 kill_petris();
594 return (retval);
595}
596
597/**************************************************************************
598 *END_COMPARE_MODE *
599 **************************************************************************/
600
601
602/**
603 * Compare all data on a cdstream-based backup.
604 * @param bkpinfo The backup information structure. Fields used:
605 * - @c bkpinfo->disaster_recovery
606 * - @c bkpinfo->media_device
607 * - @c bkpinfo->restore_path
608 * @return 0 for success, nonzero for failure.
609 */
610int compare_to_cdstream(struct s_bkpinfo *bkpinfo)
611{
612 int res;
613
614 char *dir = NULL;
615 char *command = NULL;
616
617 assert(bkpinfo != NULL);
618 /** needs malloc **/
619 malloc_string(dir);
620 getcwd(dir, MAX_STR_LEN);
621 chdir(bkpinfo->restore_path);
622
623 asprintf(&command, "cp -f /tmp/LAST-FILELIST-NUMBER %s/tmp",
624 bkpinfo->restore_path);
625 run_program_and_log_output(command, FALSE);
626 paranoid_free(command);
627 mvaddstr_and_log_it(g_currentY,
628 0, _("Verifying archives against filesystem"));
629
630 if (bkpinfo->disaster_recovery
631 && does_file_exist("/tmp/CDROM-LIVES-HERE")) {
632 paranoid_free(bkpinfo->media_device);
633 // last_line_of_file allocates the string
634 bkpinfo->media_device = last_line_of_file("/tmp/CDROM-LIVES-HERE");
635 } else {
636 paranoid_free(bkpinfo->media_device);
637 // find_cdrom_device allocates the string
638 bkpinfo->media_device = find_cdrom_device(FALSE);
639 }
640 res = verify_tape_backups(bkpinfo);
641 chdir(dir);
642 if (length_of_file("/tmp/changed.txt") > 2
643 && length_of_file("/tmp/changed.files") > 2) {
644 log_msg(0,
645 "Type 'less /tmp/changed.files' to see which files don't match the archives");
646 log_msg(2, "Calling popup_changelist_from_file()");
647 popup_changelist_from_file("/tmp/changed.files");
648 log_msg(2, "Returned from popup_changelist_from_file()");
649 }
650
651 mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
652 paranoid_free(dir);
653 return (res);
654}
655
656/**************************************************************************
657 *END_COMPARE_CD_STREAM *
658 **************************************************************************/
659
660
661/**
662 * Compare all data on a tape-based backup.
663 * @param bkpinfo The backup information structure. Field used: @c bkpinfo->restore_path.
664 * @return 0 for success, nonzero for failure.
665 */
666/**************************************************************************
667 * F@COMPARE_TO_TAPE() *
668 * compare_to_tape() - gots me?? *
669 * *
670 * returns: int *
671 **************************************************************************/
672int compare_to_tape(struct s_bkpinfo *bkpinfo)
673{
674 int res;
675 char *dir = NULL;
676 char *command = NULL;
677
678 assert(bkpinfo != NULL);
679 malloc_string(dir);
680
681 getcwd(dir, MAX_STR_LEN);
682 chdir(bkpinfo->restore_path);
683 asprintf(&command, "cp -f /tmp/LAST-FILELIST-NUMBER %s/tmp",
684 bkpinfo->restore_path);
685 run_program_and_log_output(command, FALSE);
686 paranoid_free(command);
687
688 mvaddstr_and_log_it(g_currentY,
689 0, _("Verifying archives against filesystem"));
690 res = verify_tape_backups(bkpinfo);
691 chdir(dir);
692 if (res) {
693 mvaddstr_and_log_it(g_currentY++, 74, _("Failed."));
694 } else {
695 mvaddstr_and_log_it(g_currentY++, 74, _("Done."));
696 }
697 paranoid_free(dir);
698 return (res);
699}
700
701/**************************************************************************
702 *END_COMPARE_TO_TAPE *
703 **************************************************************************/
704
705/* @} - end compareGroup */
Note: See TracBrowser for help on using the repository browser.