- Timestamp:
- Apr 27, 2015, 4:25:29 PM (10 years ago)
- Location:
- branches/3.2/mondo
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mondo/src/common/libmondo-devices.c
r3373 r3374 3284 3284 } 3285 3285 /* @} - end of deviceGroup */ 3286 3287 -
branches/3.2/mondo/src/common/libmondo-mountlist.c
r3308 r3374 22 22 /*@unused@*/ 23 23 //static char cvsid[] = "$Id$"; 24 25 /* Reference to global bkpinfo */26 extern struct s_bkpinfo *bkpinfo;27 24 28 25 /** -
branches/3.2/mondo/src/include/mr_str.h
r3193 r3374 19 19 extern inline char *mr_date(void); 20 20 extern void mr_strip_spaces(char *in_out); 21 extern char *mr_str_substitute(const char *in, const char *token, const char *subst); 21 22 /* 22 23 extern void mr_strip_char(char *in_out, char *caracs); -
branches/3.2/mondo/src/mondorestore/mondorestore.c
r3301 r3374 17 17 #include "mondo-rstr-compare-EXT.h" 18 18 #include "mondo-rstr-tools-EXT.h" 19 #include <utime.h> 20 21 extern void wait_until_software_raids_are_prepped(char *, int); 19 22 20 23 extern void twenty_seconds_til_yikes(void); … … 26 29 struct s_bkpinfo *bkpinfo; 27 30 31 char which_restore_mode(void); 28 32 29 33 /* For use in other programs (ex. XMondo) */ … … 132 136 #define COMPAQ_PROLIANTS_SUCK "Partition and format your disk using Compaq's disaster recovery CD. After you've done that, please reboot with your Mondo media in Interactive Mode." 133 137 134 135 136 137 /**138 * Allow the user to modify the mountlist before we partition & format their drives.139 * @param bkpinfo The backup information structure. @c disaster_recovery is the only field used.140 * @param mountlist The mountlist to let the user modify.141 * @param raidlist The raidlist that goes with @p mountlist.142 * @return 0 for success, nonzero for failure.143 * @ingroup restoreGuiGroup144 */145 int let_user_edit_the_mountlist(struct mountlist_itself *mountlist,146 struct raidlist_itself *raidlist)147 {148 int retval = 0, res = 0;149 150 log_msg(2, "let_user_edit_the_mountlist() --- starting");151 152 assert(bkpinfo != NULL);153 assert(mountlist != NULL);154 assert(raidlist != NULL);155 if (!bkpinfo->disaster_recovery) {156 strcpy(g_mountlist_fname, "/tmp/mountlist.txt");157 log_msg(2, "I guess you're testing edit_mountlist()");158 }159 if (!does_file_exist(g_mountlist_fname)) {160 log_to_screen(g_mountlist_fname);161 log_to_screen("does not exist");162 return (1);163 }164 165 retval = load_mountlist(mountlist, g_mountlist_fname);166 load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME);167 if (retval) {168 log_to_screen169 ("Warning - load_raidtab_into_raidlist returned an error");170 }171 res = edit_mountlist(g_mountlist_fname, mountlist, raidlist);172 if (res) {173 return (1);174 }175 176 save_mountlist_to_disk(mountlist, g_mountlist_fname);177 save_raidlist_to_raidtab(raidlist, RAIDTAB_FNAME);178 179 log_to_screen("I have finished editing the mountlist for you.");180 181 return (retval);182 }183 184 185 186 187 188 138 /** 189 139 * Determine whether @p mountlist contains a Compaq diagnostic partition. … … 193 143 */ 194 144 bool 195 partition_table_contains_Compaq_diagnostic_partition(struct 196 mountlist_itself * 197 mountlist) 198 { 199 int i; 200 201 assert(mountlist != NULL); 202 203 for (i = 0; i < mountlist->entries; i++) { 204 if (strstr(mountlist->el[i].format, "ompaq")) { 205 log_msg(2, "mountlist[%d] (%s) is %s (Compaq alert!)", 206 i, mountlist->el[i].device, mountlist->el[i].format); 207 208 return (TRUE); 209 } 210 } 211 return (FALSE); 145 partition_table_contains_Compaq_diagnostic_partition(struct mountlist_itself * mountlist) { 146 147 int i; 148 149 assert(mountlist != NULL); 150 151 for (i = 0; i < mountlist->entries; i++) { 152 if (strstr(mountlist->el[i].format, "ompaq")) { 153 log_msg(2, "mountlist[%d] (%s) is %s (Compaq alert!)", i, mountlist->el[i].device, mountlist->el[i].format); 154 155 return (TRUE); 156 } 157 } 158 return (FALSE); 212 159 } 213 160 … … 225 172 { 226 173 popup_and_OK(COMPAQ_PROLIANTS_SUCK); 227 if (ask_me_yes_or_no 228 ("Would you like to reboot and use your Compaq CD to prep your hard drive?")) 174 if (ask_me_yes_or_no("Would you like to reboot and use your Compaq CD to prep your hard drive?")) 229 175 { 230 fatal_error 231 ("Aborting. Please reboot and prep your hard drive with your Compaq CD."); 176 fatal_error("Aborting. Please reboot and prep your hard drive with your Compaq CD."); 232 177 } 233 178 } … … 237 182 **************************************************************************/ 238 183 239 240 241 /**242 * Call interactive_mode(), nuke_mode(), or compare_mode() depending on the user's choice.243 * @param bkpinfo The backup information structure. Most fields are used.244 * @param mountlist The mountlist containing information about the user's partitions.245 * @param raidlist The raidlist to go with @p mountlist.246 * @return The return code from the mode function called.247 * @ingroup restoreGroup248 */249 int250 catchall_mode(struct mountlist_itself *mountlist,251 struct raidlist_itself *raidlist)252 {253 char c;254 char *tmp = NULL;255 int retval = 0;256 257 log_it("inside catchall");258 assert(bkpinfo != NULL);259 assert(mountlist != NULL);260 assert(raidlist != NULL);261 log_it("pre wrm");262 c = which_restore_mode();263 log_it("post wrm");264 if (c == 'I' || c == 'C') {265 interactively_obtain_media_parameters_from_user(FALSE);266 } else if (c == 'N') {267 // Auto mode nothing special to do268 } else {269 popup_and_OK("No restoring or comparing will take place today.");270 if (is_this_device_mounted("/mnt/cdrom")) {271 run_program_and_log_output("umount -d /mnt/cdrom", FALSE);272 }273 if (g_ISO_restore_mode) {274 mr_asprintf(tmp, "umount -d %s", bkpinfo->isodir);275 run_program_and_log_output(tmp, FALSE);276 mr_free(tmp);277 }278 paranoid_MR_finish(0);279 }280 281 log_it("post int");282 283 if (bkpinfo->backup_media_type == iso) {284 if (iso_fiddly_bits((c == 'N') ? TRUE : FALSE)) {285 log_msg(2,286 "catchall_mode --- iso_fiddly_bits returned w/ error");287 return (1);288 } else {289 log_msg(2, "catchall_mode --- iso_fiddly_bits ok");290 }291 }292 293 if (c == 'I') {294 log_msg(2, "IM selected");295 retval += interactive_mode(mountlist, raidlist);296 } else if (c == 'N') {297 log_msg(2, "NM selected");298 retval += nuke_mode(mountlist, raidlist);299 } else if (c == 'C') {300 log_msg(2, "CM selected");301 retval += compare_mode(mountlist, raidlist);302 }303 return (retval);304 }305 306 /**************************************************************************307 *END_CATCHALL_MODE *308 **************************************************************************/309 310 /**************************************************************************311 *END_ EXTRACT_CONFIG_FILE_FROM_RAMDISK *312 **************************************************************************/313 314 315 /**316 * Locate an executable in the directory structure rooted at @p restg.317 * @param out_path Where to put the executable.318 * @param fname The basename of the executable.319 * @param restg The directory structure to look in.320 * @note If it could not be found in @p restg then @p fname is put in @p out_path.321 * @ingroup restoreUtilityGroup322 */323 void324 find_pathname_of_executable_preferably_in_RESTORING(char *out_path,325 char *fname,326 char *restg)327 {328 assert(out_path != NULL);329 assert_string_is_neither_NULL_nor_zerolength(fname);330 331 sprintf(out_path, "%s/sbin/%s", restg, fname);332 if (does_file_exist(out_path)) {333 sprintf(out_path, "%s/usr/sbin/%s", restg, fname);334 if (does_file_exist(out_path)) {335 sprintf(out_path, "%s/bin/%s", restg, fname);336 if (does_file_exist(out_path)) {337 sprintf(out_path, "%s/usr/bin/%s", restg, fname);338 if (does_file_exist(out_path)) {339 strcpy(out_path, fname);340 }341 }342 }343 }344 }345 346 /**************************************************************************347 *END_FIND_PATHNAME_OF_EXECUTABLE_PREFERABLY_IN_RESTORING *348 **************************************************************************/349 184 350 185 static void clean_blkid() { … … 402 237 403 238 239 /** 240 * Restore biggiefile @p bigfileno from the currently mounted CD. 241 * @param bkpinfo The backup information structure. Fields used: 242 * - @c bkpinfo->backup_media_type 243 * - @c bkpinfo->restore_path 244 * @param bigfileno The biggiefile number (starting from 0) to restore. 245 * @param filelist The node structure containing the list of files to restore. 246 * If the biggiefile is not in this list, it will be skipped (return value will 247 * still indicate success). 248 * @return 0 for success (or skip), nonzero for failure. 249 */ 250 int restore_a_biggiefile_from_CD(long bigfileno, 251 struct s_node *filelist, 252 char *pathname_of_last_file_restored) 253 { 254 FILE *fin; 255 FILE *fout; 256 FILE *fbzip2; 257 258 /** malloc ***/ 259 char *checksum = NULL; 260 char *outfile_fname = NULL; 261 char *tmp = NULL; 262 char *bzip2_command = NULL; 263 char *suffix = NULL; 264 char *sz_devfile = NULL; 265 char *bigblk; 266 char *mds = NULL; 267 int retval = 0; 268 int finished = FALSE; 269 long sliceno; 270 long siz; 271 char *ntfsprog_fifo = NULL; 272 char *file_to_openout = NULL; 273 struct s_filename_and_lstat_info biggiestruct; 274 struct utimbuf the_utime_buf, *ubuf; 275 bool use_ntfsprog_hack = FALSE; 276 pid_t pid; 277 int res = 0; 278 int old_loglevel; 279 struct s_node *node; 280 281 old_loglevel = g_loglevel; 282 ubuf = &the_utime_buf; 283 assert(bkpinfo != NULL); 284 285 pathname_of_last_file_restored[0] = '\0'; 286 if (!(bigblk = malloc(TAPE_BLOCK_SIZE))) { 287 fatal_error("Cannot malloc bigblk"); 288 } 289 290 if (!(fin = fopen(slice_fname(bigfileno, 0, ARCHIVES_PATH, ""), "r"))) { 291 log_to_screen("Cannot even open bigfile's info file"); 292 return (1); 293 } 294 295 memset((void *) &biggiestruct, 0, sizeof(biggiestruct)); 296 if (fread((void *) &biggiestruct, 1, sizeof(biggiestruct), fin) < 297 sizeof(biggiestruct)) { 298 log_msg(2, "Warning - unable to get biggiestruct of bigfile #%d", 299 bigfileno + 1); 300 } 301 paranoid_fclose(fin); 302 303 mr_asprintf(checksum, "%s", biggiestruct.checksum); 304 if (!checksum[0]) { 305 log_msg(3, "Warning - bigfile %ld does not have a checksum", bigfileno + 1); 306 } 307 mr_free(checksum); 308 309 if (!strncmp(biggiestruct.filename, "/dev/", 5)) // Whether NTFS or not :) 310 { 311 mr_asprintf(outfile_fname, "%s", biggiestruct.filename); 312 } else { 313 mr_asprintf(outfile_fname, "%s/%s", bkpinfo->restore_path, biggiestruct.filename); 314 } 315 316 /* skip file if we have a selective restore subset & it doesn't match */ 317 if (filelist != NULL) { 318 node = find_string_at_node(filelist, biggiestruct.filename); 319 if (!node) { 320 log_msg(0, "Skipping %s (name isn't in filelist)", biggiestruct.filename); 321 pathname_of_last_file_restored[0] = '\0'; 322 return (0); 323 } else if (!(node->selected)) { 324 log_msg(1, "Skipping %s (name isn't in biggielist subset)", biggiestruct.filename); 325 pathname_of_last_file_restored[0] = '\0'; 326 return (0); 327 } 328 } 329 330 /* otherwise, continue */ 331 log_msg(1, "DEFINITELY restoring %s", biggiestruct.filename); 332 if (biggiestruct.use_ntfsprog) { 333 if (strncmp(biggiestruct.filename, "/dev/", 5)) { 334 log_msg(1, "I was in error when I set biggiestruct.use_ntfsprog to TRUE."); 335 log_msg(1, "%s isn't even in /dev", biggiestruct.filename); 336 biggiestruct.use_ntfsprog = FALSE; 337 } 338 } 339 340 if (biggiestruct.use_ntfsprog) // if it's an NTFS device 341 { 342 g_loglevel = 4; 343 use_ntfsprog_hack = TRUE; 344 log_msg(2, "Calling ntfsclone in background because %s is an NTFS /dev entry", outfile_fname); 345 mr_asprintf(sz_devfile, "/tmp/%d.%d.000", (int) (random() % 32768), (int) (random() % 32768)); 346 mkfifo(sz_devfile, 0x770); 347 mr_asprintf(ntfsprog_fifo, "%s", sz_devfile); 348 mr_free(sz_devfile); 349 file_to_openout = ntfsprog_fifo; 350 switch (pid = fork()) { 351 case -1: 352 fatal_error("Fork failure"); 353 case 0: 354 log_msg(3, "CHILD - fip - calling feed_outfrom_ntfsprog(%s, %s)", biggiestruct.filename, ntfsprog_fifo); 355 res = feed_outfrom_ntfsprog(biggiestruct.filename, ntfsprog_fifo); 356 mr_free(ntfsprog_fifo); 357 exit(res); 358 break; 359 default: 360 log_msg(3, "feed_into_ntfsprog() called in background --- pid=%ld", (long int) (pid)); 361 } 362 mr_free(ntfsprog_fifo); 363 } else { 364 use_ntfsprog_hack = FALSE; 365 file_to_openout = outfile_fname; 366 if (!does_file_exist(outfile_fname)) // yes, it looks weird with the '!' but it's correct that way 367 { 368 make_hole_for_file(outfile_fname); 369 } 370 } 371 372 log_msg(2, "Reassembling big file %ld (%s)", bigfileno + 1, outfile_fname); 373 374 /* 375 last slice is zero-length and uncompressed; when we find it, we stop. 376 We DON'T wait until there are no more slices; if we did that, 377 We might stop at end of CD, not at last slice (which is 0-len and uncompd) 378 */ 379 380 strncpy(pathname_of_last_file_restored, biggiestruct.filename, MAX_STR_LEN - 1); 381 pathname_of_last_file_restored[MAX_STR_LEN - 1] = '\0'; 382 383 log_msg(3, "file_to_openout = %s", file_to_openout); 384 if (!(fout = fopen(file_to_openout, "w"))) { 385 log_to_screen("Cannot openout outfile_fname - hard disk full?"); 386 return (1); 387 } 388 log_msg(3, "Opened out to %s", outfile_fname); // CD/DVD --> mondorestore --> ntfsclone --> hard disk itself 389 390 for (sliceno = 1, finished = FALSE; !finished;) { 391 if (!does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "")) && 392 !does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "lzo")) && 393 !does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "gz")) && 394 !does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "lzma")) && 395 !does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "bz2"))) { 396 log_msg(3, "Cannot find a data slice or terminator slice on CD %d", g_current_media_number); 397 g_current_media_number++; 398 mds = media_descriptor_string(bkpinfo->backup_media_type); 399 log_msg(2, "Asking for %s #%d so that I may read slice #%ld\n", mds, g_current_media_number, sliceno); 400 mr_free(mds); 401 402 log_to_screen("Restoring from %s #%d", mds, g_current_media_number); 403 404 insist_on_this_cd_number(g_current_media_number); 405 log_to_screen("Continuing to restore."); 406 } else { 407 mr_asprintf(tmp, "%s", slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "")); 408 if (does_file_exist(tmp) && length_of_file(tmp) == 0) { 409 log_msg(2, "End of bigfile # %ld (slice %ld is the terminator)", bigfileno + 1, sliceno); 410 finished = TRUE; 411 mr_free(tmp); 412 continue; 413 } else { 414 if (does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "lzo"))) { 415 mr_asprintf(bzip2_command, "lzop"); 416 mr_asprintf(suffix, "lzo"); 417 } else 418 if (does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "gz"))) { 419 mr_asprintf(bzip2_command, "gzip"); 420 mr_asprintf(suffix, "gz"); 421 } else 422 if (does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "lzma"))) { 423 mr_asprintf(bzip2_command, "lzma"); 424 mr_asprintf(suffix, "lzma"); 425 } else 426 if (does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "bz2"))) { 427 mr_asprintf(bzip2_command, "bzip2"); 428 mr_asprintf(suffix, "bz2"); 429 } else 430 if (does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, ""))) { 431 mr_asprintf(bzip2_command, ""); 432 mr_asprintf(suffix, ""); 433 } else { 434 log_to_screen("OK, that's pretty fsck0red..."); 435 mr_free(tmp); 436 return (1); 437 } 438 } 439 mr_free(tmp); 440 if (bzip2_command != NULL) { 441 mr_strcat(bzip2_command, " -dc %s 2>> %s", slice_fname(bigfileno, sliceno, ARCHIVES_PATH, suffix), MONDO_LOGFILE); 442 } else { 443 mr_asprintf(bzip2_command, "cat %s 2>> %s", slice_fname(bigfileno, sliceno, ARCHIVES_PATH, suffix), MONDO_LOGFILE); 444 } 445 mr_free(suffix); 446 447 mds = media_descriptor_string(bkpinfo->backup_media_type); 448 mr_asprintf(tmp, "Working on %s #%d, file #%ld, slice #%ld ", mds, g_current_media_number, bigfileno + 1, sliceno); 449 mr_free(mds); 450 log_msg(2, tmp); 451 452 if (!g_text_mode) { 453 newtDrawRootText(0, g_noof_rows - 2, tmp); 454 newtRefresh(); 455 strip_spaces(tmp); 456 update_progress_form(tmp); 457 } 458 mr_free(tmp); 459 460 if (!(fbzip2 = popen(bzip2_command, "r"))) { 461 fatal_error("Can't run popen command"); 462 } 463 mr_free(bzip2_command); 464 465 while (!feof(fbzip2)) { 466 siz = fread(bigblk, 1, TAPE_BLOCK_SIZE, fbzip2); 467 if (siz > 0) { 468 siz = fwrite(bigblk, 1, siz, fout); 469 } 470 } 471 paranoid_pclose(fbzip2); 472 473 474 sliceno++; 475 g_current_progress++; 476 } 477 } 478 paranoid_fclose(fout); 479 g_loglevel = old_loglevel; 480 481 if (use_ntfsprog_hack) { 482 log_msg(3, "Waiting for ntfsclone to finish"); 483 mr_asprintf(tmp, " ps | grep \" ntfsclone \" | grep -v grep > /dev/null 2> /dev/null"); 484 while (system(tmp) == 0) { 485 sleep(1); 486 } 487 mr_free(tmp); 488 log_it("OK, ntfsclone has really finished"); 489 } 490 491 if (strcmp(outfile_fname, "/dev/null")) { 492 if (chown(outfile_fname, biggiestruct.properties.st_uid, biggiestruct.properties.st_gid)) { 493 // FIXME 494 } 495 chmod(outfile_fname, biggiestruct.properties.st_mode); 496 ubuf->actime = biggiestruct.properties.st_atime; 497 ubuf->modtime = biggiestruct.properties.st_mtime; 498 utime(outfile_fname, ubuf); 499 } 500 mr_free(outfile_fname); 501 paranoid_free(bigblk); 502 503 return (retval); 504 } 505 506 /************************************************************************** 507 *END_ RESTORE_A_BIGGIEFILE_FROM_CD * 508 **************************************************************************/ 509 510 511 /** 512 * Restore all biggiefiles from all media in this CD backup. 513 * The CD with the last afioball should be currently mounted. 514 * @param bkpinfo The backup information structure. @c backup_media_type is the 515 * only field used in this function. 516 * @param filelist The node structure containing the list of files to be 517 * restored. If a prospective biggiefile is not in this list, it will be ignored. 518 * @return 0 for success, nonzero for failure. 519 */ 520 int restore_all_biggiefiles_from_CD(struct s_node *filelist) { 521 522 int retval = 0; 523 int res = 0; 524 long noof_biggiefiles, bigfileno = 0, total_slices; 525 /** malloc **/ 526 char *tmp = NULL; 527 char *tmp1 = NULL; 528 char *mds = NULL; 529 bool just_changed_cds = FALSE; 530 char *xattr_fname = NULL; 531 char *acl_fname = NULL; 532 char *biggies_whose_EXATs_we_should_set = NULL; // EXtended ATtributes 533 char *pathname_of_last_biggie_restored; 534 FILE *fbw = NULL; 535 536 malloc_string(pathname_of_last_biggie_restored); 537 malloc_string(tmp); 538 assert(bkpinfo != NULL); 539 540 mr_asprintf(biggies_whose_EXATs_we_should_set, "%s/biggies-whose-EXATs-we-should-set", bkpinfo->tmpdir); 541 if (!(fbw = fopen(biggies_whose_EXATs_we_should_set, "w"))) { 542 log_msg(1, "Warning - cannot openout %s", biggies_whose_EXATs_we_should_set); 543 } 544 545 read_cfg_var(g_mondo_cfg_file, "total-slices", tmp); 546 total_slices = atol(tmp); 547 mr_free(tmp); 548 549 mr_asprintf(tmp1, "Reassembling large files "); 550 mvaddstr_and_log_it(g_currentY, 0, tmp1); 551 mr_free(tmp1); 552 553 if (length_of_file(BIGGIELIST) < 6) { 554 log_msg(1, "OK, no biggielist; not restoring biggiefiles"); 555 return (0); 556 } 557 noof_biggiefiles = count_lines_in_file(BIGGIELIST); 558 if (noof_biggiefiles <= 0) { 559 log_msg(2, "OK, no biggiefiles in biggielist; not restoring biggiefiles"); 560 return (0); 561 } 562 log_msg(2, "OK, there are %ld biggiefiles in the archives", noof_biggiefiles); 563 564 open_progress_form("Reassembling large files", 565 "I am now reassembling all the large files.", 566 "Please wait. This may take some time.", 567 "", total_slices); 568 for (bigfileno = 0 ; bigfileno < noof_biggiefiles ;) { 569 log_msg(2, "Thinking about restoring bigfile %ld", bigfileno + 1); 570 if (!does_file_exist(slice_fname(bigfileno, 0, ARCHIVES_PATH, ""))) { 571 log_msg(3, "...but its first slice isn't on this CD. Perhaps this was a selective restore?"); 572 mds = media_descriptor_string(bkpinfo->backup_media_type); 573 log_msg(3, "Cannot find bigfile #%ld 's first slice on %s #%d", bigfileno + 1, mds, g_current_media_number); 574 log_msg(3, "Slicename would have been %s", 575 slice_fname(bigfileno, 0, ARCHIVES_PATH, "")); 576 // I'm not positive 'just_changed_cds' is even necessary... 577 if (just_changed_cds) { 578 just_changed_cds = FALSE; 579 log_msg(3, "I'll continue to scan this CD for bigfiles to be restored."); 580 } else if (does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST")) { 581 insist_on_this_cd_number(++g_current_media_number); 582 log_to_screen("Restoring from %s #%d", mds, g_current_media_number); 583 just_changed_cds = TRUE; 584 } else { 585 /* That big file doesn't exist, but the followings may */ 586 /* So we need to continue looping */ 587 log_msg(2, "There was no bigfile #%ld. That's OK.", bigfileno + 1); 588 log_msg(2, "I'm going to stop restoring bigfiles now."); 589 retval++; 590 bigfileno++; 591 } 592 mr_free(mds); 593 } else { 594 just_changed_cds = FALSE; 595 mr_asprintf(tmp1, "Restoring big file %ld", bigfileno + 1); 596 update_progress_form(tmp1); 597 mr_free(tmp1); 598 res = restore_a_biggiefile_from_CD(bigfileno, filelist, pathname_of_last_biggie_restored); 599 log_it("%s",pathname_of_last_biggie_restored); 600 if (fbw && pathname_of_last_biggie_restored[0]) { 601 fprintf(fbw, "%s\n", pathname_of_last_biggie_restored); 602 } 603 retval += res; 604 bigfileno++; 605 606 } 607 } 608 609 if (fbw) { 610 fclose(fbw); 611 if (g_getfattr) { 612 mr_asprintf(xattr_fname, XATTR_BIGGLST_FNAME_RAW_SZ, ARCHIVES_PATH); 613 if (length_of_file(xattr_fname) > 0) { 614 set_fattr_list(biggies_whose_EXATs_we_should_set, xattr_fname); 615 } 616 mr_free(xattr_fname); 617 } 618 if (g_getfacl) { 619 mr_asprintf(acl_fname, ACL_BIGGLST_FNAME_RAW_SZ, ARCHIVES_PATH); 620 if (length_of_file(acl_fname) > 0) { 621 set_acl_list(biggies_whose_EXATs_we_should_set, acl_fname); 622 } 623 mr_free(acl_fname); 624 } 625 } 626 mr_free(biggies_whose_EXATs_we_should_set); 627 628 if (does_file_exist("/PAUSE")) { 629 popup_and_OK("Press ENTER to go on. Delete /PAUSE to stop these pauses."); 630 } 631 close_progress_form(); 632 if (retval) { 633 mvaddstr_and_log_it(g_currentY++, 74, "Errors."); 634 } else { 635 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 636 } 637 paranoid_free(pathname_of_last_biggie_restored); 638 return (retval); 639 } 640 641 /************************************************************************** 642 *END_RESTORE_ALL_BIGGIFILES_FROM_CD * 643 **************************************************************************/ 644 645 646 647 /** 648 * Restore @p tarball_fname from CD. 649 * @param tarball_fname The filename of the tarball to restore (in /mnt/cdrom). 650 * This will be used unmodified. 651 * @param current_tarball_number The number (starting from 0) of the fileset 652 * we're restoring now. 653 * @param filelist The node structure containing the list of files to be 654 * restored. If no file in the afioball is in this list, afio will still be 655 * called, but nothing will be written. 656 * @return 0 for success, nonzero for failure. 657 */ 658 int 659 restore_a_tarball_from_CD(char *tarball_fname, 660 long current_tarball_number, 661 struct s_node *filelist) 662 { 663 int retval = 0; 664 int res; 665 char *p; 666 667 /** malloc **/ 668 char *command = NULL; 669 char *tmp = NULL; 670 char *filelist_name = NULL; 671 char *filelist_subset_fname = NULL; 672 char *executable = NULL; 673 char *temp_log = NULL; 674 long matches = 0; 675 bool use_star; 676 char *xattr_fname = NULL; 677 char *acl_fname = NULL; 678 679 assert_string_is_neither_NULL_nor_zerolength(tarball_fname); 680 assert(bkpinfo != NULL); 681 682 log_msg(5, "Entering"); 683 use_star = (strstr(tarball_fname, ".star")) ? TRUE : FALSE; 684 mr_asprintf(command, "mkdir -p %s/tmp", MNT_RESTORING); 685 run_program_and_log_output(command, 9); 686 paranoid_free(command); 687 688 mr_asprintf(filelist_name, MNT_CDROM "/archives/filelist.%ld", current_tarball_number); 689 if (length_of_file(filelist_name) <= 2) { 690 log_msg(2, "There are _zero_ files in filelist '%s'", filelist_name); 691 log_msg(2, "This is a bit silly (ask dev-team to fix mondo_makefilelist, please)"); 692 log_msg(2, "but it's non-critical. It's cosmetic. Don't worry about it."); 693 retval = 0; 694 mr_free(filelist_name); 695 log_msg(5, "Leaving"); 696 return(0); 697 } 698 if (count_lines_in_file(filelist_name) <= 0 || length_of_file(tarball_fname) <= 0) { 699 log_msg(3, "length_of_file(%s) = %llu", tarball_fname, length_of_file(tarball_fname)); 700 log_msg(3, "count_lines_in_file(%s) = %llu", tarball_fname, count_lines_in_file(tarball_fname)); 701 log_to_screen("Unable to restore fileset #%ld (CD I/O error)", current_tarball_number); 702 mr_free(filelist_name); 703 log_msg(5, "Leaving"); 704 return(1); 705 } 706 707 if (filelist) { 708 mr_asprintf(filelist_subset_fname, "/tmp/filelist-subset-%ld.tmp", current_tarball_number); 709 if ((matches = 710 save_filelist_entries_in_common(filelist_name, filelist, 711 filelist_subset_fname, 712 use_star)) <= 0) { 713 log_msg(1, "Skipping fileset %ld", current_tarball_number); 714 } else { 715 log_msg(3, "Saved fileset %ld's subset to %s", current_tarball_number, filelist_subset_fname); 716 } 717 log_to_screen("Tarball #%ld --- %ld matches", current_tarball_number, matches); 718 } 719 mr_free(filelist_name); 720 721 if (filelist == NULL || matches > 0) { 722 if (g_getfattr) { 723 mr_asprintf(xattr_fname, XATTR_LIST_FNAME_RAW_SZ, MNT_CDROM "/archives", current_tarball_number); 724 } 725 if (g_getfacl) { 726 mr_asprintf(acl_fname, ACL_LIST_FNAME_RAW_SZ, MNT_CDROM "/archives", current_tarball_number); 727 } 728 if (strstr(tarball_fname, ".bz2")) { 729 mr_asprintf(executable, "bzip2"); 730 } else if (strstr(tarball_fname, ".lzma")) { 731 mr_asprintf(executable, "lzma"); 732 } else if (strstr(tarball_fname, ".gz")) { 733 mr_asprintf(executable, "gzip"); 734 } else if (strstr(tarball_fname, ".lzo")) { 735 mr_asprintf(executable, "lzop"); 736 } 737 if (bkpinfo->compression_level == 0) { 738 mr_asprintf(executable, "%s", ""); 739 } else { 740 if (executable) { 741 mr_asprintf(tmp, "which %s > /dev/null 2> /dev/null", executable); 742 res = run_program_and_log_output(tmp, FALSE); 743 mr_free(tmp); 744 745 if (res) { 746 log_to_screen("(compare_a_tarball) Compression program %s not found - oh no!", executable); 747 paranoid_MR_finish(1); 748 } 749 tmp = executable; 750 mr_asprintf(executable, "-P %s -Z", tmp); 751 mr_free(tmp); 752 } 753 } 754 #ifdef __FreeBSD__ 755 #define BUFSIZE 512 756 #else 757 #define BUFSIZE (1024L*1024L)/TAPE_BLOCK_SIZE 758 #endif 759 760 if (use_star) { 761 mr_asprintf(command, "star -x -force-remove -sparse -U " STAR_ACL_SZ " file=%s", tarball_fname); 762 if (strstr(tarball_fname, ".bz2")) { 763 mr_strcat(command, " -bz"); 764 } 765 } else { 766 if (! executable) { 767 log_msg(2, "No executable, this shouldn't happen !"); 768 } else { 769 if (filelist_subset_fname != NULL) { 770 mr_asprintf(command, "afio -i -M 8m -b %ld -c %ld %s -w '%s' %s", TAPE_BLOCK_SIZE, BUFSIZE, executable, filelist_subset_fname, tarball_fname); 771 } else { 772 mr_asprintf(command, "afio -i -b %ld -c %ld -M 8m %s %s", TAPE_BLOCK_SIZE, BUFSIZE, executable, tarball_fname); 773 } 774 } 775 } 776 mr_free(executable); 777 778 #undef BUFSIZE 779 mr_asprintf(temp_log, "/tmp/%d.%d", (int) (random() % 32768), (int) (random() % 32768)); 780 781 mr_strcat(command, " 2>> %s >> %s", temp_log, temp_log); 782 log_msg(1, "command = '%s'", command); 783 unlink(temp_log); 784 res = system(command); 785 if (res) { 786 p = strstr(command, "-acl "); 787 if (p) { 788 p[0] = p[1] = p[2] = p[3] = ' '; 789 log_msg(1, "new command = '%s'", command); 790 res = system(command); 791 } 792 } 793 paranoid_free(command); 794 795 if (res && length_of_file(temp_log) < 5) { 796 res = 0; 797 } 798 799 if (! use_star) { 800 if (g_getfattr) { 801 log_msg(1, "Setting fattr list %s", xattr_fname); 802 if (length_of_file(xattr_fname) > 0) { 803 res = set_fattr_list(filelist_subset_fname, xattr_fname); 804 if (res) { 805 log_to_screen("Errors occurred while setting extended attributes"); 806 } else { 807 log_msg(1, "I set xattr OK"); 808 } 809 retval += res; 810 } 811 } 812 if (g_getfacl) { 813 log_msg(1, "Setting acl list %s", acl_fname); 814 if (length_of_file(acl_fname) > 0) { 815 res = set_acl_list(filelist_subset_fname, acl_fname); 816 if (res) { 817 log_to_screen("Errors occurred while setting access control lists"); 818 } else { 819 log_msg(1, "I set ACL OK"); 820 } 821 retval += res; 822 } 823 } 824 } else { 825 retval = res; 826 } 827 // Be verbose for star 828 if (retval || use_star) { 829 mr_asprintf(command, "cat %s >> %s", temp_log, MONDO_LOGFILE); 830 paranoid_system(command); 831 paranoid_free(command); 832 833 if (retval) { 834 log_msg(2, "Errors occurred while processing fileset #%d", current_tarball_number); 835 } 836 } else { 837 log_msg(2, "Fileset #%d processed OK", current_tarball_number); 838 } 839 unlink(temp_log); 840 mr_free(temp_log); 841 } 842 if (does_file_exist("/PAUSE")) { 843 popup_and_OK 844 ("Press ENTER to go on. Delete /PAUSE to stop these pauses."); 845 } 846 unlink(filelist_subset_fname); 847 mr_free(filelist_subset_fname); 848 if (g_getfattr) { 849 unlink(xattr_fname); 850 mr_free(xattr_fname); 851 } 852 if (g_getfacl) { 853 unlink(acl_fname); 854 mr_free(acl_fname); 855 } 856 857 log_msg(5, "Leaving"); 858 return (retval); 859 } 860 861 /************************************************************************** 862 *END_RESTORE_A_TARBALL_FROM_CD * 863 **************************************************************************/ 864 865 866 867 /** 868 * Restore all afioballs from all CDs in the backup. 869 * The first CD should be inserted (if not, it will be asked for). 870 * @param bkpinfo The backup information structure. @c backup_media_type is the 871 * only field used in @e this function. 872 * @param filelist The node structure containing the list of files to be 873 * restored. If no file in some particular afioball is in this list, afio will 874 * still be called for that fileset, but nothing will be written. 875 * @return 0 for success, or the number of filesets that failed. 876 */ 877 int 878 restore_all_tarballs_from_CD(struct s_node *filelist) 879 { 880 int retval = 0; 881 int res; 882 int attempts; 883 long current_tarball_number = 0L; 884 long max_val; 885 /**malloc ***/ 886 char *mds = NULL; 887 char *tmp = NULL; 888 char *tmp1 = NULL; 889 char *tarball_fname = NULL; 890 char *progress_str = NULL; 891 892 assert(bkpinfo != NULL); 893 894 malloc_string(tmp); 895 mvaddstr_and_log_it(g_currentY, 0, "Restoring from archives"); 896 log_msg(2, "Insisting on 1st media, so that I can have a look at LAST-FILELIST-NUMBER"); 897 if (g_current_media_number != 1) { 898 log_msg(3, "OK, that's jacked up."); 899 g_current_media_number = 1; 900 } 901 insist_on_this_cd_number(g_current_media_number); 902 read_cfg_var(g_mondo_cfg_file, "last-filelist-number", tmp); 903 max_val = atol(tmp) + 1; 904 paranoid_free(tmp); 905 906 mds = media_descriptor_string(bkpinfo->backup_media_type); 907 mr_asprintf(progress_str, "Restoring from %s #%d", mds, g_current_media_number); 908 909 log_to_screen(progress_str); 910 open_progress_form("Restoring from archives", 911 "Restoring data from the archives.", 912 "Please wait. This may take some time.", 913 progress_str, max_val); 914 for (;;) { 915 insist_on_this_cd_number(g_current_media_number); 916 update_progress_form(progress_str); 917 mr_free(progress_str); 918 919 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.bz2", current_tarball_number); 920 if (!does_file_exist(tarball_fname)) { 921 mr_free(tarball_fname); 922 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.gz", current_tarball_number); 923 } 924 if (!does_file_exist(tarball_fname)) { 925 mr_free(tarball_fname); 926 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.lzma", current_tarball_number); 927 } 928 if (!does_file_exist(tarball_fname)) { 929 mr_free(tarball_fname); 930 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.lzo", current_tarball_number); 931 } 932 if (!does_file_exist(tarball_fname)) { 933 mr_free(tarball_fname); 934 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.", current_tarball_number); 935 } 936 if (!does_file_exist(tarball_fname)) { 937 mr_free(tarball_fname); 938 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.star.bz2", current_tarball_number); 939 } 940 if (!does_file_exist(tarball_fname)) { 941 mr_free(tarball_fname); 942 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.star.", current_tarball_number); 943 } 944 if (!does_file_exist(tarball_fname)) { 945 if (current_tarball_number == 0) { 946 log_to_screen 947 ("No tarballs. Strange. Maybe you only backed up freakin' big files?"); 948 mr_free(tarball_fname); 949 return (0); 950 } 951 if (!does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST") 952 || system("find " MNT_CDROM 953 "/archives/slice* > /dev/null 2> /dev/null") == 954 0) { 955 break; 956 } 957 g_current_media_number++; 958 mr_asprintf(progress_str, "Restoring from %s #%d", media_descriptor_string(bkpinfo->backup_media_type), g_current_media_number); 959 log_to_screen(progress_str); 960 } else { 961 mr_asprintf(progress_str, "Restoring from fileset #%ld on %s #%d", current_tarball_number, mds, g_current_media_number); 962 for (res = 999, attempts = 0; attempts < 3 && res != 0; attempts++) { 963 res = restore_a_tarball_from_CD(tarball_fname, current_tarball_number, filelist); 964 } 965 mr_asprintf(tmp1, "%s #%d, fileset #%ld - restore ", mds, g_current_media_number, current_tarball_number); 966 if (res) { 967 mr_strcat(tmp1, "reported errors"); 968 } else if (attempts > 1) { 969 mr_strcat(tmp1, "succeeded"); 970 } else { 971 mr_strcat(tmp1, "succeeded"); 972 } 973 if (attempts > 1) { 974 mr_strcat(tmp1, " (%d attempts) - review logs", attempts); 975 } 976 if (attempts > 1) { 977 log_to_screen(tmp1); 978 } 979 mr_free(tmp1); 980 981 retval += res; 982 current_tarball_number++; 983 g_current_progress++; 984 } 985 mr_free(tarball_fname); 986 987 /* Now we need to umount the current media to have the next mounted by insist_on_this_cd_number */ 988 /* run_program_and_log_output("umount " MNT_CDROM, FALSE); */ 989 } 990 mr_free(mds); 991 mr_free(progress_str); 992 993 close_progress_form(); 994 if (retval) { 995 mvaddstr_and_log_it(g_currentY++, 74, "Errors."); 996 } else { 997 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 998 } 999 1000 return (retval); 1001 } 1002 1003 /************************************************************************** 1004 *END_RESTORE_ALL_TARBALLS_FROM_CD * 1005 **************************************************************************/ 1006 1007 1008 /** 1009 * Restore a biggiefile from the currently opened stream. 1010 * @param bkpinfo The backup information structure. Fields used: 1011 * - @c bkpinfo->restore_path 1012 * - @c bkpinfo->zip_exe 1013 * @param orig_bf_fname The original filename of the biggiefile. 1014 * @param biggiefile_number The number of the biggiefile (starting from 0). 1015 * @param orig_checksum Unused. 1016 * @param biggiefile_size Unused. 1017 * @param filelist The node structure containing the list of files to be restored. 1018 * If @p orig_bf_fname is not in the list, it will be ignored. 1019 * @return 0 for success (or skip), nonzero for failure. 1020 * @bug orig_checksum and biggiefile_size are unused (except to check that they are non-NULL). 1021 */ 1022 int restore_a_biggiefile_from_stream(char *orig_bf_fname, long biggiefile_number, char *orig_checksum, //UNUSED 1023 long long biggiefile_size, //UNUSED 1024 struct s_node *filelist, 1025 int use_ntfsprog, 1026 char *pathname_of_last_file_restored) 1027 { 1028 FILE *pout; 1029 FILE *fin; 1030 1031 /** mallocs ********/ 1032 char *tmp = NULL; 1033 char *tmp1 = NULL; 1034 char *command = NULL; 1035 char *outfile_fname = NULL; 1036 char *sz_devfile = NULL; 1037 char *ntfsprog_fifo = NULL; 1038 char *file_to_openout = NULL; 1039 1040 struct s_node *node; 1041 1042 int old_loglevel; 1043 long current_slice_number = 0; 1044 int retval = 0; 1045 int res = 0; 1046 int ctrl_chr = '\0'; 1047 long long slice_siz; 1048 bool dummy_restore = FALSE; 1049 bool use_ntfsprog_hack = FALSE; 1050 pid_t pid; 1051 struct s_filename_and_lstat_info biggiestruct; 1052 struct utimbuf the_utime_buf, *ubuf; 1053 ubuf = &the_utime_buf; 1054 1055 malloc_string(tmp); 1056 old_loglevel = g_loglevel; 1057 assert(bkpinfo != NULL); 1058 assert(orig_bf_fname != NULL); 1059 assert(orig_checksum != NULL); 1060 1061 pathname_of_last_file_restored[0] = '\0'; 1062 if (use_ntfsprog == BLK_START_A_PIHBIGGIE) { 1063 use_ntfsprog = 1; 1064 log_msg(1, "%s --- pih=YES", orig_bf_fname); 1065 } else if (use_ntfsprog == BLK_START_A_NORMBIGGIE) { 1066 use_ntfsprog = 0; 1067 log_msg(1, "%s --- pih=NO", orig_bf_fname); 1068 } else { 1069 use_ntfsprog = 0; 1070 log_msg(1, "%s --- pih=NO (weird marker though)", orig_bf_fname); 1071 } 1072 1073 strncpy(pathname_of_last_file_restored, orig_bf_fname, 1074 MAX_STR_LEN - 1); 1075 pathname_of_last_file_restored[MAX_STR_LEN - 1] = '\0'; 1076 1077 /* open out to biggiefile to be restored (or /dev/null if biggiefile is not to be restored) */ 1078 1079 if (filelist != NULL) { 1080 node = find_string_at_node(filelist, orig_bf_fname); 1081 if (!node) { 1082 dummy_restore = TRUE; 1083 log_msg(1, 1084 "Skipping big file %ld (%s) - not in biggielist subset", 1085 biggiefile_number + 1, orig_bf_fname); 1086 pathname_of_last_file_restored[0] = '\0'; 1087 } else if (!(node->selected)) { 1088 dummy_restore = TRUE; 1089 log_msg(1, "Skipping %s (name isn't in biggielist subset)", 1090 orig_bf_fname); 1091 pathname_of_last_file_restored[0] = '\0'; 1092 } 1093 } 1094 1095 if (use_ntfsprog) { 1096 if (strncmp(orig_bf_fname, "/dev/", 5)) { 1097 log_msg(1, 1098 "I was in error when I set use_ntfsprog to TRUE."); 1099 log_msg(1, "%s isn't even in /dev", orig_bf_fname); 1100 use_ntfsprog = FALSE; 1101 } 1102 } 1103 1104 if (use_ntfsprog) { 1105 g_loglevel = 4; 1106 mr_asprintf(outfile_fname, "%s", orig_bf_fname); 1107 use_ntfsprog_hack = TRUE; 1108 log_msg(2, "Calling ntfsclone in background because %s is a /dev entry", outfile_fname); 1109 mr_asprintf(sz_devfile, "%s/%d.%d.000", bkpinfo->tmpdir, (int) (random() % 32768), (int) (random() % 32768)); 1110 mkfifo(sz_devfile, 0x770); 1111 mr_asprintf(ntfsprog_fifo, "%s", sz_devfile); 1112 mr_free(sz_devfile); 1113 1114 file_to_openout = ntfsprog_fifo; 1115 switch (pid = fork()) { 1116 case -1: 1117 fatal_error("Fork failure"); 1118 case 0: 1119 log_msg(3, "CHILD - fip - calling feed_outfrom_ntfsprog(%s, %s)", outfile_fname, ntfsprog_fifo); 1120 res = feed_outfrom_ntfsprog(outfile_fname, ntfsprog_fifo); 1121 mr_free(ntfsprog_fifo); 1122 exit(res); 1123 break; 1124 default: 1125 log_msg(3, "feed_into_ntfsprog() called in background --- pid=%ld", (long int) (pid)); 1126 } 1127 mr_free(ntfsprog_fifo); 1128 } else { 1129 if (!strncmp(orig_bf_fname, "/dev/", 5)) { 1130 // non-NTFS partition 1131 mr_asprintf(outfile_fname, "%s", orig_bf_fname); 1132 } else { 1133 // biggiefile 1134 mr_asprintf(outfile_fname, "%s/%s", bkpinfo->restore_path, orig_bf_fname); 1135 } 1136 use_ntfsprog_hack = FALSE; 1137 file_to_openout = outfile_fname; 1138 if (!does_file_exist(outfile_fname)) // yes, it looks weird with the '!' but it's correct that way 1139 { 1140 make_hole_for_file(outfile_fname); 1141 } 1142 log_msg(2, "Reassembling big file %ld (%s)", biggiefile_number + 1, orig_bf_fname); 1143 } 1144 1145 if (dummy_restore) { 1146 mr_free(outfile_fname); 1147 mr_asprintf(outfile_fname, "/dev/null"); 1148 } 1149 1150 if (!bkpinfo->zip_exe[0]) { 1151 mr_asprintf(command, "cat > \"%s\"", file_to_openout); 1152 } else { 1153 mr_asprintf(command, "%s -dc > \"%s\" 2>> %s", bkpinfo->zip_exe, file_to_openout, MONDO_LOGFILE); 1154 if (strcmp(bkpinfo->zip_exe, "gzip") == 0) { 1155 /* Ignore SIGPIPE for gzip as it causes errors on big files 1156 * Cf: http://trac.mondorescue.org/ticket/244 */ 1157 signal(SIGPIPE,SIG_IGN); 1158 } 1159 } 1160 log_msg(3, "Pipe command = '%s'", command); 1161 1162 /* restore biggiefile, one slice at a time */ 1163 if (!(pout = popen(command, "w"))) { 1164 fatal_error("Cannot pipe out"); 1165 } 1166 mr_free(command); 1167 1168 for (res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr); 1169 ctrl_chr != BLK_STOP_A_BIGGIE; 1170 res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr)) { 1171 if (ctrl_chr != BLK_START_AN_AFIO_OR_SLICE) { 1172 wrong_marker(BLK_START_AN_AFIO_OR_SLICE, ctrl_chr); 1173 } 1174 log_msg(2, "Working on file #%ld, slice #%ld ", biggiefile_number + 1, current_slice_number); 1175 if (!g_text_mode) { 1176 newtDrawRootText(0, g_noof_rows - 2, tmp); 1177 newtRefresh(); 1178 } 1179 strip_spaces(tmp); 1180 update_progress_form(tmp); 1181 if (current_slice_number == 0) { 1182 res = 1183 read_file_from_stream_to_file("/tmp/biggie-blah.txt", 1184 slice_siz); 1185 if (!(fin = fopen("/tmp/biggie-blah.txt", "r"))) { 1186 log_OS_error("blah blah"); 1187 } else { 1188 if (fread 1189 ((void *) &biggiestruct, 1, sizeof(biggiestruct), 1190 fin) < sizeof(biggiestruct)) { 1191 log_msg(2, 1192 "Warning - unable to get biggiestruct of bigfile #%d", 1193 biggiefile_number + 1); 1194 } 1195 paranoid_fclose(fin); 1196 } 1197 } else { 1198 res = 1199 read_file_from_stream_to_stream(pout, slice_siz); 1200 } 1201 retval += res; 1202 res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr); 1203 if (ctrl_chr != BLK_STOP_AN_AFIO_OR_SLICE) { 1204 wrong_marker(BLK_STOP_AN_AFIO_OR_SLICE, ctrl_chr); 1205 } 1206 current_slice_number++; 1207 g_current_progress++; 1208 } 1209 paranoid_pclose(pout); 1210 1211 if (bkpinfo->zip_exe[0]) { 1212 if (strcmp(bkpinfo->zip_exe, "gzip") == 0) { 1213 /* Re-enable SIGPIPE for gzip */ 1214 signal(SIGPIPE, terminate_daemon); 1215 } 1216 } 1217 1218 log_msg(1, "pathname_of_last_file_restored is now %s", 1219 pathname_of_last_file_restored); 1220 1221 if (use_ntfsprog_hack) { 1222 log_msg(3, "Waiting for ntfsclone to finish"); 1223 mr_asprintf(tmp1, " ps | grep \" ntfsclone \" | grep -v grep > /dev/null 2> /dev/null"); 1224 while (system(tmp1) == 0) { 1225 sleep(1); 1226 } 1227 mr_free(tmp1); 1228 log_msg(3, "OK, ntfsclone has really finished"); 1229 } 1230 1231 log_msg(3, "biggiestruct.filename = %s", biggiestruct.filename); 1232 log_msg(3, "biggiestruct.checksum = %s", biggiestruct.checksum); 1233 if (strcmp(outfile_fname, "/dev/null")) { 1234 chmod(outfile_fname, biggiestruct.properties.st_mode); 1235 if (chown(outfile_fname, biggiestruct.properties.st_uid, biggiestruct.properties.st_gid)) { 1236 // FIXME 1237 } 1238 ubuf->actime = biggiestruct.properties.st_atime; 1239 ubuf->modtime = biggiestruct.properties.st_mtime; 1240 utime(outfile_fname, ubuf); 1241 } 1242 mr_free(outfile_fname); 1243 1244 paranoid_free(tmp); 1245 g_loglevel = old_loglevel; 1246 return (retval); 1247 } 1248 1249 /************************************************************************** 1250 *END_RESTORE_A_BIGGIEFILE_FROM_STREAM * 1251 **************************************************************************/ 1252 1253 1254 1255 /** 1256 * Restore all biggiefiles from the currently opened stream. 1257 * @param bkpinfo The backup information structure. Passed to other functions. 1258 * @param filelist The node structure containing the list of files to be 1259 * restored. If a prospective biggiefile is not in the list, it will be ignored. 1260 * @return 0 for success, or the number of biggiefiles that failed. 1261 */ 1262 int 1263 restore_all_biggiefiles_from_stream(struct s_node *filelist) 1264 { 1265 long noof_biggiefiles; 1266 long current_bigfile_number = 0; 1267 long total_slices; 1268 1269 int retval = 0; 1270 int res = 0; 1271 int ctrl_chr; 1272 1273 /** malloc add ****/ 1274 char *tmp = NULL; 1275 char *tmp1 = NULL; 1276 char *biggie_fname; 1277 char *biggie_cksum; 1278 char *xattr_fname = NULL; 1279 char *acl_fname = NULL; 1280 char *p; 1281 char *pathname_of_last_biggie_restored; 1282 char *biggies_whose_EXATs_we_should_set = NULL; // EXtended ATtributes 1283 long long biggie_size; 1284 FILE *fbw = NULL; 1285 1286 malloc_string(tmp); 1287 malloc_string(biggie_fname); 1288 malloc_string(biggie_cksum); 1289 malloc_string(pathname_of_last_biggie_restored); 1290 assert(bkpinfo != NULL); 1291 1292 read_cfg_var(g_mondo_cfg_file, "total-slices", tmp); 1293 1294 total_slices = atol(tmp); 1295 1296 if (g_getfattr) { 1297 mr_asprintf(xattr_fname, XATTR_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir); 1298 } 1299 if (g_getfacl) { 1300 mr_asprintf(acl_fname, ACL_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir); 1301 } 1302 mr_asprintf(tmp1, "Reassembling large files "); 1303 mvaddstr_and_log_it(g_currentY, 0, tmp1); 1304 mr_free(tmp1); 1305 1306 mr_asprintf(biggies_whose_EXATs_we_should_set, "%s/biggies-whose-EXATs-we-should-set", bkpinfo->tmpdir); 1307 if (!(fbw = fopen(biggies_whose_EXATs_we_should_set, "w"))) { 1308 log_msg(1, "Warning - cannot openout %s", biggies_whose_EXATs_we_should_set); 1309 } 1310 1311 // get xattr and acl files if they're there 1312 res = read_header_block_from_stream(&biggie_size, biggie_fname, &ctrl_chr); 1313 if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) { 1314 res = read_EXAT_files_from_tape(&biggie_size, biggie_fname, &ctrl_chr, xattr_fname, acl_fname); 1315 } 1316 1317 noof_biggiefiles = atol(biggie_fname); 1318 log_msg(2, "OK, there are %ld biggiefiles in the archives", noof_biggiefiles); 1319 open_progress_form("Reassembling large files", 1320 "I am now reassembling all the large files.", 1321 "Please wait. This may take some time.", 1322 "", total_slices); 1323 1324 for (res = 1325 read_header_block_from_stream(&biggie_size, biggie_fname, 1326 &ctrl_chr); 1327 ctrl_chr != BLK_STOP_BIGGIEFILES; 1328 res = 1329 read_header_block_from_stream(&biggie_size, biggie_fname, 1330 &ctrl_chr)) { 1331 if (ctrl_chr != BLK_START_A_NORMBIGGIE 1332 && ctrl_chr != BLK_START_A_PIHBIGGIE) { 1333 wrong_marker(BLK_START_A_NORMBIGGIE, ctrl_chr); 1334 } 1335 p = strrchr(biggie_fname, '/'); 1336 if (!p) { 1337 p = biggie_fname; 1338 } else { 1339 p++; 1340 } 1341 mr_asprintf(tmp1, "Restoring big file %ld (%lld K)", current_bigfile_number + 1, biggie_size / 1024); 1342 update_progress_form(tmp1); 1343 mr_free(tmp1); 1344 res = restore_a_biggiefile_from_stream(biggie_fname, 1345 current_bigfile_number, 1346 biggie_cksum, 1347 biggie_size, 1348 filelist, ctrl_chr, 1349 pathname_of_last_biggie_restored); 1350 log_msg(1, "I believe I have restored %s", 1351 pathname_of_last_biggie_restored); 1352 if (fbw && pathname_of_last_biggie_restored[0]) { 1353 fprintf(fbw, "%s\n", pathname_of_last_biggie_restored); 1354 } 1355 retval += res; 1356 current_bigfile_number++; 1357 1358 } 1359 if (current_bigfile_number != noof_biggiefiles 1360 && noof_biggiefiles != 0) { 1361 log_msg(1, "Warning - bigfileno=%ld but noof_biggiefiles=%ld\n", current_bigfile_number, noof_biggiefiles); 1362 } else { 1363 log_msg(1, "%ld biggiefiles in biggielist.txt; %ld biggiefiles processed today.", noof_biggiefiles, current_bigfile_number); 1364 } 1365 1366 if (fbw) { 1367 fclose(fbw); 1368 if (length_of_file(biggies_whose_EXATs_we_should_set) > 2) { 1369 log_it("Setting biggie-EXATs"); 1370 if (g_getfattr) { 1371 if (length_of_file(xattr_fname) > 0) { 1372 log_msg(1, "set_fattr_List(%s,%s)", biggies_whose_EXATs_we_should_set, xattr_fname); 1373 set_fattr_list(biggies_whose_EXATs_we_should_set, xattr_fname); 1374 } 1375 } 1376 if (g_getfacl) { 1377 if (length_of_file(acl_fname) > 0) { 1378 log_msg(1, "set_acl_list(%s,%s)", biggies_whose_EXATs_we_should_set, acl_fname); 1379 set_acl_list(biggies_whose_EXATs_we_should_set, acl_fname); 1380 } 1381 } 1382 } else { 1383 log_it("No biggiefiles selected. So, no biggie-EXATs to set."); 1384 } 1385 } 1386 mr_free(xattr_fname); 1387 mr_free(acl_fname); 1388 mr_free(biggies_whose_EXATs_we_should_set); 1389 1390 if (does_file_exist("/PAUSE")) { 1391 popup_and_OK 1392 ("Press ENTER to go on. Delete /PAUSE to stop these pauses."); 1393 } 1394 1395 close_progress_form(); 1396 if (retval) { 1397 mvaddstr_and_log_it(g_currentY++, 74, "Errors."); 1398 } else { 1399 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 1400 } 1401 paranoid_free(pathname_of_last_biggie_restored); 1402 paranoid_free(biggie_fname); 1403 paranoid_free(biggie_cksum); 1404 paranoid_free(tmp); 1405 return (retval); 1406 } 1407 1408 /************************************************************************** 1409 *END_RESTORE_ALL_BIGGIEFILES_FROM_STREAM * 1410 **************************************************************************/ 1411 1412 1413 1414 1415 /** 1416 * Restore a tarball from the currently opened stream. 1417 * @param bkpinfo The backup information structure. Fields used: 1418 * - @c bkpinfo->backup_media_type 1419 * - @c bkpinfo->media_device 1420 * - @c bkpinfo->zip_exe 1421 * @param tarball_fname The filename of the afioball to restore. 1422 * @param current_tarball_number The number (starting from 0) of the fileset 1423 * we're restoring now. 1424 * @param filelist The node structure containing the list of files to be 1425 * restored. If no file in the afioball is in this list, afio will still be 1426 * called, but nothing will be written. 1427 * @param size The size (in @b bytes) of the afioball. 1428 * @return 0 for success, nonzero for failure. 1429 */ 1430 int 1431 restore_a_tarball_from_stream(char *tarball_fname, 1432 long current_tarball_number, 1433 struct s_node *filelist, 1434 long long size, char *xattr_fname, 1435 char *acl_fname) 1436 { 1437 int retval = 0; 1438 int res = 0; 1439 1440 /** malloc add ***/ 1441 char *mds = NULL; 1442 char *command = NULL; 1443 char *afio_fname = NULL; 1444 char *filelist_fname = NULL; 1445 char *filelist_subset_fname = NULL; 1446 char *executable = NULL; 1447 long matches = 0; 1448 bool restore_this_fileset = FALSE; 1449 bool use_star; 1450 1451 assert(bkpinfo != NULL); 1452 assert_string_is_neither_NULL_nor_zerolength(tarball_fname); 1453 1454 /* to do it with a file... */ 1455 use_star = (strstr(tarball_fname, ".star")) ? TRUE : FALSE; 1456 mds = media_descriptor_string(bkpinfo->backup_media_type); 1457 log_msg(2, "Restoring from fileset #%ld (%ld KB) on %s #%d", 1458 current_tarball_number, (long) size >> 10, mds, g_current_media_number); 1459 mr_free(mds); 1460 1461 run_program_and_log_output("mkdir -p " MNT_RESTORING "/tmp", FALSE); 1462 1463 /**************************************************************************** 1464 * Use RAMDISK's /tmp; saves time; oh wait, it's too small * 1465 * Well, pipe from tape to afio, then; oh wait, can't do that either: bug * 1466 * in afio or someting; oh darn.. OK, use tmpfs :-) * 1467 ****************************************************************************/ 1468 mr_asprintf(afio_fname, "/tmp/tmpfs/archive.tmp.%ld", current_tarball_number); 1469 mr_asprintf(filelist_fname, "%s/filelist.%ld", bkpinfo->tmpdir, current_tarball_number); 1470 mr_asprintf(filelist_subset_fname, "%s/filelist-subset-%ld.tmp", bkpinfo->tmpdir, current_tarball_number); 1471 1472 res = read_file_from_stream_to_file(afio_fname, size); 1473 if (strstr(tarball_fname, ".star")) { 1474 bkpinfo->use_star = TRUE; 1475 } 1476 if (res) { 1477 log_msg(1, "Warning - error reading afioball from tape"); 1478 } 1479 if (bkpinfo->compression_level == 0) { 1480 mr_asprintf(executable, "%s", ""); 1481 } else { 1482 if (bkpinfo->use_star) { 1483 mr_asprintf(executable, "%s", " -bz"); 1484 } else { 1485 mr_asprintf(executable, "-P %s -Z", bkpinfo->zip_exe); 1486 } 1487 } 1488 1489 if (!filelist) // if unconditional restore then restore entire fileset 1490 { 1491 restore_this_fileset = TRUE; 1492 } else // If restoring selectively then get TOC from tarball 1493 { 1494 if (strstr(tarball_fname, ".star.")) { 1495 use_star = TRUE; 1496 mr_asprintf(command, "star -sparse -t file=%s %s", afio_fname, executable); 1497 } else { 1498 use_star = FALSE; 1499 mr_asprintf(command, "afio -t -M 8m -b %ld %s %s", TAPE_BLOCK_SIZE, executable, afio_fname); 1500 } 1501 mr_strcat(command, " > %s 2>> %s", filelist_fname, MONDO_LOGFILE); 1502 log_msg(1, "command = %s", command); 1503 if (system(command)) { 1504 log_msg(4, "Warning - error occurred while retrieving TOC"); 1505 } 1506 mr_free(command); 1507 1508 if ((matches = 1509 save_filelist_entries_in_common(filelist_fname, filelist, 1510 filelist_subset_fname, 1511 use_star)) 1512 <= 0 || length_of_file(filelist_subset_fname) < 2) { 1513 if (length_of_file(filelist_subset_fname) < 2) { 1514 log_msg(1, "No matches found in fileset %ld", 1515 current_tarball_number); 1516 } 1517 log_msg(2, "Skipping fileset %ld", current_tarball_number); 1518 restore_this_fileset = FALSE; 1519 } else { 1520 log_msg(5, "%ld matches. Saved fileset %ld's subset to %s", 1521 matches, current_tarball_number, 1522 filelist_subset_fname); 1523 restore_this_fileset = TRUE; 1524 } 1525 } 1526 1527 // Concoct the call to star/afio to restore files 1528 if (strstr(tarball_fname, ".star.")) { 1529 // star 1530 mr_asprintf(command, "star -sparse -x file=%s %s", afio_fname, executable); 1531 if (filelist) { 1532 mr_strcat(command, " list=%s", filelist_subset_fname); 1533 } 1534 } else { 1535 // afio 1536 mr_asprintf(command, "afio -i -M 8m -b %ld %s", TAPE_BLOCK_SIZE, executable); 1537 if (filelist) { 1538 mr_strcat(command, " -w %s", filelist_subset_fname); 1539 } 1540 mr_strcat(command, " %s", afio_fname); 1541 } 1542 mr_strcat(command, " 2>> %s", MONDO_LOGFILE); 1543 mr_free(executable); 1544 1545 // Call if IF there are files to restore (selectively/unconditionally) 1546 if (restore_this_fileset) { 1547 log_msg(1, "Calling command='%s'", command); 1548 paranoid_system(command); 1549 1550 if (g_getfattr) { 1551 log_it("Restoring xattr stuff"); 1552 res = set_fattr_list(filelist_subset_fname, xattr_fname); 1553 if (res) { 1554 log_msg(1, "Errors occurred while setting xattr"); 1555 } else { 1556 log_msg(1, "I set xattr OK"); 1557 } 1558 retval += res; 1559 } 1560 1561 if (g_getfacl) { 1562 log_it("Restoring acl stuff"); 1563 res = set_acl_list(filelist_subset_fname, acl_fname); 1564 if (res) { 1565 log_msg(1, "Errors occurred while setting ACL"); 1566 } else { 1567 log_msg(1, "I set ACL OK"); 1568 } 1569 retval += res; 1570 } 1571 1572 } else { 1573 log_msg(1, "NOT CALLING '%s'", command); 1574 } 1575 mr_free(command); 1576 1577 if (does_file_exist("/PAUSE") && current_tarball_number >= 50) { 1578 log_to_screen("Paused after set %ld", current_tarball_number); 1579 popup_and_OK("Pausing. Press ENTER to continue."); 1580 } 1581 1582 unlink(filelist_subset_fname); 1583 mr_free(filelist_subset_fname); 1584 unlink(filelist_fname); 1585 mr_free(filelist_fname); 1586 unlink(afio_fname); 1587 mr_free(afio_fname); 1588 1589 return (retval); 1590 } 1591 1592 /************************************************************************** 1593 *END_RESTORE_A_TARBALL_FROM_STREAM * 1594 **************************************************************************/ 1595 1596 1597 1598 1599 1600 /** 1601 * Restore all afioballs from the currently opened tape stream. 1602 * @param bkpinfo The backup information structure. Fields used: 1603 * - @c bkpinfo->backup_media_type 1604 * - @c bkpinfo->restore_path 1605 * @param filelist The node structure containing the list of files to be 1606 * restored. If no file in an afioball is in this list, afio will still be 1607 * called for that fileset, but nothing will be written. 1608 * @return 0 for success, or the number of filesets that failed. 1609 */ 1610 int restore_all_tarballs_from_stream(struct s_node *filelist) 1611 { 1612 int retval = 0; 1613 int res; 1614 long current_afioball_number = 0; 1615 int ctrl_chr; 1616 long max_val /*, total_noof_files */ ; 1617 1618 /** malloc **/ 1619 char *tmp = NULL; 1620 char *mds = NULL; 1621 char *progress_str = NULL; 1622 char *tmp_fname; 1623 char *xattr_fname = NULL; 1624 char *acl_fname = NULL; 1625 1626 long long tmp_size; 1627 1628 malloc_string(tmp); 1629 malloc_string(tmp_fname); 1630 assert(bkpinfo != NULL); 1631 mvaddstr_and_log_it(g_currentY, 0, "Restoring from archives"); 1632 read_cfg_var(g_mondo_cfg_file, "last-filelist-number", tmp); 1633 max_val = atol(tmp) + 1; 1634 1635 if (chdir(bkpinfo->restore_path)) { /* I don't know why this is needed _here_ but it seems to be. -HR, 02/04/2002 */ 1636 //FIXME 1637 } 1638 1639 run_program_and_log_output("pwd", 5); 1640 1641 mr_asprintf(progress_str, "Restoring from media #%d", g_current_media_number); 1642 log_to_screen(progress_str); 1643 open_progress_form("Restoring from archives", 1644 "Restoring data from the archives.", 1645 "Please wait. This may take some time.", 1646 progress_str, max_val); 1647 1648 log_msg(3, "hey"); 1649 1650 res = read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr); 1651 if (res) { 1652 log_msg(2, "Warning - error reading afioball from tape"); 1653 } 1654 retval += res; 1655 if (ctrl_chr != BLK_START_AFIOBALLS) { 1656 wrong_marker(BLK_START_AFIOBALLS, ctrl_chr); 1657 } 1658 log_msg(2, "ho"); 1659 res = read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr); 1660 while (ctrl_chr != BLK_STOP_AFIOBALLS) { 1661 update_progress_form(progress_str); 1662 if (g_getfattr) { 1663 mr_asprintf(xattr_fname, "%s/xattr-subset-%ld.tmp", bkpinfo->tmpdir, current_afioball_number); 1664 unlink(xattr_fname); 1665 } 1666 if (g_getfacl) { 1667 mr_asprintf(acl_fname, "%s/acl-subset-%ld.tmp", bkpinfo->tmpdir, current_afioball_number); 1668 unlink(acl_fname); 1669 } 1670 if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) { 1671 log_it("Reading EXAT files from tape"); 1672 res = read_EXAT_files_from_tape(&tmp_size, tmp_fname, &ctrl_chr, xattr_fname, acl_fname); 1673 } 1674 if (ctrl_chr != BLK_START_AN_AFIO_OR_SLICE) { 1675 wrong_marker(BLK_START_AN_AFIO_OR_SLICE, ctrl_chr); 1676 } 1677 log_msg(4, "Restoring from fileset #%ld (name=%s, size=%ld K)", current_afioball_number, tmp_fname, (long) tmp_size >> 10); 1678 res = restore_a_tarball_from_stream(tmp_fname, current_afioball_number, filelist, tmp_size, xattr_fname, acl_fname); 1679 retval += res; 1680 if (res) { 1681 log_to_screen("Fileset %ld - errors occurred", current_afioball_number); 1682 } 1683 res = 1684 read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr); 1685 if (ctrl_chr != BLK_STOP_AN_AFIO_OR_SLICE) { 1686 wrong_marker(BLK_STOP_AN_AFIO_OR_SLICE, ctrl_chr); 1687 } 1688 1689 current_afioball_number++; 1690 g_current_progress++; 1691 mds = media_descriptor_string(bkpinfo->backup_media_type), 1692 1693 mr_free(progress_str); 1694 mr_asprintf(progress_str, "Restoring from fileset #%ld on %s #%d", current_afioball_number, mds, g_current_media_number); 1695 mr_free(mds); 1696 res = read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr); 1697 if (g_getfattr) { 1698 unlink(xattr_fname); 1699 } 1700 if (g_getfacl) { 1701 unlink(acl_fname); 1702 } 1703 } // next 1704 mr_free(progress_str); 1705 if (g_getfattr) { 1706 mr_free(xattr_fname); 1707 } 1708 if (g_getfacl) { 1709 mr_free(acl_fname); 1710 } 1711 1712 log_msg(1, "All done with afioballs"); 1713 close_progress_form(); 1714 if (retval) { 1715 mvaddstr_and_log_it(g_currentY++, 74, "Errors."); 1716 } else { 1717 mvaddstr_and_log_it(g_currentY++, 74, "Done."); 1718 } 1719 paranoid_free(tmp); 1720 paranoid_free(tmp_fname); 1721 return (retval); 1722 } 1723 1724 /************************************************************************** 1725 *END_ RESTORE_ALL_TARBALLS_FROM_STREAM * 1726 **************************************************************************/ 1727 1728 /* @} - end of LLrestoreGroup */ 1729 1730 1731 /** 1732 * Restore all files in @p filelist. 1733 * @param bkpinfo The backup information structure. Most fields are used. 1734 * @param filelist The node structure containing the list of files to be 1735 * restored. 1736 * @return 0 for success, or the number of afioballs and biggiefiles that failed. 1737 * @ingroup restoreGroup 1738 */ 1739 int restore_everything(struct s_node *filelist) 1740 { 1741 int resA; 1742 int resB; 1743 1744 /** mallco ***/ 1745 char *cwd; 1746 char *newpath; 1747 char *tmp = NULL; 1748 assert(bkpinfo != NULL); 1749 1750 malloc_string(cwd); 1751 malloc_string(newpath); 1752 log_msg(2, "restore_everything() --- starting"); 1753 g_current_media_number = 1; 1754 if (getcwd(cwd, MAX_STR_LEN - 1)) { 1755 // FIXME 1756 } 1757 mr_asprintf(tmp, "mkdir -p %s", bkpinfo->restore_path); 1758 run_program_and_log_output(tmp, FALSE); 1759 mr_free(tmp); 1760 1761 log_msg(1, "Changing dir to %s", bkpinfo->restore_path); 1762 if (chdir(bkpinfo->restore_path)) { 1763 //FIXME 1764 } 1765 if (getcwd(newpath, MAX_STR_LEN - 1)) { 1766 // FIXME 1767 } 1768 log_msg(1, "path is now %s", newpath); 1769 log_msg(1, "restoring everything"); 1770 if (!find_home_of_exe("petris") && !g_text_mode) { 1771 newtDrawRootText(0, g_noof_rows - 2, 1772 "Press ALT-<left cursor> twice to play Petris :-) "); 1773 newtRefresh(); 1774 } 1775 mvaddstr_and_log_it(g_currentY, 0, "Preparing to read your archives"); 1776 mount_media(); 1777 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) { 1778 mvaddstr_and_log_it(g_currentY++, 0, 1779 "Restoring OS and data from streaming media"); 1780 if (bkpinfo->backup_media_type == cdstream) { 1781 openin_cdstream(); 1782 } else { 1783 assert_string_is_neither_NULL_nor_zerolength(bkpinfo->media_device); 1784 openin_tape(); 1785 } 1786 resA = restore_all_tarballs_from_stream(filelist); 1787 resB = restore_all_biggiefiles_from_stream(filelist); 1788 if (bkpinfo->backup_media_type == cdstream) { 1789 closein_cdstream(); 1790 } else { 1791 closein_tape(); 1792 } 1793 } else { 1794 mvaddstr_and_log_it(g_currentY++, 0, 1795 "Restoring OS and data from CD/USB "); 1796 resA = restore_all_tarballs_from_CD(filelist); 1797 resB = restore_all_biggiefiles_from_CD(filelist); 1798 } 1799 if (chdir(cwd)) { 1800 //FIXME 1801 } 1802 if (resA + resB) { 1803 log_to_screen("Errors occurred while data was being restored."); 1804 } 1805 if (length_of_file("/etc/raidtab") > 0) { 1806 log_msg(2, "Copying local raidtab to restored filesystem"); 1807 run_program_and_log_output("cp -f /etc/raidtab " MNT_RESTORING 1808 "/etc/raidtab", FALSE); 1809 } 1810 kill_petris(); 1811 log_msg(2, "restore_everything() --- leaving"); 1812 paranoid_free(cwd); 1813 paranoid_free(newpath); 1814 return (resA + resB); 1815 } 1816 1817 /************************************************************************** 1818 *END_RESTORE_EVERYTHING * 1819 **************************************************************************/ 404 1820 405 1821 … … 661 2077 662 2078 /** 663 * Run an arbitrary restore mode (prompt the user), but from ISO images664 * instead of real media.665 * @param mountlist The mountlist containing information about the user's partitions.666 * @param raidlist The raidlist that goes with @p mountlist.667 * @param nuke_me_please If TRUE, we plan to run Nuke Mode.668 * @return 0 for success, or the number of errors encountered.669 */670 int671 iso_mode(struct mountlist_itself *mountlist,672 struct raidlist_itself *raidlist, bool nuke_me_please)673 {674 char c;675 int retval = 0;676 677 assert(mountlist != NULL);678 assert(raidlist != NULL);679 if (iso_fiddly_bits(nuke_me_please)) {680 log_msg(1, "iso_mode --- returning w/ error");681 return (1);682 } else {683 c = which_restore_mode();684 if (c == 'I' || c == 'N' || c == 'C') {685 interactively_obtain_media_parameters_from_user(FALSE);686 }687 if (c == 'I') {688 retval += interactive_mode(mountlist, raidlist);689 } else if (c == 'N') {690 retval += nuke_mode(mountlist, raidlist);691 } else if (c == 'C') {692 retval += compare_mode(mountlist, raidlist);693 } else {694 log_to_screen("OK, I shan't restore/compare any files.");695 }696 }697 if (is_this_device_mounted(MNT_CDROM)) {698 paranoid_system("umount -d " MNT_CDROM);699 }700 // if (! already_mounted)701 // {702 if (system("umount -d /tmp/isodir 2> /dev/null")) {703 log_to_screen("WARNING - unable to unmount device where the ISO files are stored.");704 }705 // }706 return (retval);707 }708 709 /**************************************************************************710 *END_ISO_MODE *711 **************************************************************************/712 713 714 /* MONDO - saving your systems since Feb 18th, 2000 */715 716 717 718 719 /**720 2079 * Restore the user's data automatically (no prompts), after a twenty-second 721 2080 * warning period. … … 870 2229 871 2230 /** 2231 * Allow the user to modify the mountlist before we partition & format their drives. 2232 * @param bkpinfo The backup information structure. @c disaster_recovery is the only field used. 2233 * @param mountlist The mountlist to let the user modify. 2234 * @param raidlist The raidlist that goes with @p mountlist. 2235 * @return 0 for success, nonzero for failure. 2236 * @ingroup restoreGuiGroup 2237 */ 2238 int let_user_edit_the_mountlist(struct mountlist_itself *mountlist, 2239 struct raidlist_itself *raidlist) 2240 { 2241 int retval = 0, res = 0; 2242 2243 log_msg(2, "let_user_edit_the_mountlist() --- starting"); 2244 2245 assert(bkpinfo != NULL); 2246 assert(mountlist != NULL); 2247 assert(raidlist != NULL); 2248 if (!bkpinfo->disaster_recovery) { 2249 strcpy(g_mountlist_fname, "/tmp/mountlist.txt"); 2250 log_msg(2, "I guess you're testing edit_mountlist()"); 2251 } 2252 if (!does_file_exist(g_mountlist_fname)) { 2253 log_to_screen(g_mountlist_fname); 2254 log_to_screen("does not exist"); 2255 return (1); 2256 } 2257 2258 retval = load_mountlist(mountlist, g_mountlist_fname); 2259 load_raidtab_into_raidlist(raidlist, RAIDTAB_FNAME); 2260 if (retval) { 2261 log_to_screen 2262 ("Warning - load_raidtab_into_raidlist returned an error"); 2263 } 2264 res = edit_mountlist(g_mountlist_fname, mountlist, raidlist); 2265 if (res) { 2266 return (1); 2267 } 2268 2269 save_mountlist_to_disk(mountlist, g_mountlist_fname); 2270 save_raidlist_to_raidtab(raidlist, RAIDTAB_FNAME); 2271 2272 log_to_screen("I have finished editing the mountlist for you."); 2273 2274 return (retval); 2275 } 2276 2277 2278 2279 2280 2281 /** 2282 * Call interactive_mode(), nuke_mode(), or compare_mode() depending on the user's choice. 2283 * @param bkpinfo The backup information structure. Most fields are used. 2284 * @param mountlist The mountlist containing information about the user's partitions. 2285 * @param raidlist The raidlist to go with @p mountlist. 2286 * @return The return code from the mode function called. 2287 * @ingroup restoreGroup 2288 */ 2289 int 2290 catchall_mode(struct mountlist_itself *mountlist, 2291 struct raidlist_itself *raidlist) 2292 { 2293 char c; 2294 char *tmp = NULL; 2295 int retval = 0; 2296 2297 log_it("inside catchall"); 2298 assert(bkpinfo != NULL); 2299 assert(mountlist != NULL); 2300 assert(raidlist != NULL); 2301 log_it("pre wrm"); 2302 c = which_restore_mode(); 2303 log_it("post wrm"); 2304 if (c == 'I' || c == 'C') { 2305 interactively_obtain_media_parameters_from_user(FALSE); 2306 } else if (c == 'N') { 2307 // Auto mode nothing special to do 2308 } else { 2309 popup_and_OK("No restoring or comparing will take place today."); 2310 if (is_this_device_mounted("/mnt/cdrom")) { 2311 run_program_and_log_output("umount -d /mnt/cdrom", FALSE); 2312 } 2313 if (g_ISO_restore_mode) { 2314 mr_asprintf(tmp, "umount -d %s", bkpinfo->isodir); 2315 run_program_and_log_output(tmp, FALSE); 2316 mr_free(tmp); 2317 } 2318 paranoid_MR_finish(0); 2319 } 2320 2321 log_it("post int"); 2322 2323 if (bkpinfo->backup_media_type == iso) { 2324 if (iso_fiddly_bits((c == 'N') ? TRUE : FALSE)) { 2325 log_msg(2, 2326 "catchall_mode --- iso_fiddly_bits returned w/ error"); 2327 return (1); 2328 } else { 2329 log_msg(2, "catchall_mode --- iso_fiddly_bits ok"); 2330 } 2331 } 2332 2333 if (c == 'I') { 2334 log_msg(2, "IM selected"); 2335 retval += interactive_mode(mountlist, raidlist); 2336 } else if (c == 'N') { 2337 log_msg(2, "NM selected"); 2338 retval += nuke_mode(mountlist, raidlist); 2339 } else if (c == 'C') { 2340 log_msg(2, "CM selected"); 2341 retval += compare_mode(mountlist, raidlist); 2342 } 2343 return (retval); 2344 } 2345 2346 /************************************************************************** 2347 *END_CATCHALL_MODE * 2348 **************************************************************************/ 2349 2350 /************************************************************************** 2351 *END_ EXTRACT_CONFIG_FILE_FROM_RAMDISK * 2352 **************************************************************************/ 2353 2354 2355 /** 2356 * Locate an executable in the directory structure rooted at @p restg. 2357 * @param out_path Where to put the executable. 2358 * @param fname The basename of the executable. 2359 * @param restg The directory structure to look in. 2360 * @note If it could not be found in @p restg then @p fname is put in @p out_path. 2361 * @ingroup restoreUtilityGroup 2362 */ 2363 void 2364 find_pathname_of_executable_preferably_in_RESTORING(char *out_path, 2365 char *fname, 2366 char *restg) 2367 { 2368 assert(out_path != NULL); 2369 assert_string_is_neither_NULL_nor_zerolength(fname); 2370 2371 sprintf(out_path, "%s/sbin/%s", restg, fname); 2372 if (does_file_exist(out_path)) { 2373 sprintf(out_path, "%s/usr/sbin/%s", restg, fname); 2374 if (does_file_exist(out_path)) { 2375 sprintf(out_path, "%s/bin/%s", restg, fname); 2376 if (does_file_exist(out_path)) { 2377 sprintf(out_path, "%s/usr/bin/%s", restg, fname); 2378 if (does_file_exist(out_path)) { 2379 strcpy(out_path, fname); 2380 } 2381 } 2382 } 2383 } 2384 } 2385 2386 /************************************************************************** 2387 *END_FIND_PATHNAME_OF_EXECUTABLE_PREFERABLY_IN_RESTORING * 2388 **************************************************************************/ 2389 2390 2391 /** 2392 * Run an arbitrary restore mode (prompt the user), but from ISO images 2393 * instead of real media. 2394 * @param mountlist The mountlist containing information about the user's partitions. 2395 * @param raidlist The raidlist that goes with @p mountlist. 2396 * @param nuke_me_please If TRUE, we plan to run Nuke Mode. 2397 * @return 0 for success, or the number of errors encountered. 2398 */ 2399 int 2400 iso_mode(struct mountlist_itself *mountlist, 2401 struct raidlist_itself *raidlist, bool nuke_me_please) 2402 { 2403 char c; 2404 int retval = 0; 2405 2406 assert(mountlist != NULL); 2407 assert(raidlist != NULL); 2408 if (iso_fiddly_bits(nuke_me_please)) { 2409 log_msg(1, "iso_mode --- returning w/ error"); 2410 return (1); 2411 } else { 2412 c = which_restore_mode(); 2413 if (c == 'I' || c == 'N' || c == 'C') { 2414 interactively_obtain_media_parameters_from_user(FALSE); 2415 } 2416 if (c == 'I') { 2417 retval += interactive_mode(mountlist, raidlist); 2418 } else if (c == 'N') { 2419 retval += nuke_mode(mountlist, raidlist); 2420 } else if (c == 'C') { 2421 retval += compare_mode(mountlist, raidlist); 2422 } else { 2423 log_to_screen("OK, I shan't restore/compare any files."); 2424 } 2425 } 2426 if (is_this_device_mounted(MNT_CDROM)) { 2427 paranoid_system("umount -d " MNT_CDROM); 2428 } 2429 // if (! already_mounted) 2430 // { 2431 if (system("umount -d /tmp/isodir 2> /dev/null")) { 2432 log_to_screen("WARNING - unable to unmount device where the ISO files are stored."); 2433 } 2434 // } 2435 return (retval); 2436 } 2437 2438 /************************************************************************** 2439 *END_ISO_MODE * 2440 **************************************************************************/ 2441 2442 2443 /* MONDO - saving your systems since Feb 18th, 2000 */ 2444 2445 2446 2447 /** 872 2448 * Restore the user's data (or a subset of it) to the live filesystem. 873 2449 * This should not be called if we're booted from CD! … … 959 2535 960 2536 /* @} - end of restoreGroup */ 961 962 963 #include <utime.h>964 /**965 * @addtogroup LLrestoreGroup966 * @{967 */968 969 /**970 * Restore biggiefile @p bigfileno from the currently mounted CD.971 * @param bkpinfo The backup information structure. Fields used:972 * - @c bkpinfo->backup_media_type973 * - @c bkpinfo->restore_path974 * @param bigfileno The biggiefile number (starting from 0) to restore.975 * @param filelist The node structure containing the list of files to restore.976 * If the biggiefile is not in this list, it will be skipped (return value will977 * still indicate success).978 * @return 0 for success (or skip), nonzero for failure.979 */980 int restore_a_biggiefile_from_CD(long bigfileno,981 struct s_node *filelist,982 char *pathname_of_last_file_restored)983 {984 FILE *fin;985 FILE *fout;986 FILE *fbzip2;987 988 /** malloc ***/989 char *checksum = NULL;990 char *outfile_fname = NULL;991 char *tmp = NULL;992 char *bzip2_command = NULL;993 char *suffix = NULL;994 char *sz_devfile = NULL;995 char *bigblk;996 char *mds = NULL;997 int retval = 0;998 int finished = FALSE;999 long sliceno;1000 long siz;1001 char *ntfsprog_fifo = NULL;1002 char *file_to_openout = NULL;1003 struct s_filename_and_lstat_info biggiestruct;1004 struct utimbuf the_utime_buf, *ubuf;1005 bool use_ntfsprog_hack = FALSE;1006 pid_t pid;1007 int res = 0;1008 int old_loglevel;1009 struct s_node *node;1010 1011 old_loglevel = g_loglevel;1012 ubuf = &the_utime_buf;1013 assert(bkpinfo != NULL);1014 1015 pathname_of_last_file_restored[0] = '\0';1016 if (!(bigblk = malloc(TAPE_BLOCK_SIZE))) {1017 fatal_error("Cannot malloc bigblk");1018 }1019 1020 if (!(fin = fopen(slice_fname(bigfileno, 0, ARCHIVES_PATH, ""), "r"))) {1021 log_to_screen("Cannot even open bigfile's info file");1022 return (1);1023 }1024 1025 memset((void *) &biggiestruct, 0, sizeof(biggiestruct));1026 if (fread((void *) &biggiestruct, 1, sizeof(biggiestruct), fin) <1027 sizeof(biggiestruct)) {1028 log_msg(2, "Warning - unable to get biggiestruct of bigfile #%d",1029 bigfileno + 1);1030 }1031 paranoid_fclose(fin);1032 1033 mr_asprintf(checksum, "%s", biggiestruct.checksum);1034 if (!checksum[0]) {1035 log_msg(3, "Warning - bigfile %ld does not have a checksum", bigfileno + 1);1036 }1037 mr_free(checksum);1038 1039 if (!strncmp(biggiestruct.filename, "/dev/", 5)) // Whether NTFS or not :)1040 {1041 mr_asprintf(outfile_fname, "%s", biggiestruct.filename);1042 } else {1043 mr_asprintf(outfile_fname, "%s/%s", bkpinfo->restore_path, biggiestruct.filename);1044 }1045 1046 /* skip file if we have a selective restore subset & it doesn't match */1047 if (filelist != NULL) {1048 node = find_string_at_node(filelist, biggiestruct.filename);1049 if (!node) {1050 log_msg(0, "Skipping %s (name isn't in filelist)", biggiestruct.filename);1051 pathname_of_last_file_restored[0] = '\0';1052 return (0);1053 } else if (!(node->selected)) {1054 log_msg(1, "Skipping %s (name isn't in biggielist subset)", biggiestruct.filename);1055 pathname_of_last_file_restored[0] = '\0';1056 return (0);1057 }1058 }1059 1060 /* otherwise, continue */1061 log_msg(1, "DEFINITELY restoring %s", biggiestruct.filename);1062 if (biggiestruct.use_ntfsprog) {1063 if (strncmp(biggiestruct.filename, "/dev/", 5)) {1064 log_msg(1, "I was in error when I set biggiestruct.use_ntfsprog to TRUE.");1065 log_msg(1, "%s isn't even in /dev", biggiestruct.filename);1066 biggiestruct.use_ntfsprog = FALSE;1067 }1068 }1069 1070 if (biggiestruct.use_ntfsprog) // if it's an NTFS device1071 {1072 g_loglevel = 4;1073 use_ntfsprog_hack = TRUE;1074 log_msg(2, "Calling ntfsclone in background because %s is an NTFS /dev entry", outfile_fname);1075 mr_asprintf(sz_devfile, "/tmp/%d.%d.000", (int) (random() % 32768), (int) (random() % 32768));1076 mkfifo(sz_devfile, 0x770);1077 mr_asprintf(ntfsprog_fifo, "%s", sz_devfile);1078 mr_free(sz_devfile);1079 file_to_openout = ntfsprog_fifo;1080 switch (pid = fork()) {1081 case -1:1082 fatal_error("Fork failure");1083 case 0:1084 log_msg(3, "CHILD - fip - calling feed_outfrom_ntfsprog(%s, %s)", biggiestruct.filename, ntfsprog_fifo);1085 res = feed_outfrom_ntfsprog(biggiestruct.filename, ntfsprog_fifo);1086 mr_free(ntfsprog_fifo);1087 exit(res);1088 break;1089 default:1090 log_msg(3, "feed_into_ntfsprog() called in background --- pid=%ld", (long int) (pid));1091 }1092 mr_free(ntfsprog_fifo);1093 } else {1094 use_ntfsprog_hack = FALSE;1095 file_to_openout = outfile_fname;1096 if (!does_file_exist(outfile_fname)) // yes, it looks weird with the '!' but it's correct that way1097 {1098 make_hole_for_file(outfile_fname);1099 }1100 }1101 1102 log_msg(2, "Reassembling big file %ld (%s)", bigfileno + 1, outfile_fname);1103 1104 /*1105 last slice is zero-length and uncompressed; when we find it, we stop.1106 We DON'T wait until there are no more slices; if we did that,1107 We might stop at end of CD, not at last slice (which is 0-len and uncompd)1108 */1109 1110 strncpy(pathname_of_last_file_restored, biggiestruct.filename, MAX_STR_LEN - 1);1111 pathname_of_last_file_restored[MAX_STR_LEN - 1] = '\0';1112 1113 log_msg(3, "file_to_openout = %s", file_to_openout);1114 if (!(fout = fopen(file_to_openout, "w"))) {1115 log_to_screen("Cannot openout outfile_fname - hard disk full?");1116 return (1);1117 }1118 log_msg(3, "Opened out to %s", outfile_fname); // CD/DVD --> mondorestore --> ntfsclone --> hard disk itself1119 1120 for (sliceno = 1, finished = FALSE; !finished;) {1121 if (!does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "")) &&1122 !does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "lzo")) &&1123 !does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "gz")) &&1124 !does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "lzma")) &&1125 !does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "bz2"))) {1126 log_msg(3, "Cannot find a data slice or terminator slice on CD %d", g_current_media_number);1127 g_current_media_number++;1128 mds = media_descriptor_string(bkpinfo->backup_media_type);1129 log_msg(2, "Asking for %s #%d so that I may read slice #%ld\n", mds, g_current_media_number, sliceno);1130 mr_free(mds);1131 1132 log_to_screen("Restoring from %s #%d", mds, g_current_media_number);1133 1134 insist_on_this_cd_number(g_current_media_number);1135 log_to_screen("Continuing to restore.");1136 } else {1137 mr_asprintf(tmp, "%s", slice_fname(bigfileno, sliceno, ARCHIVES_PATH, ""));1138 if (does_file_exist(tmp) && length_of_file(tmp) == 0) {1139 log_msg(2, "End of bigfile # %ld (slice %ld is the terminator)", bigfileno + 1, sliceno);1140 finished = TRUE;1141 mr_free(tmp);1142 continue;1143 } else {1144 if (does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "lzo"))) {1145 mr_asprintf(bzip2_command, "lzop");1146 mr_asprintf(suffix, "lzo");1147 } else1148 if (does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "gz"))) {1149 mr_asprintf(bzip2_command, "gzip");1150 mr_asprintf(suffix, "gz");1151 } else1152 if (does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "lzma"))) {1153 mr_asprintf(bzip2_command, "lzma");1154 mr_asprintf(suffix, "lzma");1155 } else1156 if (does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, "bz2"))) {1157 mr_asprintf(bzip2_command, "bzip2");1158 mr_asprintf(suffix, "bz2");1159 } else1160 if (does_file_exist(slice_fname(bigfileno, sliceno, ARCHIVES_PATH, ""))) {1161 mr_asprintf(bzip2_command, "");1162 mr_asprintf(suffix, "");1163 } else {1164 log_to_screen("OK, that's pretty fsck0red...");1165 mr_free(tmp);1166 return (1);1167 }1168 }1169 mr_free(tmp);1170 if (bzip2_command != NULL) {1171 mr_strcat(bzip2_command, " -dc %s 2>> %s", slice_fname(bigfileno, sliceno, ARCHIVES_PATH, suffix), MONDO_LOGFILE);1172 } else {1173 mr_asprintf(bzip2_command, "cat %s 2>> %s", slice_fname(bigfileno, sliceno, ARCHIVES_PATH, suffix), MONDO_LOGFILE);1174 }1175 mr_free(suffix);1176 1177 mds = media_descriptor_string(bkpinfo->backup_media_type);1178 mr_asprintf(tmp, "Working on %s #%d, file #%ld, slice #%ld ", mds, g_current_media_number, bigfileno + 1, sliceno);1179 mr_free(mds);1180 log_msg(2, tmp);1181 1182 if (!g_text_mode) {1183 newtDrawRootText(0, g_noof_rows - 2, tmp);1184 newtRefresh();1185 strip_spaces(tmp);1186 update_progress_form(tmp);1187 }1188 mr_free(tmp);1189 1190 if (!(fbzip2 = popen(bzip2_command, "r"))) {1191 fatal_error("Can't run popen command");1192 }1193 mr_free(bzip2_command);1194 1195 while (!feof(fbzip2)) {1196 siz = fread(bigblk, 1, TAPE_BLOCK_SIZE, fbzip2);1197 if (siz > 0) {1198 siz = fwrite(bigblk, 1, siz, fout);1199 }1200 }1201 paranoid_pclose(fbzip2);1202 1203 1204 sliceno++;1205 g_current_progress++;1206 }1207 }1208 paranoid_fclose(fout);1209 g_loglevel = old_loglevel;1210 1211 if (use_ntfsprog_hack) {1212 log_msg(3, "Waiting for ntfsclone to finish");1213 mr_asprintf(tmp, " ps | grep \" ntfsclone \" | grep -v grep > /dev/null 2> /dev/null");1214 while (system(tmp) == 0) {1215 sleep(1);1216 }1217 mr_free(tmp);1218 log_it("OK, ntfsclone has really finished");1219 }1220 1221 if (strcmp(outfile_fname, "/dev/null")) {1222 if (chown(outfile_fname, biggiestruct.properties.st_uid, biggiestruct.properties.st_gid)) {1223 // FIXME1224 }1225 chmod(outfile_fname, biggiestruct.properties.st_mode);1226 ubuf->actime = biggiestruct.properties.st_atime;1227 ubuf->modtime = biggiestruct.properties.st_mtime;1228 utime(outfile_fname, ubuf);1229 }1230 mr_free(outfile_fname);1231 paranoid_free(bigblk);1232 1233 return (retval);1234 }1235 1236 /**************************************************************************1237 *END_ RESTORE_A_BIGGIEFILE_FROM_CD *1238 **************************************************************************/1239 1240 1241 1242 /**1243 * Restore a biggiefile from the currently opened stream.1244 * @param bkpinfo The backup information structure. Fields used:1245 * - @c bkpinfo->restore_path1246 * - @c bkpinfo->zip_exe1247 * @param orig_bf_fname The original filename of the biggiefile.1248 * @param biggiefile_number The number of the biggiefile (starting from 0).1249 * @param orig_checksum Unused.1250 * @param biggiefile_size Unused.1251 * @param filelist The node structure containing the list of files to be restored.1252 * If @p orig_bf_fname is not in the list, it will be ignored.1253 * @return 0 for success (or skip), nonzero for failure.1254 * @bug orig_checksum and biggiefile_size are unused (except to check that they are non-NULL).1255 */1256 int restore_a_biggiefile_from_stream(char *orig_bf_fname, long biggiefile_number, char *orig_checksum, //UNUSED1257 long long biggiefile_size, //UNUSED1258 struct s_node *filelist,1259 int use_ntfsprog,1260 char *pathname_of_last_file_restored)1261 {1262 FILE *pout;1263 FILE *fin;1264 1265 /** mallocs ********/1266 char *tmp = NULL;1267 char *tmp1 = NULL;1268 char *command = NULL;1269 char *outfile_fname = NULL;1270 char *sz_devfile = NULL;1271 char *ntfsprog_fifo = NULL;1272 char *file_to_openout = NULL;1273 1274 struct s_node *node;1275 1276 int old_loglevel;1277 long current_slice_number = 0;1278 int retval = 0;1279 int res = 0;1280 int ctrl_chr = '\0';1281 long long slice_siz;1282 bool dummy_restore = FALSE;1283 bool use_ntfsprog_hack = FALSE;1284 pid_t pid;1285 struct s_filename_and_lstat_info biggiestruct;1286 struct utimbuf the_utime_buf, *ubuf;1287 ubuf = &the_utime_buf;1288 1289 malloc_string(tmp);1290 old_loglevel = g_loglevel;1291 assert(bkpinfo != NULL);1292 assert(orig_bf_fname != NULL);1293 assert(orig_checksum != NULL);1294 1295 pathname_of_last_file_restored[0] = '\0';1296 if (use_ntfsprog == BLK_START_A_PIHBIGGIE) {1297 use_ntfsprog = 1;1298 log_msg(1, "%s --- pih=YES", orig_bf_fname);1299 } else if (use_ntfsprog == BLK_START_A_NORMBIGGIE) {1300 use_ntfsprog = 0;1301 log_msg(1, "%s --- pih=NO", orig_bf_fname);1302 } else {1303 use_ntfsprog = 0;1304 log_msg(1, "%s --- pih=NO (weird marker though)", orig_bf_fname);1305 }1306 1307 strncpy(pathname_of_last_file_restored, orig_bf_fname,1308 MAX_STR_LEN - 1);1309 pathname_of_last_file_restored[MAX_STR_LEN - 1] = '\0';1310 1311 /* open out to biggiefile to be restored (or /dev/null if biggiefile is not to be restored) */1312 1313 if (filelist != NULL) {1314 node = find_string_at_node(filelist, orig_bf_fname);1315 if (!node) {1316 dummy_restore = TRUE;1317 log_msg(1,1318 "Skipping big file %ld (%s) - not in biggielist subset",1319 biggiefile_number + 1, orig_bf_fname);1320 pathname_of_last_file_restored[0] = '\0';1321 } else if (!(node->selected)) {1322 dummy_restore = TRUE;1323 log_msg(1, "Skipping %s (name isn't in biggielist subset)",1324 orig_bf_fname);1325 pathname_of_last_file_restored[0] = '\0';1326 }1327 }1328 1329 if (use_ntfsprog) {1330 if (strncmp(orig_bf_fname, "/dev/", 5)) {1331 log_msg(1,1332 "I was in error when I set use_ntfsprog to TRUE.");1333 log_msg(1, "%s isn't even in /dev", orig_bf_fname);1334 use_ntfsprog = FALSE;1335 }1336 }1337 1338 if (use_ntfsprog) {1339 g_loglevel = 4;1340 mr_asprintf(outfile_fname, "%s", orig_bf_fname);1341 use_ntfsprog_hack = TRUE;1342 log_msg(2, "Calling ntfsclone in background because %s is a /dev entry", outfile_fname);1343 mr_asprintf(sz_devfile, "%s/%d.%d.000", bkpinfo->tmpdir, (int) (random() % 32768), (int) (random() % 32768));1344 mkfifo(sz_devfile, 0x770);1345 mr_asprintf(ntfsprog_fifo, "%s", sz_devfile);1346 mr_free(sz_devfile);1347 1348 file_to_openout = ntfsprog_fifo;1349 switch (pid = fork()) {1350 case -1:1351 fatal_error("Fork failure");1352 case 0:1353 log_msg(3, "CHILD - fip - calling feed_outfrom_ntfsprog(%s, %s)", outfile_fname, ntfsprog_fifo);1354 res = feed_outfrom_ntfsprog(outfile_fname, ntfsprog_fifo);1355 mr_free(ntfsprog_fifo);1356 exit(res);1357 break;1358 default:1359 log_msg(3, "feed_into_ntfsprog() called in background --- pid=%ld", (long int) (pid));1360 }1361 mr_free(ntfsprog_fifo);1362 } else {1363 if (!strncmp(orig_bf_fname, "/dev/", 5)) {1364 // non-NTFS partition1365 mr_asprintf(outfile_fname, "%s", orig_bf_fname);1366 } else {1367 // biggiefile1368 mr_asprintf(outfile_fname, "%s/%s", bkpinfo->restore_path, orig_bf_fname);1369 }1370 use_ntfsprog_hack = FALSE;1371 file_to_openout = outfile_fname;1372 if (!does_file_exist(outfile_fname)) // yes, it looks weird with the '!' but it's correct that way1373 {1374 make_hole_for_file(outfile_fname);1375 }1376 log_msg(2, "Reassembling big file %ld (%s)", biggiefile_number + 1, orig_bf_fname);1377 }1378 1379 if (dummy_restore) {1380 mr_free(outfile_fname);1381 mr_asprintf(outfile_fname, "/dev/null");1382 }1383 1384 if (!bkpinfo->zip_exe[0]) {1385 mr_asprintf(command, "cat > \"%s\"", file_to_openout);1386 } else {1387 mr_asprintf(command, "%s -dc > \"%s\" 2>> %s", bkpinfo->zip_exe, file_to_openout, MONDO_LOGFILE);1388 if (strcmp(bkpinfo->zip_exe, "gzip") == 0) {1389 /* Ignore SIGPIPE for gzip as it causes errors on big files1390 * Cf: http://trac.mondorescue.org/ticket/244 */1391 signal(SIGPIPE,SIG_IGN);1392 }1393 }1394 log_msg(3, "Pipe command = '%s'", command);1395 1396 /* restore biggiefile, one slice at a time */1397 if (!(pout = popen(command, "w"))) {1398 fatal_error("Cannot pipe out");1399 }1400 mr_free(command);1401 1402 for (res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr);1403 ctrl_chr != BLK_STOP_A_BIGGIE;1404 res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr)) {1405 if (ctrl_chr != BLK_START_AN_AFIO_OR_SLICE) {1406 wrong_marker(BLK_START_AN_AFIO_OR_SLICE, ctrl_chr);1407 }1408 log_msg(2, "Working on file #%ld, slice #%ld ", biggiefile_number + 1, current_slice_number);1409 if (!g_text_mode) {1410 newtDrawRootText(0, g_noof_rows - 2, tmp);1411 newtRefresh();1412 }1413 strip_spaces(tmp);1414 update_progress_form(tmp);1415 if (current_slice_number == 0) {1416 res =1417 read_file_from_stream_to_file("/tmp/biggie-blah.txt",1418 slice_siz);1419 if (!(fin = fopen("/tmp/biggie-blah.txt", "r"))) {1420 log_OS_error("blah blah");1421 } else {1422 if (fread1423 ((void *) &biggiestruct, 1, sizeof(biggiestruct),1424 fin) < sizeof(biggiestruct)) {1425 log_msg(2,1426 "Warning - unable to get biggiestruct of bigfile #%d",1427 biggiefile_number + 1);1428 }1429 paranoid_fclose(fin);1430 }1431 } else {1432 res =1433 read_file_from_stream_to_stream(pout, slice_siz);1434 }1435 retval += res;1436 res = read_header_block_from_stream(&slice_siz, tmp, &ctrl_chr);1437 if (ctrl_chr != BLK_STOP_AN_AFIO_OR_SLICE) {1438 wrong_marker(BLK_STOP_AN_AFIO_OR_SLICE, ctrl_chr);1439 }1440 current_slice_number++;1441 g_current_progress++;1442 }1443 paranoid_pclose(pout);1444 1445 if (bkpinfo->zip_exe[0]) {1446 if (strcmp(bkpinfo->zip_exe, "gzip") == 0) {1447 /* Re-enable SIGPIPE for gzip */1448 signal(SIGPIPE, terminate_daemon);1449 }1450 }1451 1452 log_msg(1, "pathname_of_last_file_restored is now %s",1453 pathname_of_last_file_restored);1454 1455 if (use_ntfsprog_hack) {1456 log_msg(3, "Waiting for ntfsclone to finish");1457 mr_asprintf(tmp1, " ps | grep \" ntfsclone \" | grep -v grep > /dev/null 2> /dev/null");1458 while (system(tmp1) == 0) {1459 sleep(1);1460 }1461 mr_free(tmp1);1462 log_msg(3, "OK, ntfsclone has really finished");1463 }1464 1465 log_msg(3, "biggiestruct.filename = %s", biggiestruct.filename);1466 log_msg(3, "biggiestruct.checksum = %s", biggiestruct.checksum);1467 if (strcmp(outfile_fname, "/dev/null")) {1468 chmod(outfile_fname, biggiestruct.properties.st_mode);1469 if (chown(outfile_fname, biggiestruct.properties.st_uid, biggiestruct.properties.st_gid)) {1470 // FIXME1471 }1472 ubuf->actime = biggiestruct.properties.st_atime;1473 ubuf->modtime = biggiestruct.properties.st_mtime;1474 utime(outfile_fname, ubuf);1475 }1476 mr_free(outfile_fname);1477 1478 paranoid_free(tmp);1479 g_loglevel = old_loglevel;1480 return (retval);1481 }1482 1483 /**************************************************************************1484 *END_RESTORE_A_BIGGIEFILE_FROM_STREAM *1485 **************************************************************************/1486 1487 1488 1489 /**1490 * Restore @p tarball_fname from CD.1491 * @param tarball_fname The filename of the tarball to restore (in /mnt/cdrom).1492 * This will be used unmodified.1493 * @param current_tarball_number The number (starting from 0) of the fileset1494 * we're restoring now.1495 * @param filelist The node structure containing the list of files to be1496 * restored. If no file in the afioball is in this list, afio will still be1497 * called, but nothing will be written.1498 * @return 0 for success, nonzero for failure.1499 */1500 int1501 restore_a_tarball_from_CD(char *tarball_fname,1502 long current_tarball_number,1503 struct s_node *filelist)1504 {1505 int retval = 0;1506 int res;1507 char *p;1508 1509 /** malloc **/1510 char *command = NULL;1511 char *tmp = NULL;1512 char *filelist_name = NULL;1513 char *filelist_subset_fname = NULL;1514 char *executable = NULL;1515 char *temp_log = NULL;1516 long matches = 0;1517 bool use_star;1518 char *xattr_fname = NULL;1519 char *acl_fname = NULL;1520 1521 assert_string_is_neither_NULL_nor_zerolength(tarball_fname);1522 assert(bkpinfo != NULL);1523 1524 log_msg(5, "Entering");1525 use_star = (strstr(tarball_fname, ".star")) ? TRUE : FALSE;1526 mr_asprintf(command, "mkdir -p %s/tmp", MNT_RESTORING);1527 run_program_and_log_output(command, 9);1528 paranoid_free(command);1529 1530 mr_asprintf(filelist_name, MNT_CDROM "/archives/filelist.%ld", current_tarball_number);1531 if (length_of_file(filelist_name) <= 2) {1532 log_msg(2, "There are _zero_ files in filelist '%s'", filelist_name);1533 log_msg(2, "This is a bit silly (ask dev-team to fix mondo_makefilelist, please)");1534 log_msg(2, "but it's non-critical. It's cosmetic. Don't worry about it.");1535 retval = 0;1536 mr_free(filelist_name);1537 log_msg(5, "Leaving");1538 return(0);1539 }1540 if (count_lines_in_file(filelist_name) <= 0 || length_of_file(tarball_fname) <= 0) {1541 log_msg(3, "length_of_file(%s) = %llu", tarball_fname, length_of_file(tarball_fname));1542 log_msg(3, "count_lines_in_file(%s) = %llu", tarball_fname, count_lines_in_file(tarball_fname));1543 log_to_screen("Unable to restore fileset #%ld (CD I/O error)", current_tarball_number);1544 mr_free(filelist_name);1545 log_msg(5, "Leaving");1546 return(1);1547 }1548 1549 if (filelist) {1550 mr_asprintf(filelist_subset_fname, "/tmp/filelist-subset-%ld.tmp", current_tarball_number);1551 if ((matches =1552 save_filelist_entries_in_common(filelist_name, filelist,1553 filelist_subset_fname,1554 use_star)) <= 0) {1555 log_msg(1, "Skipping fileset %ld", current_tarball_number);1556 } else {1557 log_msg(3, "Saved fileset %ld's subset to %s", current_tarball_number, filelist_subset_fname);1558 }1559 log_to_screen("Tarball #%ld --- %ld matches", current_tarball_number, matches);1560 }1561 mr_free(filelist_name);1562 1563 if (filelist == NULL || matches > 0) {1564 if (g_getfattr) {1565 mr_asprintf(xattr_fname, XATTR_LIST_FNAME_RAW_SZ, MNT_CDROM "/archives", current_tarball_number);1566 }1567 if (g_getfacl) {1568 mr_asprintf(acl_fname, ACL_LIST_FNAME_RAW_SZ, MNT_CDROM "/archives", current_tarball_number);1569 }1570 if (strstr(tarball_fname, ".bz2")) {1571 mr_asprintf(executable, "bzip2");1572 } else if (strstr(tarball_fname, ".lzma")) {1573 mr_asprintf(executable, "lzma");1574 } else if (strstr(tarball_fname, ".gz")) {1575 mr_asprintf(executable, "gzip");1576 } else if (strstr(tarball_fname, ".lzo")) {1577 mr_asprintf(executable, "lzop");1578 }1579 if (bkpinfo->compression_level == 0) {1580 mr_asprintf(executable, "%s", "");1581 } else {1582 if (executable) {1583 mr_asprintf(tmp, "which %s > /dev/null 2> /dev/null", executable);1584 res = run_program_and_log_output(tmp, FALSE);1585 mr_free(tmp);1586 1587 if (res) {1588 log_to_screen("(compare_a_tarball) Compression program %s not found - oh no!", executable);1589 paranoid_MR_finish(1);1590 }1591 tmp = executable;1592 mr_asprintf(executable, "-P %s -Z", tmp);1593 mr_free(tmp);1594 }1595 }1596 #ifdef __FreeBSD__1597 #define BUFSIZE 5121598 #else1599 #define BUFSIZE (1024L*1024L)/TAPE_BLOCK_SIZE1600 #endif1601 1602 if (use_star) {1603 mr_asprintf(command, "star -x -force-remove -sparse -U " STAR_ACL_SZ " file=%s", tarball_fname);1604 if (strstr(tarball_fname, ".bz2")) {1605 mr_strcat(command, " -bz");1606 }1607 } else {1608 if (! executable) {1609 log_msg(2, "No executable, this shouldn't happen !");1610 } else {1611 if (filelist_subset_fname != NULL) {1612 mr_asprintf(command, "afio -i -M 8m -b %ld -c %ld %s -w '%s' %s", TAPE_BLOCK_SIZE, BUFSIZE, executable, filelist_subset_fname, tarball_fname);1613 } else {1614 mr_asprintf(command, "afio -i -b %ld -c %ld -M 8m %s %s", TAPE_BLOCK_SIZE, BUFSIZE, executable, tarball_fname);1615 }1616 }1617 }1618 mr_free(executable);1619 1620 #undef BUFSIZE1621 mr_asprintf(temp_log, "/tmp/%d.%d", (int) (random() % 32768), (int) (random() % 32768));1622 1623 mr_strcat(command, " 2>> %s >> %s", temp_log, temp_log);1624 log_msg(1, "command = '%s'", command);1625 unlink(temp_log);1626 res = system(command);1627 if (res) {1628 p = strstr(command, "-acl ");1629 if (p) {1630 p[0] = p[1] = p[2] = p[3] = ' ';1631 log_msg(1, "new command = '%s'", command);1632 res = system(command);1633 }1634 }1635 paranoid_free(command);1636 1637 if (res && length_of_file(temp_log) < 5) {1638 res = 0;1639 }1640 1641 if (! use_star) {1642 if (g_getfattr) {1643 log_msg(1, "Setting fattr list %s", xattr_fname);1644 if (length_of_file(xattr_fname) > 0) {1645 res = set_fattr_list(filelist_subset_fname, xattr_fname);1646 if (res) {1647 log_to_screen("Errors occurred while setting extended attributes");1648 } else {1649 log_msg(1, "I set xattr OK");1650 }1651 retval += res;1652 }1653 }1654 if (g_getfacl) {1655 log_msg(1, "Setting acl list %s", acl_fname);1656 if (length_of_file(acl_fname) > 0) {1657 res = set_acl_list(filelist_subset_fname, acl_fname);1658 if (res) {1659 log_to_screen("Errors occurred while setting access control lists");1660 } else {1661 log_msg(1, "I set ACL OK");1662 }1663 retval += res;1664 }1665 }1666 } else {1667 retval = res;1668 }1669 // Be verbose for star1670 if (retval || use_star) {1671 mr_asprintf(command, "cat %s >> %s", temp_log, MONDO_LOGFILE);1672 paranoid_system(command);1673 paranoid_free(command);1674 1675 if (retval) {1676 log_msg(2, "Errors occurred while processing fileset #%d", current_tarball_number);1677 }1678 } else {1679 log_msg(2, "Fileset #%d processed OK", current_tarball_number);1680 }1681 unlink(temp_log);1682 mr_free(temp_log);1683 }1684 if (does_file_exist("/PAUSE")) {1685 popup_and_OK1686 ("Press ENTER to go on. Delete /PAUSE to stop these pauses.");1687 }1688 unlink(filelist_subset_fname);1689 mr_free(filelist_subset_fname);1690 if (g_getfattr) {1691 unlink(xattr_fname);1692 mr_free(xattr_fname);1693 }1694 if (g_getfacl) {1695 unlink(acl_fname);1696 mr_free(acl_fname);1697 }1698 1699 log_msg(5, "Leaving");1700 return (retval);1701 }1702 1703 /**************************************************************************1704 *END_RESTORE_A_TARBALL_FROM_CD *1705 **************************************************************************/1706 1707 1708 /**1709 * Restore a tarball from the currently opened stream.1710 * @param bkpinfo The backup information structure. Fields used:1711 * - @c bkpinfo->backup_media_type1712 * - @c bkpinfo->media_device1713 * - @c bkpinfo->zip_exe1714 * @param tarball_fname The filename of the afioball to restore.1715 * @param current_tarball_number The number (starting from 0) of the fileset1716 * we're restoring now.1717 * @param filelist The node structure containing the list of files to be1718 * restored. If no file in the afioball is in this list, afio will still be1719 * called, but nothing will be written.1720 * @param size The size (in @b bytes) of the afioball.1721 * @return 0 for success, nonzero for failure.1722 */1723 int1724 restore_a_tarball_from_stream(char *tarball_fname,1725 long current_tarball_number,1726 struct s_node *filelist,1727 long long size, char *xattr_fname,1728 char *acl_fname)1729 {1730 int retval = 0;1731 int res = 0;1732 1733 /** malloc add ***/1734 char *mds = NULL;1735 char *command = NULL;1736 char *afio_fname = NULL;1737 char *filelist_fname = NULL;1738 char *filelist_subset_fname = NULL;1739 char *executable = NULL;1740 long matches = 0;1741 bool restore_this_fileset = FALSE;1742 bool use_star;1743 1744 assert(bkpinfo != NULL);1745 assert_string_is_neither_NULL_nor_zerolength(tarball_fname);1746 1747 /* to do it with a file... */1748 use_star = (strstr(tarball_fname, ".star")) ? TRUE : FALSE;1749 mds = media_descriptor_string(bkpinfo->backup_media_type);1750 log_msg(2, "Restoring from fileset #%ld (%ld KB) on %s #%d",1751 current_tarball_number, (long) size >> 10, mds, g_current_media_number);1752 mr_free(mds);1753 1754 run_program_and_log_output("mkdir -p " MNT_RESTORING "/tmp", FALSE);1755 1756 /****************************************************************************1757 * Use RAMDISK's /tmp; saves time; oh wait, it's too small *1758 * Well, pipe from tape to afio, then; oh wait, can't do that either: bug *1759 * in afio or someting; oh darn.. OK, use tmpfs :-) *1760 ****************************************************************************/1761 mr_asprintf(afio_fname, "/tmp/tmpfs/archive.tmp.%ld", current_tarball_number);1762 mr_asprintf(filelist_fname, "%s/filelist.%ld", bkpinfo->tmpdir, current_tarball_number);1763 mr_asprintf(filelist_subset_fname, "%s/filelist-subset-%ld.tmp", bkpinfo->tmpdir, current_tarball_number);1764 1765 res = read_file_from_stream_to_file(afio_fname, size);1766 if (strstr(tarball_fname, ".star")) {1767 bkpinfo->use_star = TRUE;1768 }1769 if (res) {1770 log_msg(1, "Warning - error reading afioball from tape");1771 }1772 if (bkpinfo->compression_level == 0) {1773 mr_asprintf(executable, "%s", "");1774 } else {1775 if (bkpinfo->use_star) {1776 mr_asprintf(executable, "%s", " -bz");1777 } else {1778 mr_asprintf(executable, "-P %s -Z", bkpinfo->zip_exe);1779 }1780 }1781 1782 if (!filelist) // if unconditional restore then restore entire fileset1783 {1784 restore_this_fileset = TRUE;1785 } else // If restoring selectively then get TOC from tarball1786 {1787 if (strstr(tarball_fname, ".star.")) {1788 use_star = TRUE;1789 mr_asprintf(command, "star -sparse -t file=%s %s", afio_fname, executable);1790 } else {1791 use_star = FALSE;1792 mr_asprintf(command, "afio -t -M 8m -b %ld %s %s", TAPE_BLOCK_SIZE, executable, afio_fname);1793 }1794 mr_strcat(command, " > %s 2>> %s", filelist_fname, MONDO_LOGFILE);1795 log_msg(1, "command = %s", command);1796 if (system(command)) {1797 log_msg(4, "Warning - error occurred while retrieving TOC");1798 }1799 mr_free(command);1800 1801 if ((matches =1802 save_filelist_entries_in_common(filelist_fname, filelist,1803 filelist_subset_fname,1804 use_star))1805 <= 0 || length_of_file(filelist_subset_fname) < 2) {1806 if (length_of_file(filelist_subset_fname) < 2) {1807 log_msg(1, "No matches found in fileset %ld",1808 current_tarball_number);1809 }1810 log_msg(2, "Skipping fileset %ld", current_tarball_number);1811 restore_this_fileset = FALSE;1812 } else {1813 log_msg(5, "%ld matches. Saved fileset %ld's subset to %s",1814 matches, current_tarball_number,1815 filelist_subset_fname);1816 restore_this_fileset = TRUE;1817 }1818 }1819 1820 // Concoct the call to star/afio to restore files1821 if (strstr(tarball_fname, ".star.")) {1822 // star1823 mr_asprintf(command, "star -sparse -x file=%s %s", afio_fname, executable);1824 if (filelist) {1825 mr_strcat(command, " list=%s", filelist_subset_fname);1826 }1827 } else {1828 // afio1829 mr_asprintf(command, "afio -i -M 8m -b %ld %s", TAPE_BLOCK_SIZE, executable);1830 if (filelist) {1831 mr_strcat(command, " -w %s", filelist_subset_fname);1832 }1833 mr_strcat(command, " %s", afio_fname);1834 }1835 mr_strcat(command, " 2>> %s", MONDO_LOGFILE);1836 mr_free(executable);1837 1838 // Call if IF there are files to restore (selectively/unconditionally)1839 if (restore_this_fileset) {1840 log_msg(1, "Calling command='%s'", command);1841 paranoid_system(command);1842 1843 if (g_getfattr) {1844 log_it("Restoring xattr stuff");1845 res = set_fattr_list(filelist_subset_fname, xattr_fname);1846 if (res) {1847 log_msg(1, "Errors occurred while setting xattr");1848 } else {1849 log_msg(1, "I set xattr OK");1850 }1851 retval += res;1852 }1853 1854 if (g_getfacl) {1855 log_it("Restoring acl stuff");1856 res = set_acl_list(filelist_subset_fname, acl_fname);1857 if (res) {1858 log_msg(1, "Errors occurred while setting ACL");1859 } else {1860 log_msg(1, "I set ACL OK");1861 }1862 retval += res;1863 }1864 1865 } else {1866 log_msg(1, "NOT CALLING '%s'", command);1867 }1868 mr_free(command);1869 1870 if (does_file_exist("/PAUSE") && current_tarball_number >= 50) {1871 log_to_screen("Paused after set %ld", current_tarball_number);1872 popup_and_OK("Pausing. Press ENTER to continue.");1873 }1874 1875 unlink(filelist_subset_fname);1876 mr_free(filelist_subset_fname);1877 unlink(filelist_fname);1878 mr_free(filelist_fname);1879 unlink(afio_fname);1880 mr_free(afio_fname);1881 1882 return (retval);1883 }1884 1885 /**************************************************************************1886 *END_RESTORE_A_TARBALL_FROM_STREAM *1887 **************************************************************************/1888 1889 1890 1891 1892 /**1893 * Restore all biggiefiles from all media in this CD backup.1894 * The CD with the last afioball should be currently mounted.1895 * @param bkpinfo The backup information structure. @c backup_media_type is the1896 * only field used in this function.1897 * @param filelist The node structure containing the list of files to be1898 * restored. If a prospective biggiefile is not in this list, it will be ignored.1899 * @return 0 for success, nonzero for failure.1900 */1901 int restore_all_biggiefiles_from_CD(struct s_node *filelist) {1902 1903 int retval = 0;1904 int res = 0;1905 long noof_biggiefiles, bigfileno = 0, total_slices;1906 /** malloc **/1907 char *tmp = NULL;1908 char *tmp1 = NULL;1909 char *mds = NULL;1910 bool just_changed_cds = FALSE;1911 char *xattr_fname = NULL;1912 char *acl_fname = NULL;1913 char *biggies_whose_EXATs_we_should_set = NULL; // EXtended ATtributes1914 char *pathname_of_last_biggie_restored;1915 FILE *fbw = NULL;1916 1917 malloc_string(pathname_of_last_biggie_restored);1918 malloc_string(tmp);1919 assert(bkpinfo != NULL);1920 1921 mr_asprintf(biggies_whose_EXATs_we_should_set, "%s/biggies-whose-EXATs-we-should-set", bkpinfo->tmpdir);1922 if (!(fbw = fopen(biggies_whose_EXATs_we_should_set, "w"))) {1923 log_msg(1, "Warning - cannot openout %s", biggies_whose_EXATs_we_should_set);1924 }1925 1926 read_cfg_var(g_mondo_cfg_file, "total-slices", tmp);1927 total_slices = atol(tmp);1928 mr_free(tmp);1929 1930 mr_asprintf(tmp1, "Reassembling large files ");1931 mvaddstr_and_log_it(g_currentY, 0, tmp1);1932 mr_free(tmp1);1933 1934 if (length_of_file(BIGGIELIST) < 6) {1935 log_msg(1, "OK, no biggielist; not restoring biggiefiles");1936 return (0);1937 }1938 noof_biggiefiles = count_lines_in_file(BIGGIELIST);1939 if (noof_biggiefiles <= 0) {1940 log_msg(2, "OK, no biggiefiles in biggielist; not restoring biggiefiles");1941 return (0);1942 }1943 log_msg(2, "OK, there are %ld biggiefiles in the archives", noof_biggiefiles);1944 1945 open_progress_form("Reassembling large files",1946 "I am now reassembling all the large files.",1947 "Please wait. This may take some time.",1948 "", total_slices);1949 for (bigfileno = 0 ; bigfileno < noof_biggiefiles ;) {1950 log_msg(2, "Thinking about restoring bigfile %ld", bigfileno + 1);1951 if (!does_file_exist(slice_fname(bigfileno, 0, ARCHIVES_PATH, ""))) {1952 log_msg(3, "...but its first slice isn't on this CD. Perhaps this was a selective restore?");1953 mds = media_descriptor_string(bkpinfo->backup_media_type);1954 log_msg(3, "Cannot find bigfile #%ld 's first slice on %s #%d", bigfileno + 1, mds, g_current_media_number);1955 log_msg(3, "Slicename would have been %s",1956 slice_fname(bigfileno, 0, ARCHIVES_PATH, ""));1957 // I'm not positive 'just_changed_cds' is even necessary...1958 if (just_changed_cds) {1959 just_changed_cds = FALSE;1960 log_msg(3, "I'll continue to scan this CD for bigfiles to be restored.");1961 } else if (does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST")) {1962 insist_on_this_cd_number(++g_current_media_number);1963 log_to_screen("Restoring from %s #%d", mds, g_current_media_number);1964 just_changed_cds = TRUE;1965 } else {1966 /* That big file doesn't exist, but the followings may */1967 /* So we need to continue looping */1968 log_msg(2, "There was no bigfile #%ld. That's OK.", bigfileno + 1);1969 log_msg(2, "I'm going to stop restoring bigfiles now.");1970 retval++;1971 bigfileno++;1972 }1973 mr_free(mds);1974 } else {1975 just_changed_cds = FALSE;1976 mr_asprintf(tmp1, "Restoring big file %ld", bigfileno + 1);1977 update_progress_form(tmp1);1978 mr_free(tmp1);1979 res = restore_a_biggiefile_from_CD(bigfileno, filelist, pathname_of_last_biggie_restored);1980 log_it("%s",pathname_of_last_biggie_restored);1981 if (fbw && pathname_of_last_biggie_restored[0]) {1982 fprintf(fbw, "%s\n", pathname_of_last_biggie_restored);1983 }1984 retval += res;1985 bigfileno++;1986 1987 }1988 }1989 1990 if (fbw) {1991 fclose(fbw);1992 if (g_getfattr) {1993 mr_asprintf(xattr_fname, XATTR_BIGGLST_FNAME_RAW_SZ, ARCHIVES_PATH);1994 if (length_of_file(xattr_fname) > 0) {1995 set_fattr_list(biggies_whose_EXATs_we_should_set, xattr_fname);1996 }1997 mr_free(xattr_fname);1998 }1999 if (g_getfacl) {2000 mr_asprintf(acl_fname, ACL_BIGGLST_FNAME_RAW_SZ, ARCHIVES_PATH);2001 if (length_of_file(acl_fname) > 0) {2002 set_acl_list(biggies_whose_EXATs_we_should_set, acl_fname);2003 }2004 mr_free(acl_fname);2005 }2006 }2007 mr_free(biggies_whose_EXATs_we_should_set);2008 2009 if (does_file_exist("/PAUSE")) {2010 popup_and_OK("Press ENTER to go on. Delete /PAUSE to stop these pauses.");2011 }2012 close_progress_form();2013 if (retval) {2014 mvaddstr_and_log_it(g_currentY++, 74, "Errors.");2015 } else {2016 mvaddstr_and_log_it(g_currentY++, 74, "Done.");2017 }2018 paranoid_free(pathname_of_last_biggie_restored);2019 return (retval);2020 }2021 2022 /**************************************************************************2023 *END_RESTORE_ALL_BIGGIFILES_FROM_CD *2024 **************************************************************************/2025 2026 2027 2028 /**2029 * Restore all afioballs from all CDs in the backup.2030 * The first CD should be inserted (if not, it will be asked for).2031 * @param bkpinfo The backup information structure. @c backup_media_type is the2032 * only field used in @e this function.2033 * @param filelist The node structure containing the list of files to be2034 * restored. If no file in some particular afioball is in this list, afio will2035 * still be called for that fileset, but nothing will be written.2036 * @return 0 for success, or the number of filesets that failed.2037 */2038 int2039 restore_all_tarballs_from_CD(struct s_node *filelist)2040 {2041 int retval = 0;2042 int res;2043 int attempts;2044 long current_tarball_number = 0L;2045 long max_val;2046 /**malloc ***/2047 char *mds = NULL;2048 char *tmp = NULL;2049 char *tmp1 = NULL;2050 char *tarball_fname = NULL;2051 char *progress_str = NULL;2052 2053 assert(bkpinfo != NULL);2054 2055 malloc_string(tmp);2056 mvaddstr_and_log_it(g_currentY, 0, "Restoring from archives");2057 log_msg(2, "Insisting on 1st media, so that I can have a look at LAST-FILELIST-NUMBER");2058 if (g_current_media_number != 1) {2059 log_msg(3, "OK, that's jacked up.");2060 g_current_media_number = 1;2061 }2062 insist_on_this_cd_number(g_current_media_number);2063 read_cfg_var(g_mondo_cfg_file, "last-filelist-number", tmp);2064 max_val = atol(tmp) + 1;2065 paranoid_free(tmp);2066 2067 mds = media_descriptor_string(bkpinfo->backup_media_type);2068 mr_asprintf(progress_str, "Restoring from %s #%d", mds, g_current_media_number);2069 2070 log_to_screen(progress_str);2071 open_progress_form("Restoring from archives",2072 "Restoring data from the archives.",2073 "Please wait. This may take some time.",2074 progress_str, max_val);2075 for (;;) {2076 insist_on_this_cd_number(g_current_media_number);2077 update_progress_form(progress_str);2078 mr_free(progress_str);2079 2080 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.bz2", current_tarball_number);2081 if (!does_file_exist(tarball_fname)) {2082 mr_free(tarball_fname);2083 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.gz", current_tarball_number);2084 }2085 if (!does_file_exist(tarball_fname)) {2086 mr_free(tarball_fname);2087 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.lzma", current_tarball_number);2088 }2089 if (!does_file_exist(tarball_fname)) {2090 mr_free(tarball_fname);2091 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.lzo", current_tarball_number);2092 }2093 if (!does_file_exist(tarball_fname)) {2094 mr_free(tarball_fname);2095 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.afio.", current_tarball_number);2096 }2097 if (!does_file_exist(tarball_fname)) {2098 mr_free(tarball_fname);2099 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.star.bz2", current_tarball_number);2100 }2101 if (!does_file_exist(tarball_fname)) {2102 mr_free(tarball_fname);2103 mr_asprintf(tarball_fname, MNT_CDROM "/archives/%ld.star.", current_tarball_number);2104 }2105 if (!does_file_exist(tarball_fname)) {2106 if (current_tarball_number == 0) {2107 log_to_screen2108 ("No tarballs. Strange. Maybe you only backed up freakin' big files?");2109 mr_free(tarball_fname);2110 return (0);2111 }2112 if (!does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST")2113 || system("find " MNT_CDROM2114 "/archives/slice* > /dev/null 2> /dev/null") ==2115 0) {2116 break;2117 }2118 g_current_media_number++;2119 mr_asprintf(progress_str, "Restoring from %s #%d", media_descriptor_string(bkpinfo->backup_media_type), g_current_media_number);2120 log_to_screen(progress_str);2121 } else {2122 mr_asprintf(progress_str, "Restoring from fileset #%ld on %s #%d", current_tarball_number, mds, g_current_media_number);2123 for (res = 999, attempts = 0; attempts < 3 && res != 0; attempts++) {2124 res = restore_a_tarball_from_CD(tarball_fname, current_tarball_number, filelist);2125 }2126 mr_asprintf(tmp1, "%s #%d, fileset #%ld - restore ", mds, g_current_media_number, current_tarball_number);2127 if (res) {2128 mr_strcat(tmp1, "reported errors");2129 } else if (attempts > 1) {2130 mr_strcat(tmp1, "succeeded");2131 } else {2132 mr_strcat(tmp1, "succeeded");2133 }2134 if (attempts > 1) {2135 mr_strcat(tmp1, " (%d attempts) - review logs", attempts);2136 }2137 if (attempts > 1) {2138 log_to_screen(tmp1);2139 }2140 mr_free(tmp1);2141 2142 retval += res;2143 current_tarball_number++;2144 g_current_progress++;2145 }2146 mr_free(tarball_fname);2147 2148 /* Now we need to umount the current media to have the next mounted by insist_on_this_cd_number */2149 /* run_program_and_log_output("umount " MNT_CDROM, FALSE); */2150 }2151 mr_free(mds);2152 mr_free(progress_str);2153 2154 close_progress_form();2155 if (retval) {2156 mvaddstr_and_log_it(g_currentY++, 74, "Errors.");2157 } else {2158 mvaddstr_and_log_it(g_currentY++, 74, "Done.");2159 }2160 2161 return (retval);2162 }2163 2164 /**************************************************************************2165 *END_RESTORE_ALL_TARBALLS_FROM_CD *2166 **************************************************************************/2167 2168 2169 2170 /**2171 * Restore all biggiefiles from the currently opened stream.2172 * @param bkpinfo The backup information structure. Passed to other functions.2173 * @param filelist The node structure containing the list of files to be2174 * restored. If a prospective biggiefile is not in the list, it will be ignored.2175 * @return 0 for success, or the number of biggiefiles that failed.2176 */2177 int2178 restore_all_biggiefiles_from_stream(struct s_node *filelist)2179 {2180 long noof_biggiefiles;2181 long current_bigfile_number = 0;2182 long total_slices;2183 2184 int retval = 0;2185 int res = 0;2186 int ctrl_chr;2187 2188 /** malloc add ****/2189 char *tmp = NULL;2190 char *tmp1 = NULL;2191 char *biggie_fname;2192 char *biggie_cksum;2193 char *xattr_fname = NULL;2194 char *acl_fname = NULL;2195 char *p;2196 char *pathname_of_last_biggie_restored;2197 char *biggies_whose_EXATs_we_should_set = NULL; // EXtended ATtributes2198 long long biggie_size;2199 FILE *fbw = NULL;2200 2201 malloc_string(tmp);2202 malloc_string(biggie_fname);2203 malloc_string(biggie_cksum);2204 malloc_string(pathname_of_last_biggie_restored);2205 assert(bkpinfo != NULL);2206 2207 read_cfg_var(g_mondo_cfg_file, "total-slices", tmp);2208 2209 total_slices = atol(tmp);2210 2211 if (g_getfattr) {2212 mr_asprintf(xattr_fname, XATTR_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir);2213 }2214 if (g_getfacl) {2215 mr_asprintf(acl_fname, ACL_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir);2216 }2217 mr_asprintf(tmp1, "Reassembling large files ");2218 mvaddstr_and_log_it(g_currentY, 0, tmp1);2219 mr_free(tmp1);2220 2221 mr_asprintf(biggies_whose_EXATs_we_should_set, "%s/biggies-whose-EXATs-we-should-set", bkpinfo->tmpdir);2222 if (!(fbw = fopen(biggies_whose_EXATs_we_should_set, "w"))) {2223 log_msg(1, "Warning - cannot openout %s", biggies_whose_EXATs_we_should_set);2224 }2225 2226 // get xattr and acl files if they're there2227 res = read_header_block_from_stream(&biggie_size, biggie_fname, &ctrl_chr);2228 if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) {2229 res = read_EXAT_files_from_tape(&biggie_size, biggie_fname, &ctrl_chr, xattr_fname, acl_fname);2230 }2231 2232 noof_biggiefiles = atol(biggie_fname);2233 log_msg(2, "OK, there are %ld biggiefiles in the archives", noof_biggiefiles);2234 open_progress_form("Reassembling large files",2235 "I am now reassembling all the large files.",2236 "Please wait. This may take some time.",2237 "", total_slices);2238 2239 for (res =2240 read_header_block_from_stream(&biggie_size, biggie_fname,2241 &ctrl_chr);2242 ctrl_chr != BLK_STOP_BIGGIEFILES;2243 res =2244 read_header_block_from_stream(&biggie_size, biggie_fname,2245 &ctrl_chr)) {2246 if (ctrl_chr != BLK_START_A_NORMBIGGIE2247 && ctrl_chr != BLK_START_A_PIHBIGGIE) {2248 wrong_marker(BLK_START_A_NORMBIGGIE, ctrl_chr);2249 }2250 p = strrchr(biggie_fname, '/');2251 if (!p) {2252 p = biggie_fname;2253 } else {2254 p++;2255 }2256 mr_asprintf(tmp1, "Restoring big file %ld (%lld K)", current_bigfile_number + 1, biggie_size / 1024);2257 update_progress_form(tmp1);2258 mr_free(tmp1);2259 res = restore_a_biggiefile_from_stream(biggie_fname,2260 current_bigfile_number,2261 biggie_cksum,2262 biggie_size,2263 filelist, ctrl_chr,2264 pathname_of_last_biggie_restored);2265 log_msg(1, "I believe I have restored %s",2266 pathname_of_last_biggie_restored);2267 if (fbw && pathname_of_last_biggie_restored[0]) {2268 fprintf(fbw, "%s\n", pathname_of_last_biggie_restored);2269 }2270 retval += res;2271 current_bigfile_number++;2272 2273 }2274 if (current_bigfile_number != noof_biggiefiles2275 && noof_biggiefiles != 0) {2276 log_msg(1, "Warning - bigfileno=%ld but noof_biggiefiles=%ld\n", current_bigfile_number, noof_biggiefiles);2277 } else {2278 log_msg(1, "%ld biggiefiles in biggielist.txt; %ld biggiefiles processed today.", noof_biggiefiles, current_bigfile_number);2279 }2280 2281 if (fbw) {2282 fclose(fbw);2283 if (length_of_file(biggies_whose_EXATs_we_should_set) > 2) {2284 log_it("Setting biggie-EXATs");2285 if (g_getfattr) {2286 if (length_of_file(xattr_fname) > 0) {2287 log_msg(1, "set_fattr_List(%s,%s)", biggies_whose_EXATs_we_should_set, xattr_fname);2288 set_fattr_list(biggies_whose_EXATs_we_should_set, xattr_fname);2289 }2290 }2291 if (g_getfacl) {2292 if (length_of_file(acl_fname) > 0) {2293 log_msg(1, "set_acl_list(%s,%s)", biggies_whose_EXATs_we_should_set, acl_fname);2294 set_acl_list(biggies_whose_EXATs_we_should_set, acl_fname);2295 }2296 }2297 } else {2298 log_it("No biggiefiles selected. So, no biggie-EXATs to set.");2299 }2300 }2301 mr_free(xattr_fname);2302 mr_free(acl_fname);2303 mr_free(biggies_whose_EXATs_we_should_set);2304 2305 if (does_file_exist("/PAUSE")) {2306 popup_and_OK2307 ("Press ENTER to go on. Delete /PAUSE to stop these pauses.");2308 }2309 2310 close_progress_form();2311 if (retval) {2312 mvaddstr_and_log_it(g_currentY++, 74, "Errors.");2313 } else {2314 mvaddstr_and_log_it(g_currentY++, 74, "Done.");2315 }2316 paranoid_free(pathname_of_last_biggie_restored);2317 paranoid_free(biggie_fname);2318 paranoid_free(biggie_cksum);2319 paranoid_free(tmp);2320 return (retval);2321 }2322 2323 /**************************************************************************2324 *END_RESTORE_ALL_BIGGIEFILES_FROM_STREAM *2325 **************************************************************************/2326 2327 2328 2329 2330 2331 2332 /**2333 * Restore all afioballs from the currently opened tape stream.2334 * @param bkpinfo The backup information structure. Fields used:2335 * - @c bkpinfo->backup_media_type2336 * - @c bkpinfo->restore_path2337 * @param filelist The node structure containing the list of files to be2338 * restored. If no file in an afioball is in this list, afio will still be2339 * called for that fileset, but nothing will be written.2340 * @return 0 for success, or the number of filesets that failed.2341 */2342 int restore_all_tarballs_from_stream(struct s_node *filelist)2343 {2344 int retval = 0;2345 int res;2346 long current_afioball_number = 0;2347 int ctrl_chr;2348 long max_val /*, total_noof_files */ ;2349 2350 /** malloc **/2351 char *tmp = NULL;2352 char *mds = NULL;2353 char *progress_str = NULL;2354 char *tmp_fname;2355 char *xattr_fname = NULL;2356 char *acl_fname = NULL;2357 2358 long long tmp_size;2359 2360 malloc_string(tmp);2361 malloc_string(tmp_fname);2362 assert(bkpinfo != NULL);2363 mvaddstr_and_log_it(g_currentY, 0, "Restoring from archives");2364 read_cfg_var(g_mondo_cfg_file, "last-filelist-number", tmp);2365 max_val = atol(tmp) + 1;2366 2367 if (chdir(bkpinfo->restore_path)) { /* I don't know why this is needed _here_ but it seems to be. -HR, 02/04/2002 */2368 //FIXME2369 }2370 2371 run_program_and_log_output("pwd", 5);2372 2373 mr_asprintf(progress_str, "Restoring from media #%d", g_current_media_number);2374 log_to_screen(progress_str);2375 open_progress_form("Restoring from archives",2376 "Restoring data from the archives.",2377 "Please wait. This may take some time.",2378 progress_str, max_val);2379 2380 log_msg(3, "hey");2381 2382 res = read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);2383 if (res) {2384 log_msg(2, "Warning - error reading afioball from tape");2385 }2386 retval += res;2387 if (ctrl_chr != BLK_START_AFIOBALLS) {2388 wrong_marker(BLK_START_AFIOBALLS, ctrl_chr);2389 }2390 log_msg(2, "ho");2391 res = read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);2392 while (ctrl_chr != BLK_STOP_AFIOBALLS) {2393 update_progress_form(progress_str);2394 if (g_getfattr) {2395 mr_asprintf(xattr_fname, "%s/xattr-subset-%ld.tmp", bkpinfo->tmpdir, current_afioball_number);2396 unlink(xattr_fname);2397 }2398 if (g_getfacl) {2399 mr_asprintf(acl_fname, "%s/acl-subset-%ld.tmp", bkpinfo->tmpdir, current_afioball_number);2400 unlink(acl_fname);2401 }2402 if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) {2403 log_it("Reading EXAT files from tape");2404 res = read_EXAT_files_from_tape(&tmp_size, tmp_fname, &ctrl_chr, xattr_fname, acl_fname);2405 }2406 if (ctrl_chr != BLK_START_AN_AFIO_OR_SLICE) {2407 wrong_marker(BLK_START_AN_AFIO_OR_SLICE, ctrl_chr);2408 }2409 log_msg(4, "Restoring from fileset #%ld (name=%s, size=%ld K)", current_afioball_number, tmp_fname, (long) tmp_size >> 10);2410 res = restore_a_tarball_from_stream(tmp_fname, current_afioball_number, filelist, tmp_size, xattr_fname, acl_fname);2411 retval += res;2412 if (res) {2413 log_to_screen("Fileset %ld - errors occurred", current_afioball_number);2414 }2415 res =2416 read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);2417 if (ctrl_chr != BLK_STOP_AN_AFIO_OR_SLICE) {2418 wrong_marker(BLK_STOP_AN_AFIO_OR_SLICE, ctrl_chr);2419 }2420 2421 current_afioball_number++;2422 g_current_progress++;2423 mds = media_descriptor_string(bkpinfo->backup_media_type),2424 2425 mr_free(progress_str);2426 mr_asprintf(progress_str, "Restoring from fileset #%ld on %s #%d", current_afioball_number, mds, g_current_media_number);2427 mr_free(mds);2428 res = read_header_block_from_stream(&tmp_size, tmp_fname, &ctrl_chr);2429 if (g_getfattr) {2430 unlink(xattr_fname);2431 }2432 if (g_getfacl) {2433 unlink(acl_fname);2434 }2435 } // next2436 mr_free(progress_str);2437 if (g_getfattr) {2438 mr_free(xattr_fname);2439 }2440 if (g_getfacl) {2441 mr_free(acl_fname);2442 }2443 2444 log_msg(1, "All done with afioballs");2445 close_progress_form();2446 if (retval) {2447 mvaddstr_and_log_it(g_currentY++, 74, "Errors.");2448 } else {2449 mvaddstr_and_log_it(g_currentY++, 74, "Done.");2450 }2451 paranoid_free(tmp);2452 paranoid_free(tmp_fname);2453 return (retval);2454 }2455 2456 /**************************************************************************2457 *END_ RESTORE_ALL_TARBALLS_FROM_STREAM *2458 **************************************************************************/2459 2460 /* @} - end of LLrestoreGroup */2461 2462 2463 /**2464 * Restore all files in @p filelist.2465 * @param bkpinfo The backup information structure. Most fields are used.2466 * @param filelist The node structure containing the list of files to be2467 * restored.2468 * @return 0 for success, or the number of afioballs and biggiefiles that failed.2469 * @ingroup restoreGroup2470 */2471 int restore_everything(struct s_node *filelist)2472 {2473 int resA;2474 int resB;2475 2476 /** mallco ***/2477 char *cwd;2478 char *newpath;2479 char *tmp = NULL;2480 assert(bkpinfo != NULL);2481 2482 malloc_string(cwd);2483 malloc_string(newpath);2484 log_msg(2, "restore_everything() --- starting");2485 g_current_media_number = 1;2486 if (getcwd(cwd, MAX_STR_LEN - 1)) {2487 // FIXME2488 }2489 mr_asprintf(tmp, "mkdir -p %s", bkpinfo->restore_path);2490 run_program_and_log_output(tmp, FALSE);2491 mr_free(tmp);2492 2493 log_msg(1, "Changing dir to %s", bkpinfo->restore_path);2494 if (chdir(bkpinfo->restore_path)) {2495 //FIXME2496 }2497 if (getcwd(newpath, MAX_STR_LEN - 1)) {2498 // FIXME2499 }2500 log_msg(1, "path is now %s", newpath);2501 log_msg(1, "restoring everything");2502 if (!find_home_of_exe("petris") && !g_text_mode) {2503 newtDrawRootText(0, g_noof_rows - 2,2504 "Press ALT-<left cursor> twice to play Petris :-) ");2505 newtRefresh();2506 }2507 mvaddstr_and_log_it(g_currentY, 0, "Preparing to read your archives");2508 mount_media();2509 if (IS_THIS_A_STREAMING_BACKUP(bkpinfo->backup_media_type)) {2510 mvaddstr_and_log_it(g_currentY++, 0,2511 "Restoring OS and data from streaming media");2512 if (bkpinfo->backup_media_type == cdstream) {2513 openin_cdstream();2514 } else {2515 assert_string_is_neither_NULL_nor_zerolength(bkpinfo->media_device);2516 openin_tape();2517 }2518 resA = restore_all_tarballs_from_stream(filelist);2519 resB = restore_all_biggiefiles_from_stream(filelist);2520 if (bkpinfo->backup_media_type == cdstream) {2521 closein_cdstream();2522 } else {2523 closein_tape();2524 }2525 } else {2526 mvaddstr_and_log_it(g_currentY++, 0,2527 "Restoring OS and data from CD/USB ");2528 resA = restore_all_tarballs_from_CD(filelist);2529 resB = restore_all_biggiefiles_from_CD(filelist);2530 }2531 if (chdir(cwd)) {2532 //FIXME2533 }2534 if (resA + resB) {2535 log_to_screen("Errors occurred while data was being restored.");2536 }2537 if (length_of_file("/etc/raidtab") > 0) {2538 log_msg(2, "Copying local raidtab to restored filesystem");2539 run_program_and_log_output("cp -f /etc/raidtab " MNT_RESTORING2540 "/etc/raidtab", FALSE);2541 }2542 kill_petris();2543 log_msg(2, "restore_everything() --- leaving");2544 paranoid_free(cwd);2545 paranoid_free(newpath);2546 return (resA + resB);2547 }2548 2549 /**************************************************************************2550 *END_RESTORE_EVERYTHING *2551 **************************************************************************/2552 2553 2554 extern void wait_until_software_raids_are_prepped(char *, int);2555 2556 2557 char which_restore_mode(void);2558 2537 2559 2538 -
branches/3.2/mondo/test/test-mountlist.c
r3185 r3374 17 17 18 18 extern void twenty_seconds_til_yikes(void); 19 20 /* Reference to global bkpinfo */21 struct s_bkpinfo *bkpinfo;22 19 23 20 extern bool g_text_mode; … … 47 44 extern char *MONDO_LOGFILE; 48 45 extern int copy_from_src_to_dest(FILE * f_orig, FILE * f_archived, char direction); 46 extern int create_raid_device_via_mdadm(struct raidlist_itself *raidlist, char *device, bool test); 47 48 /* Reference to global bkpinfo */ 49 struct s_bkpinfo *bkpinfo; 50 49 51 /* We don't have a cleanup function yet */ 50 52 void (*mr_cleanup)(void) = NULL; 51 53 52 voidmain() {54 int main() { 53 55 54 56 struct mountlist_itself *mountlist = NULL; -
branches/3.2/mondo/test/test-mr_stresc.c
r3294 r3374 13 13 /* Whether we should fail immediately at first error */ 14 14 bool g_fail_immediately = FALSE; 15 16 /* Reference to global bkpinfo */ 17 struct s_bkpinfo *bkpinfo; 15 18 16 19 void (*mr_cleanup)(void) = NULL; -
branches/3.2/mondo/test/test-truncname.c
r3185 r3374 13 13 14 14 extern void twenty_seconds_til_yikes(void); 15 16 /* Reference to global bkpinfo */17 struct s_bkpinfo *bkpinfo;18 15 19 16 extern bool g_text_mode; … … 40 37 char *g_getfacl; 41 38 char *g_getfattr; 39 40 /* Reference to global bkpinfo */ 41 struct s_bkpinfo *bkpinfo; 42 42 43 43 extern char *MONDO_LOGFILE;
Note:
See TracChangeset
for help on using the changeset viewer.