/************************************************************************** * F@COMPARE_TO_TAPE() * * compare_to_tape() - gots me?? * * * * returns: int * **************************************************************************/ int compare_to_tape(struct s_bkpinfo *bkpinfo) { int res; char *dir, *command; assert(bkpinfo != NULL); malloc_string(dir); malloc_string(command); getcwd(dir, MAX_STR_LEN); chdir(bkpinfo->restore_path); sprintf(command, "cp -f /tmp/LAST-FILELIST-NUMBER %s/tmp", bkpinfo->restore_path); run_program_and_log_output(command, FALSE); mvaddstr_and_log_it(g_currentY, 0, "Verifying archives against filesystem"); res = verify_tape_backups(bkpinfo); chdir(dir); if (res) { mvaddstr_and_log_it(g_currentY++, 74, "Failed."); } else { mvaddstr_and_log_it(g_currentY++, 74, "Done."); } paranoid_free(dir); paranoid_free(command); return (res); }
/** * Call a program and retrieve its last line of output. * @param call The program to run. * @return The last line of its output. * @note The returned value points to static storage that will be overwritten with each call. */ char *call_program_and_get_last_line_of_output(char *call) { /*@ buffers ***************************************************** */ static char result[512]; char *tmp; /*@ pointers **************************************************** */ FILE *fin; /*@ initialize data ********************************************* */ malloc_string(tmp); result[0] = '\0'; tmp[0] = '\0'; /*@******************************************************************** */ assert_string_is_neither_NULL_nor_zerolength(call); if ((fin = popen(call, "r"))) { for (fgets(tmp, MAX_STR_LEN, fin); !feof(fin); fgets(tmp, MAX_STR_LEN, fin)) { if (strlen(tmp) > 1) { strcpy(result, tmp); } } paranoid_pclose(fin); } else { log_OS_error("Unable to popen call"); } strip_spaces(result); return (result); }
/* ------------------------------------------------------------------------- */ struct service_t* service_create(struct plugin_t* plugin, const char* directory, const service_func exec, struct type_info_t* type_info) { struct service_t* service; struct ptree_t* node; assert(plugin); assert(plugin->game); assert(directory); assert(exec); assert(type_info); /* allocate and initialise service object */ if(!(service = (struct service_t*)MALLOC(sizeof(struct service_t)))) OUT_OF_MEMORY("service_create()", NULL); memset(service, 0, sizeof(struct service_t)); /* if anything fails, break */ for(;;) { service->plugin = plugin; service->exec = exec; service->type_info = type_info; /* plugin object keeps track of all created services */ if(!unordered_vector_push(&plugin->services, &service)) break; /* copy directory */ if(!(service->directory = malloc_string(directory))) break; /* create node in game's service directory - want to do this last * because ptree_remove_node uses malloc() */ if(!(node = ptree_add_node(&plugin->game->services, directory, service))) break; /* NOTE: don't MALLOC() past this point ----------------------- */ /* set the node's free function to service_free() to make deleting * nodes easier */ ptree_set_free_func(node, (ptree_free_func)service_free); /* success! */ return service; } /* something went wrong, clean up everything */ /* remove from plugin's list of services */ unordered_vector_erase_element(&plugin->services, &service); if(service->directory) free_string(service->directory); return NULL; }
/** * Compare all data on a CD-R/CD-RW/DVD/ISO/NFS-based backup. * @param bkpinfo The backup information structure. Passed to other functions. * @return 0 for success, nonzero for failure. */ int compare_to_CD(struct s_bkpinfo *bkpinfo) { /** needs malloc *********/ char *tmp, *cwd, *new, *command; int resA = 0; int resB = 0; long noof_changed_files; malloc_string(tmp); malloc_string(cwd); malloc_string(new); malloc_string(command); assert(bkpinfo != NULL); getcwd(cwd, MAX_STR_LEN - 1); chdir(bkpinfo->restore_path); getcwd(new, MAX_STR_LEN - 1); sprintf(tmp, "new path is %s", new); insist_on_this_cd_number(bkpinfo, g_current_media_number); unlink("/tmp/changed.txt"); resA = compare_all_tarballs(bkpinfo); resB = compare_all_biggiefiles(bkpinfo); chdir(cwd); noof_changed_files = count_lines_in_file("/tmp/changed.txt"); if (noof_changed_files) { sprintf(tmp, "%ld files do not match the backup ", noof_changed_files); // mvaddstr_and_log_it( g_currentY++, 0, tmp ); log_to_screen(tmp); sprintf(command, "cat /tmp/changed.txt >> %s", MONDO_LOGFILE); paranoid_system(command); } else { sprintf(tmp, "All files match the backup "); mvaddstr_and_log_it(g_currentY++, 0, tmp); log_to_screen(tmp); } paranoid_free(tmp); paranoid_free(cwd); paranoid_free(new); paranoid_free(command); return (resA + resB); }
/** * Verify one afioball from the opened tape/CD stream. * Copies the file from tape to tmpdir and then calls verify_an_afioball(). * @param bkpinfo The backup information structure. Passed to verify_an_afioball(). * @param orig_fname The original filename of the afioball to verify. * @param size The size of the afioball to verify. * @return The return value of verify_an_afioball(). * @see verify_an_afioball */ int verify_an_afioball_from_stream(struct s_bkpinfo *bkpinfo, char *orig_fname, long long size) { /*@ int ************************************************************** */ int retval = 0; int res = 0; /*@ buffers ********************************************************** */ char *tmp; char *tarball_fname; /*@ pointers ********************************************************* */ char *p; malloc_string(tmp); malloc_string(tarball_fname); assert(bkpinfo != NULL); assert_string_is_neither_NULL_nor_zerolength(orig_fname); p = strrchr(orig_fname, '/'); if (!p) { p = orig_fname; } else { p++; } sprintf(tmp, "mkdir -p %s/tmpfs", bkpinfo->tmpdir); paranoid_system(tmp); sprintf(tarball_fname, "%s/tmpfs/temporary-%s", bkpinfo->tmpdir, p); sprintf(tmp, "Temporarily copying file from tape to '%s'", tarball_fname); /* log_it(tmp); */ read_file_from_stream_to_file(bkpinfo, tarball_fname, size); res = verify_a_tarball(bkpinfo, tarball_fname); if (res) { sprintf(tmp, "Afioball '%s' no longer matches your live filesystem", p); log_msg(0, tmp); retval++; } unlink(tarball_fname); paranoid_free(tmp); paranoid_free(tarball_fname); return (retval); }
/** * Compare all data on a cdstream-based backup. * @param bkpinfo The backup information structure. Fields used: * - @c bkpinfo->disaster_recovery * - @c bkpinfo->media_device * - @c bkpinfo->restore_path * @return 0 for success, nonzero for failure. */ int compare_to_cdstream(struct s_bkpinfo *bkpinfo) { int res; /** needs malloc **/ char *dir, *command; assert(bkpinfo != NULL); malloc_string(dir); malloc_string(command); getcwd(dir, MAX_STR_LEN); chdir(bkpinfo->restore_path); sprintf(command, "cp -f /tmp/LAST-FILELIST-NUMBER %s/tmp", bkpinfo->restore_path); run_program_and_log_output(command, FALSE); mvaddstr_and_log_it(g_currentY, 0, "Verifying archives against filesystem"); if (bkpinfo->disaster_recovery && does_file_exist("/tmp/CDROM-LIVES-HERE")) { strcpy(bkpinfo->media_device, last_line_of_file("/tmp/CDROM-LIVES-HERE")); } else { find_cdrom_device(bkpinfo->media_device, FALSE); } res = verify_tape_backups(bkpinfo); chdir(dir); if (length_of_file("/tmp/changed.txt") > 2 && length_of_file("/tmp/changed.files") > 2) { log_msg(0, "Type 'less /tmp/changed.files' to see which files don't match the archives"); log_msg(2, "Calling popup_changelist_from_file()"); popup_changelist_from_file("/tmp/changed.files"); log_msg(2, "Returned from popup_changelist_from_file()"); } mvaddstr_and_log_it(g_currentY++, 74, "Done."); paranoid_free(dir); paranoid_free(command); return (res); }
/** * Kill @c buffer processes. */ void kill_buffer() { char *tmp; char *command; malloc_string(tmp); malloc_string(command); paranoid_system("sync"); sprintf(command, "ps wwax | fgrep \"%s\" | fgrep -v grep | awk '{print $1;}' | grep -v PID | tr -s '\n' ' ' | awk '{ print $1; }'", g_sz_call_to_buffer); log_msg(2, "kill_buffer() --- command = %s", command); strcpy(tmp, call_program_and_get_last_line_of_output(command)); sprintf(command, "kill %s", tmp); log_msg(2, "kill_buffer() --- command = %s", command); if (strlen(tmp) > 0) { run_program_and_log_output(command, TRUE); } paranoid_free(tmp); paranoid_free(command); }
/* ------------------------------------------------------------------------- */ struct event_t* event_create(struct plugin_t* plugin, const char* directory, struct type_info_t* type_info) { struct ptree_t* node; struct event_t* event; assert(plugin); assert(plugin->game); assert(directory); /* allocate and initialise event object */ if(!(event = (struct event_t*)MALLOC(sizeof(struct event_t)))) OUT_OF_MEMORY("event_create()", NULL); memset(event, 0, sizeof(struct event_t)); for(;;) { event->plugin = plugin; event->type_info = type_info; unordered_vector_init_vector(&event->listeners, sizeof(struct event_listener_t)); /* copy directory */ if(!(event->directory = malloc_string(directory))) break; /* plugin object keeps track of all created events */ if(!unordered_vector_push(&plugin->events, &event)) break; /* create node in game's event directory and add event - do this last * because ptree_remove_node() uses malloc() */ if(!(node = ptree_add_node(&plugin->game->events, directory, event))) break; /* NOTE: don't MALLOC() past this point ----------------------- */ /* set the node's free function to event_free() to make deleting * nodes easier */ ptree_set_free_func(node, (ptree_free_func)event_free); /* success! */ return event; } /* something went wrong, clean up */ if(event->directory) free_string(event->directory); return NULL; }
/** * Feed @p input_fifo through ntfsclone (restore) to @p output_device. * @param input_fifo The ntfsclone file to read. * @param output_device Where to put the output. * @return The return value of ntfsclone (0 for success). */ int feed_outfrom_ntfsprog(char *output_device, char *input_fifo) { // RESTORE int res = -1; char *command; if ( !find_home_of_exe("ntfsclone")) { fatal_error("ntfsclone not found"); } malloc_string(command); sprintf(command, "ntfsclone --force --restore-image --overwrite %s %s", output_device, input_fifo); res = run_program_and_log_output(command, 5); paranoid_free(command); return (res); }
/** * Feed @p input_device through ntfsclone to @p output_fname. * @param input_device The device to image. * @param output_fname The file to write. * @return 0 for success, nonzero for failure. */ int feed_into_ntfsprog(char *input_device, char *output_fname) { // BACKUP int res = -1; char*command; if (!does_file_exist(input_device)) { fatal_error("input device does not exist"); } if ( !find_home_of_exe("ntfsclone")) { fatal_error("ntfsclone not found"); } malloc_string(command); sprintf(command, "ntfsclone --force --save-image --overwrite %s %s", output_fname, input_device); res = run_program_and_log_output(command, 5); paranoid_free(command); unlink(output_fname); return (res); }
void set_texture_to_object(SDL_Surface * sdl_texture, SDL_Surface * sdl_normal_texture, d3_object * d3object) { if (d3object == NULL) { printf("ERROR: set_texture_to_object object is null\n"); return; } if (d3object->texture_id == NULL){ printf("ERROR: set_texture_to_object texture_id is null\n"); return; } if (strncmp(d3object->texture_id->mfilename, "dynamic", strlen("dynamic")) != 0) { d3object->texture_id->mfilename = malloc_string("dynamic"); } printf("deleting texture %u\n", d3object->texture_id->texture_id); if (d3object->texture_id->texture_id != 0) glDeleteTextures(1, &(d3object->texture_id->texture_id)); if (sdl_normal_texture != NULL && d3object->texture_bump_id == NULL) { printf("ERROR: set_texture_to_object texture_bump_id is null\n"); return; } SDL_Surface * s = SDL_CreateRGBSurface(0, sdl_texture->w, sdl_texture->h, 32, 0x00ff0000,0x0000ff00,0x000000ff,0xff000000); SDL_BlitSurface(sdl_texture, NULL, s, NULL); gpu_texture(&(d3object->texture_id->texture_id), (unsigned char * )s->pixels, s->w, s->h); printf("created texture %u\n", d3object->texture_id->texture_id); SDL_FreeSurface(s); if (sdl_normal_texture != NULL) { printf("deleting normal texture %u\n", d3object->texture_bump_id->texture_id); if (d3object->texture_bump_id->texture_id != 0) glDeleteTextures(1, &(d3object->texture_bump_id->texture_id)); s = SDL_CreateRGBSurface(0, sdl_normal_texture->w, sdl_normal_texture->h, 32, 0x00ff0000,0x0000ff00,0x000000ff,0xff000000); SDL_BlitSurface(sdl_normal_texture, NULL, s, NULL); gpu_texture(&(d3object->texture_bump_id->texture_id), (unsigned char * )s->pixels, s->w, s->h); printf("creating normal texture %u\n", d3object->texture_bump_id->texture_id); SDL_FreeSurface(s); } }
/** * Verify all biggiefiles on the opened CD/tape stream. * @param bkpinfo The backup information structure. Fields used: * - @c bkpinfo->restore_path * - @c bkpinfo->tmpdir * * @return 0 for success (even if there are differences); nonzero for a tape error. */ int verify_biggiefiles_from_stream(struct s_bkpinfo *bkpinfo) { /*@ int ************************************************************ */ int retval = 0; int res = 0; int ctrl_chr = 0; /*@ long *********************************************************** */ long noof_biggiefiles = 0; long current_biggiefile_number = 0; /*@ buffers ******************************************************** */ char *tmp; char *orig_fname, *logical_fname; char *comment; char *curr_xattr_list_fname; char *curr_acl_list_fname; /*@ pointers ******************************************************* */ char *p; /*@ long long size ************************************************* */ long long size = 0; assert(bkpinfo != NULL); malloc_string(tmp); malloc_string(orig_fname); malloc_string(logical_fname); malloc_string(comment); malloc_string(curr_xattr_list_fname); malloc_string(curr_acl_list_fname); sprintf(curr_xattr_list_fname, XATTR_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir); sprintf(curr_acl_list_fname, ACL_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir); sprintf(comment, "Verifying all bigfiles."); log_to_screen(comment); sprintf(tmp, "%s/biggielist.txt", bkpinfo->tmpdir); // noof_biggiefiles = count_lines_in_file (tmp); // pointless res = read_header_block_from_stream(&size, orig_fname, &ctrl_chr); if (ctrl_chr != BLK_START_BIGGIEFILES) { if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) { iamhere("Grabbing the EXAT biggiefiles"); res = read_EXAT_files_from_tape(bkpinfo, &size, orig_fname, &ctrl_chr, curr_xattr_list_fname, curr_acl_list_fname); } } if (ctrl_chr != BLK_START_BIGGIEFILES) { wrong_marker(BLK_START_BIGGIEFILES, ctrl_chr); } noof_biggiefiles = (long) size; log_msg(1, "noof_biggiefiles = %ld", noof_biggiefiles); open_progress_form("Verifying big files", comment, "Please wait. This may take some time.", "", noof_biggiefiles); for (res = read_header_block_from_stream(&size, orig_fname, &ctrl_chr); ctrl_chr != BLK_STOP_BIGGIEFILES; res = read_header_block_from_stream(&size, orig_fname, &ctrl_chr)) { if (ctrl_chr != BLK_START_A_NORMBIGGIE && ctrl_chr != BLK_START_A_PIHBIGGIE) { wrong_marker(BLK_START_A_NORMBIGGIE, ctrl_chr); } p = strrchr(orig_fname, '/'); if (!p) { p = orig_fname; } else { p++; } sprintf(comment, "Verifying bigfile #%ld (%ld K)", current_biggiefile_number, (long) size >> 10); update_progress_form(comment); sprintf(logical_fname, "%s/%s", bkpinfo->restore_path, orig_fname); res = verify_a_biggiefile_from_stream(bkpinfo, logical_fname, size); retval += res; current_biggiefile_number++; g_current_progress++; } close_progress_form(); paranoid_free(orig_fname); paranoid_free(logical_fname); paranoid_free(curr_xattr_list_fname); paranoid_free(curr_acl_list_fname); paranoid_free(comment); paranoid_free(tmp); return (retval); }
/** * Compare all data in the user's backup. * This function will mount filesystems, compare afioballs and biggiefiles, * and show the user the differences. * @param bkpinfo The backup information structure. Passed to other functions. * @param mountlist The mountlist containing partitions to mount. * @param raidlist The raidlist containing the user's RAID devices. * @return The number of errors/differences found. */ int compare_mode(struct s_bkpinfo *bkpinfo, struct mountlist_itself *mountlist, struct raidlist_itself *raidlist) { int retval = 0; long q; char *tmp; malloc_string(tmp); /************************************************************************** * also deletes tmp/filelist.full & tmp/biggielist.txt _and_ tries to * * restore them from start of tape, if available * **************************************************************************/ assert(bkpinfo != NULL); assert(mountlist != NULL); assert(raidlist != NULL); while (get_cfg_file_from_archive(bkpinfo)) { if (!ask_me_yes_or_no ("Failed to find config file/archives. Choose another source?")) { fatal_error("Unable to find config file/archives. Aborting."); } interactively_obtain_media_parameters_from_user(bkpinfo, FALSE); } read_cfg_file_into_bkpinfo(g_mondo_cfg_file, bkpinfo); g_current_media_number = 1; mvaddstr_and_log_it(1, 30, "Comparing Automatically"); iamhere("Pre-MAD"); retval = mount_all_devices(mountlist, FALSE); iamhere("Post-MAD"); if (retval) { unmount_all_devices(mountlist); return (retval); } if (bkpinfo->backup_media_type == tape || bkpinfo->backup_media_type == udev) { retval += compare_to_tape(bkpinfo); } else if (bkpinfo->backup_media_type == cdstream) { retval += compare_to_cdstream(bkpinfo); } else { retval += compare_to_CD(bkpinfo); } if (retval) { mvaddstr_and_log_it(g_currentY++, 0, "Warning - differences found during the compare phase"); } retval += unmount_all_devices(mountlist); if (count_lines_in_file("/tmp/changed.txt") > 0) { mvaddstr_and_log_it(g_currentY++, 0, "Differences found while files were being compared."); streamline_changes_file("/tmp/changed.files", "/tmp/changed.txt"); if (count_lines_in_file("/tmp/changed.files") <= 0) { mvaddstr_and_log_it(g_currentY++, 0, "...but they were logfiles and temporary files. Your archives are fine."); log_to_screen ("The differences were logfiles and temporary files. Your archives are fine."); } else { q = count_lines_in_file("/tmp/changed.files"); sprintf(tmp, "%ld significant difference%s found.", q, (q != 1) ? "s" : ""); mvaddstr_and_log_it(g_currentY++, 0, tmp); log_to_screen(tmp); strcpy(tmp, "Type 'less /tmp/changed.files' for a list of non-matching files"); mvaddstr_and_log_it(g_currentY++, 0, tmp); log_to_screen(tmp); log_msg(2, "calling popup_changelist_from_file()"); popup_changelist_from_file("/tmp/changed.files"); log_msg(2, "Returning from popup_changelist_from_file()"); } } else { log_to_screen ("No significant differences were found. Your backup is perfect."); } kill_petris(); paranoid_free(tmp); return (retval); }
/** * Compare afioball @p tarball_fname against the filesystem. * You must be chdir()ed to the directory where the filesystem is mounted * before you call this function. * @param tarball_fname The filename of the tarball to compare. * @param current_tarball_number The fileset number contained in @p tarball_fname. * @return 0 for success, nonzero for failure. */ int compare_a_tarball(char *tarball_fname, int current_tarball_number) { int retval = 0; int res; long noof_lines; long archiver_errors; bool use_star; /*** needs malloc *********/ char *command, *tmp, *filelist_name, *logfile, *archiver_exe, *compressor_exe; malloc_string(command); malloc_string(tmp); malloc_string(filelist_name); malloc_string(logfile); malloc_string(archiver_exe); malloc_string(compressor_exe); use_star = (strstr(tarball_fname, ".star")) ? TRUE : FALSE; assert_string_is_neither_NULL_nor_zerolength(tarball_fname); sprintf(logfile, "/tmp/afio.log.%d", current_tarball_number); sprintf(filelist_name, MNT_CDROM "/archives/filelist.%d", current_tarball_number); noof_lines = count_lines_in_file(filelist_name); if (strstr(tarball_fname, ".bz2")) { strcpy(compressor_exe, "bzip2"); } else if (strstr(tarball_fname, ".lzo")) { strcpy(compressor_exe, "lzop"); } else { compressor_exe[0] = '\0'; } if (use_star) { strcpy(archiver_exe, "star"); } else { strcpy(archiver_exe, "afio"); } if (compressor_exe[0]) { strcpy(tmp, compressor_exe); if (!find_home_of_exe(tmp)) { fatal_error("(compare_a_tarball) Compression program missing"); } if (use_star) // star { if (!strcmp(compressor_exe, "bzip2")) { strcat(archiver_exe, " -bz"); } else { fatal_error ("(compare_a_tarball) Please use only bzip2 with star"); } } else // afio { sprintf(compressor_exe, "-P %s -Z", tmp); } } // star -diff H=star -bz file=.... #ifdef __FreeBSD__ #define BUFSIZE 512L #else #define BUFSIZE (1024L*1024L)/TAPE_BLOCK_SIZE #endif if (use_star) // doesn't use compressor_exe { sprintf(command, "%s -diff H=star file=%s >> %s 2>> %s", archiver_exe, tarball_fname, logfile, logfile); } else { sprintf(command, "%s -r -b %ld -M 16m -c %ld %s %s >> %s 2>> %s", archiver_exe, TAPE_BLOCK_SIZE, BUFSIZE, compressor_exe, tarball_fname, logfile, logfile); } #undef BUFSIZE res = system(command); retval += res; if (res) { log_OS_error(command); sprintf(tmp, "Warning - afio returned error = %d", res); } if (length_of_file(logfile) > 5) { sprintf(command, "sed s/': \\\"'/\\|/ %s | sed s/'\\\": '/\\|/ | cut -d'|' -f2 | sort -u | grep -vx \"dev/.*\" >> /tmp/changed.txt", logfile); system(command); archiver_errors = count_lines_in_file(logfile); } else { archiver_errors = 0; } sprintf(tmp, "%ld difference%c in fileset #%d ", archiver_errors, (archiver_errors != 1) ? 's' : ' ', current_tarball_number); if (archiver_errors) { sprintf(tmp, "Differences found while processing fileset #%d ", current_tarball_number); log_msg(1, tmp); } unlink(logfile); paranoid_free(command); paranoid_free(tmp); paranoid_free(filelist_name); paranoid_free(logfile); malloc_string(archiver_exe); malloc_string(compressor_exe); return (retval); }
/** * Compare all afioballs in this backup. * @param bkpinfo The backup media structure. Passed to other functions. * @return 0 for success, nonzero for failure. */ int compare_all_tarballs(struct s_bkpinfo *bkpinfo) { int retval = 0; int res; int current_tarball_number = 0; /** needs malloc **********/ char *tarball_fname, *progress_str, *tmp; long max_val; malloc_string(tarball_fname); malloc_string(progress_str); malloc_string(tmp); assert(bkpinfo != NULL); mvaddstr_and_log_it(g_currentY, 0, "Comparing archives"); read_cfg_var(g_mondo_cfg_file, "last-filelist-number", tmp); max_val = atol(tmp); sprintf(progress_str, "Comparing with %s #%d ", media_descriptor_string(bkpinfo->backup_media_type), g_current_media_number); open_progress_form("Comparing files", "Comparing tarballs against filesystem.", "Please wait. This may take some time.", progress_str, max_val); log_to_screen(progress_str); for (;;) { insist_on_this_cd_number(bkpinfo, g_current_media_number); update_progress_form(progress_str); sprintf(tarball_fname, MNT_CDROM "/archives/%d.afio.bz2", current_tarball_number); if (!does_file_exist(tarball_fname)) { sprintf(tarball_fname, MNT_CDROM "/archives/%d.afio.lzo", current_tarball_number); } if (!does_file_exist(tarball_fname)) { sprintf(tarball_fname, MNT_CDROM "/archives/%d.afio.", current_tarball_number); } if (!does_file_exist(tarball_fname)) { sprintf(tarball_fname, MNT_CDROM "/archives/%d.star.bz2", current_tarball_number); } if (!does_file_exist(tarball_fname)) { sprintf(tarball_fname, MNT_CDROM "/archives/%d.star.", current_tarball_number); } if (!does_file_exist(tarball_fname)) { if (!does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST") || system("find " MNT_CDROM "/archives/slice* > /dev/null 2> /dev/null") == 0) { log_msg(2, "OK, I think I'm done with tarballs..."); break; } log_msg(2, "OK, I think it's time for another CD..."); g_current_media_number++; sprintf(progress_str, "Comparing with %s #%d ", media_descriptor_string(bkpinfo->backup_media_type), g_current_media_number); log_to_screen(progress_str); } else { res = compare_a_tarball(tarball_fname, current_tarball_number); g_current_progress++; current_tarball_number++; } } close_progress_form(); if (retval) { mvaddstr_and_log_it(g_currentY++, 74, "Errors."); } else { mvaddstr_and_log_it(g_currentY++, 74, "Done."); } paranoid_free(tarball_fname); paranoid_free(progress_str); paranoid_free(tmp); return (retval); }
static b_torrent_tracker* malloc_tracker(char* src, int len) { b_torrent_tracker* ttk = malloc(sizeof(b_torrent_tracker)); ttk->next = NULL; ttk->url = malloc_string(src, len); return ttk; }
/** * Process mondoarchive's command-line switches. * @param bkpinfo The backup information structure to populate. * @param flag_val An array of the argument passed to each switch (the letter is the index). * If a switch is not set or has no argument, the field in @p flag_val doesn't matter. * @param flag_set An array of <tt>bool</tt>s indexed by switch letter: TRUE if it's set, * FALSE if it's not. * @return The number of problems with the switches, or 0 for success. * @bug Maybe include a list of all switches (inc. intentionally undocumented ones not in the manual!) here? */ int process_switches(struct s_bkpinfo *bkpinfo, char flag_val[128][MAX_STR_LEN], bool flag_set[128]) { /*@ ints *** */ int i = 0; int retval = 0; int percent = 0; /*@ buffers ** */ char *tmp; char *tmp1; char *psz; char *p; char *q; long itbs; struct stat buf; malloc_string(tmp); malloc_string(psz); assert(bkpinfo != NULL); assert(flag_val != NULL); assert(flag_set != NULL); bkpinfo->internal_tape_block_size = DEFAULT_INTERNAL_TAPE_BLOCK_SIZE; /* compulsory */ i = flag_set['c'] + flag_set['i'] + flag_set['n'] + flag_set['t'] + flag_set['u'] + flag_set['r'] + flag_set['w'] + flag_set['C']; if (i == 0) { retval++; log_to_screen("You must specify the media type\n"); } if (i > 1) { retval++; log_to_screen("Please specify only one media type\n"); } if (flag_set['K']) { g_loglevel = atoi(flag_val['K']); if (g_loglevel < 3) { g_loglevel = 3; } } if (flag_set['L'] && flag_set['0']) { retval++; log_to_screen("You cannot have 'no compression' _and_ LZOP.\n"); } bkpinfo->backup_data = flag_set['O']; bkpinfo->verify_data = flag_set['V']; if (flag_set['I'] && !bkpinfo->backup_data) { log_to_screen("-I switch is ignored if just verifying"); } if (flag_set['E'] && !bkpinfo->backup_data) { log_to_screen("-E switch is ignored if just verifying"); } if (!find_home_of_exe("afio")) { if (find_home_of_exe("star")) { flag_set['R'] = TRUE; log_msg(1, "Using star instead of afio"); } else { fatal_error ("Neither afio nor star is installed. Please install at least one."); } } if (flag_set['R']) { bkpinfo->use_star = TRUE; if (flag_set['L']) { fatal_error("You may not use star and lzop at the same time."); } if (!find_home_of_exe("star")) { fatal_error ("Please install 'star' RPM or tarball if you are going to use -R. Thanks."); } } if (flag_set['W']) { bkpinfo->nonbootable_backup = TRUE; log_to_screen("Warning - you have opted for non-bootable backup"); if (flag_set['f'] || flag_set['l']) { log_to_screen ("You don't need to specify bootloader or bootdevice"); } } if (flag_set['t'] && flag_set['H']) { fatal_error ("Sorry, you may not nuke w/o warning from tape. Drop -H, please."); } if (flag_set['I']) { if (!strcmp(bkpinfo->include_paths, "/")) { log_msg(2, "'/' is pleonastic."); bkpinfo->include_paths[0] = '\0'; } if (bkpinfo->include_paths[0]) { strcat(bkpinfo->include_paths, " "); } asprintf(&tmp1, flag_val['I']); p = tmp1; q = tmp1; /* Cut the flag_val['I'] in parts containing all paths to test them */ while (p != NULL) { q = strchr(p, ' '); if (q != NULL) { *q = '\0'; if (stat(p, &buf) != 0) { log_msg(1, "ERROR ! %s doesn't exist", p); fatal_error("ERROR ! You specified a directory to include which doesn't exist"); } p = q+1 ; } else { if (stat(p, &buf) != 0) { log_msg(1, "ERROR ! %s doesn't exist", p); fatal_error("ERROR ! You specified a directory to include which doesn't exist"); } p = NULL; } } paranoid_free(tmp1); strncpy(bkpinfo->include_paths + strlen(bkpinfo->include_paths), flag_val['I'], 4*MAX_STR_LEN - strlen(bkpinfo->include_paths)); log_msg(1, "include_paths is now '%s'", bkpinfo->include_paths); if (bkpinfo->include_paths[0] == '-') { retval++; log_to_screen("Please supply a sensible value with '-I'\n"); } } if (g_kernel_version >= 2.6 && !flag_set['d'] && (flag_set['c'] || flag_set['w'])) { fatal_error ("If you are using the 2.6.x kernel, please specify the CD-R(W) device."); } if (flag_set['J']) { if (flag_set['I']) { retval++; log_to_screen ("Please do not use -J in combination with -I. If you want to make a list of files to backup, that's fine, use -J <filename> but please don't muddy the waters by combining -J with -I. Thanks. :-)"); } bkpinfo->make_filelist = FALSE; strcpy(bkpinfo->include_paths, flag_val['J']); } if (flag_set['c'] || flag_set['w'] || flag_set['C'] || flag_set['r']) { if (!flag_set['r'] && g_kernel_version <= 2.5 && strstr(flag_val['d'], "/dev/")) { fatal_error ("Please don't give a /dev entry. Give a SCSI node for the parameter of the -d flag."); } if (flag_set['r'] && g_kernel_version <= 2.5 && !strstr(flag_val['d'], "/dev/")) { fatal_error ("Please give a /dev entry, not a SCSI node, as the parameter of the -d flag."); } if (g_kernel_version >= 2.6 && !strstr(flag_val['d'], "/dev/")) { log_to_screen ("Linus says 2.6 has a broken ide-scsi module. Proceed at your own risk..."); } if (system("which cdrecord > /dev/null 2> /dev/null") && system("which dvdrecord > /dev/null 2> /dev/null")) { fatal_error ("Please install dvdrecord/cdrecord and try again."); } if (flag_set['C']) { bkpinfo->cdrw_speed = atoi(flag_val['C']); if (bkpinfo->cdrw_speed < 1) { fatal_error ("You specified a silly speed for a CD-R[W] drive"); } if (!flag_set['L']) { log_to_screen ("You must use -L with -C. Therefore I am setting it for you."); flag_set['L'] = 1; flag_val['L'][0] = '\0'; } } else { log_msg(3, "flag_val['c'] = %s", flag_val['c']); log_msg(3, "flag_val['w'] = %s", flag_val['w']); // log_msg(3, "flag_set['r'] = %i", flag_set['r'] ); if (flag_set['c']) { bkpinfo->cdrw_speed = atoi(flag_val['c']); } else if (flag_set['w']) { bkpinfo->cdrw_speed = atoi(flag_val['w']); } else if (flag_set['r']) { bkpinfo->cdrw_speed = 1; /*atoi(flag_val['r']); */ } if (bkpinfo->cdrw_speed < 1) { fatal_error ("You specified a silly speed for a CD-R[W] drive"); } } } if (flag_set['t'] && !flag_set['d']) { log_it("Hmm! No tape drive specified. Let's see what we can do."); if (find_tape_device_and_size(flag_val['d'], tmp)) { fatal_error ("Tape device not specified. I couldn't find it either."); } flag_set['d'] = TRUE; sprintf(tmp, "You didn't specify a tape streamer device. I'm assuming %s", flag_val['d']); log_to_screen(tmp); percent = 0; } if (flag_set['r']) // DVD { if (flag_set['m']) { fatal_error ("Manual CD tray (-m) not yet supported in conjunction w/ DVD drives. Drop -m."); } if (!flag_set['d']) { if (!find_dvd_device(flag_val['d'], FALSE)) { flag_set['d'] = TRUE; log_to_screen("I guess DVD drive is at %s", flag_val['d']); } } if (!find_home_of_exe("growisofs")) { fatal_error ("Please install growisofs (probably part of dvd+rw-tools). If you want DVD support, you need it."); } if (!find_home_of_exe("dvd+rw-format")) { fatal_error ("Please install dvd+rw-format (probably part of dvd+rw-tools). If you want DVD support, you need it."); } if (strchr(flag_val['d'], ',')) { fatal_error ("Please don't give a SCSI node. Give a _device_, preferably a /dev entry, for the parameter of the -d flag."); } if (!flag_set['s']) { sprintf(flag_val['s'], "%d", DEFAULT_DVD_DISK_SIZE); // 4.7 salesman's GB = 4.482 real GB = 4582 MB strcat(flag_val['s'], "m"); log_to_screen ("You did not specify a size (-s) for DVD. I'm guessing %s.", flag_val['s']); flag_set['s'] = 1; } /* if (flag_set['Z']) { bkpinfo->blank_dvd_first = TRUE; } */ } if (flag_set['t'] || flag_set['u']) { /* tape size */ if (strchr(flag_val['d'], ',')) { fatal_error ("Please don't give a SCSI node. Give a _device_, preferably a /dev entry, for the parameter of the -d flag."); } if (flag_set['O']) { if (flag_set['s']) { if (flag_set['t']) { fatal_error ("For the moment, please don't specify a tape size. Mondo should handle end-of-tape gracefully anyway."); } if (process_the_s_switch(bkpinfo, flag_val['s'])) { fatal_error("Bad -s switch"); } } else if (flag_set['u'] || flag_set['t']) { for (i = 0; i <= MAX_NOOF_MEDIA; i++) { bkpinfo->media_size[i] = 0; } } else { retval++; log_to_screen("Tape size not specified.\n"); } } } else { /* CD size */ if (flag_set['s']) { if (process_the_s_switch(bkpinfo, flag_val['s'])) { fatal_error("Bad -s switch"); } } if (flag_set['w']) { bkpinfo->wipe_media_first = TRUE; } /* CD-RW */ } if (flag_set['n']) { strncpy(bkpinfo->nfs_mount, flag_val['n'], MAX_STR_LEN); if (!flag_set['d']) { strncpy(bkpinfo->nfs_remote_dir, "/", MAX_STR_LEN); } sprintf(tmp, "mount | grep -x \"%s .*\" | cut -d' ' -f3", bkpinfo->nfs_mount); strncpy(bkpinfo->isodir, call_program_and_get_last_line_of_output(tmp), MAX_STR_LEN / 4); if (strlen(bkpinfo->isodir) < 3) { retval++; log_to_screen("NFS share is not mounted. Please mount it.\n"); } log_msg(3, "mount = %s", bkpinfo->nfs_mount); log_msg(3, "isodir= %s", bkpinfo->isodir); } if (flag_set['c']) { bkpinfo->backup_media_type = cdr; } if (flag_set['C']) { bkpinfo->backup_media_type = cdstream; } if (flag_set['i']) { bkpinfo->backup_media_type = iso; } if (flag_set['n']) { bkpinfo->backup_media_type = nfs; } if (flag_set['r']) { bkpinfo->backup_media_type = dvd; } if (flag_set['t']) { bkpinfo->backup_media_type = tape; } if (flag_set['u']) { bkpinfo->backup_media_type = udev; } if (flag_set['w']) { bkpinfo->backup_media_type = cdrw; } /* optional, popular */ if (flag_set['g']) { g_text_mode = FALSE; } if (flag_set['E']) { if (bkpinfo->exclude_paths[0]) { strcat(bkpinfo->exclude_paths, " "); } asprintf(&tmp1, flag_val['E']); p = tmp1; q = tmp1; /* Cut the flag_val['E'] in parts containing all paths to test them */ while (p != NULL) { q = strchr(p, ' '); if (q != NULL) { *q = '\0'; if (stat(p, &buf) != 0) { log_msg(1, "WARNING ! %s doesn't exist", p); } p = q+1 ; } else { if (stat(p, &buf) != 0) { log_msg(1, "WARNING ! %s doesn't exist", p); } p = NULL; } } paranoid_free(tmp1); strncpy(bkpinfo->exclude_paths + strlen(bkpinfo->exclude_paths), flag_val['E'], 4*MAX_STR_LEN - strlen(bkpinfo->exclude_paths)); } if (flag_set['e']) { bkpinfo->please_dont_eject = TRUE; } if (flag_set['N']) // exclude NFS mounts & devices { // strncpy(psz, list_of_NFS_devices_and_mounts(), MAX_STR_LEN); strncpy(psz, list_of_NFS_mounts_only(), MAX_STR_LEN); if (bkpinfo->exclude_paths[0]) { strncat(bkpinfo->exclude_paths, " ", MAX_STR_LEN); } strncat(bkpinfo->exclude_paths, psz, MAX_STR_LEN); log_msg(3, "-N means we're now excluding %s", bkpinfo->exclude_paths); } if (strlen(bkpinfo->exclude_paths) >= MAX_STR_LEN) { fatal_error ("Your '-E' parameter is too long. Please use '-J'. (See manual.)"); } if (flag_set['b']) { strcpy(psz, flag_val['b']); log_msg(1, "psz = '%s'", psz); if (psz[strlen(psz) - 1] == 'k') { psz[strlen(psz) - 1] = '\0'; itbs = atol(psz) * 1024L; } else { itbs = atol(psz); } log_msg(1, "'%s' --> %ld", flag_val['b'], itbs); log_msg(1, "Internal tape block size is now %ld bytes", itbs); if (itbs % 512 != 0 || itbs < 256 || itbs > 1024L * 1024) { fatal_error ("Are you nuts? Silly, your internal tape block size is. Abort, I shall."); } bkpinfo->internal_tape_block_size = itbs; } if (flag_set['D']) { bkpinfo->differential = 1; // bkpinfo->differential = atoi (flag_val['D']); if ((bkpinfo->differential < 1) || (bkpinfo->differential > 9)) { fatal_error ("The D option should be between 1 and 9 inclusive"); } } if (flag_set['x']) { strncpy(bkpinfo->image_devs, flag_val['x'], MAX_STR_LEN / 4); if (run_program_and_log_output("which ntfsclone", 2)) { fatal_error("Please install ntfsprogs package/tarball."); } } if (flag_set['m']) { bkpinfo->manual_cd_tray = TRUE; } if (flag_set['k']) { strncpy(bkpinfo->kernel_path, flag_val['k'], MAX_STR_LEN); if (!strcmp(bkpinfo->kernel_path, "failsafe")) { strcpy(bkpinfo->kernel_path, "FAILSAFE"); } if (strcmp(bkpinfo->kernel_path, "FAILSAFE") && !does_file_exist(bkpinfo->kernel_path)) { retval++; sprintf(tmp, "You specified kernel '%s', which does not exist\n", bkpinfo->kernel_path); log_to_screen(tmp); } } if (flag_set['p']) { strncpy(bkpinfo->prefix, flag_val['p'], MAX_STR_LEN / 4); } if (flag_set['d']) { /* backup directory (if ISO/NFS) */ if (flag_set['i']) { strncpy(bkpinfo->isodir, flag_val['d'], MAX_STR_LEN / 4); sprintf(tmp, "ls -l %s", bkpinfo->isodir); if (run_program_and_log_output(tmp, FALSE)) { fatal_error ("output folder does not exist - please create it"); } } else if (flag_set['n']) { strncpy(bkpinfo->nfs_remote_dir, flag_val['d'], MAX_STR_LEN); } else { /* backup device (if tape/CD-R/CD-RW) */ strncpy(bkpinfo->media_device, flag_val['d'], MAX_STR_LEN / 4); } } if (flag_set['n']) { sprintf(tmp, "echo hi > %s/%s/.dummy.txt", bkpinfo->isodir, bkpinfo->nfs_remote_dir); if (run_program_and_log_output(tmp, FALSE)) { retval++; sprintf(tmp, "Are you sure directory '%s' exists in remote dir '%s'?\nIf so, do you have rights to write to it?\n", bkpinfo->nfs_remote_dir, bkpinfo->nfs_mount); log_to_screen(tmp); } } if (!flag_set['d'] && (flag_set['c'] || flag_set['w'] || flag_set['C'])) { if (g_kernel_version >= 2.6) { if (popup_and_get_string ("Device", "Please specify the device", bkpinfo->media_device, MAX_STR_LEN / 4)) { retval++; log_to_screen("User opted to cancel."); } } else if (find_cdrw_device(bkpinfo->media_device)) { retval++; log_to_screen ("Tried and failed to find CD-R[W] drive automatically.\n"); } else { flag_set['d'] = TRUE; strncpy(flag_val['d'], bkpinfo->media_device, MAX_STR_LEN / 4); } } if (!flag_set['d'] && !flag_set['n'] && !flag_set['C']) { retval++; log_to_screen("Please specify the backup device/directory.\n"); fatal_error ("You didn't use -d to specify the backup device/directory."); } /* optional, obscure */ for (i = '0'; i <= '9'; i++) { if (flag_set[i]) { bkpinfo->compression_level = i - '0'; } /* not '\0' but '0' */ } if (flag_set['S']) { sprintf(bkpinfo->scratchdir, "%s/mondo.scratch.%ld", flag_val['S'], random() % 32768); } if (flag_set['T']) { sprintf(bkpinfo->tmpdir, "%s/tmp.mondo.%ld", flag_val['T'], random() % 32768); sprintf(tmp, "touch %s/.foo.dat", flag_val['T']); if (run_program_and_log_output(tmp, 1)) { retval++; log_to_screen ("Please specify a tempdir which I can write to. :)"); fatal_error("I cannot write to the tempdir you specified."); } sprintf(tmp, "ln -sf %s/.foo.dat %s/.bar.dat", flag_val['T'], flag_val['T']); if (run_program_and_log_output(tmp, 1)) { retval++; log_to_screen ("Please don't specify a SAMBA or VFAT or NFS tmpdir."); fatal_error("I cannot write to the tempdir you specified."); } } if (flag_set['A']) { strncpy(bkpinfo->call_after_iso, flag_val['A'], MAX_STR_LEN); } if (flag_set['B']) { strncpy(bkpinfo->call_before_iso, flag_val['B'], MAX_STR_LEN); } if (flag_set['F']) { g_skip_floppies = TRUE; } if (flag_set['H']) { g_cd_recovery = TRUE; } if (flag_set['l']) { #ifdef __FreeBSD__ # define BOOT_LOADER_CHARS "GLBMR" #else # ifdef __IA64__ # define BOOT_LOADER_CHARS "GER" # else # define BOOT_LOADER_CHARS "GLR" # endif #endif if (!strchr (BOOT_LOADER_CHARS, (bkpinfo->boot_loader = flag_val['l'][0]))) { log_msg(1, "%c? WTF is %c? I need G, L, E or R.", bkpinfo->boot_loader, bkpinfo->boot_loader); fatal_error ("Please specify GRUB, LILO, ELILO or RAW with the -l switch"); } #undef BOOT_LOADER_CHARS } if (flag_set['f']) { strncpy(bkpinfo->boot_device, resolve_softlinks_to_get_to_actual_device_file(flag_val ['f']), MAX_STR_LEN / 4); } if (flag_set['P']) { strncpy(bkpinfo->postnuke_tarball, flag_val['P'], MAX_STR_LEN); } if (flag_set['Q']) { i = which_boot_loader(tmp); log_msg(3, "boot loader is %c, residing at %s", i, tmp); printf("boot loader is %c, residing at %s\n", i, tmp); finish(0); } if (flag_set['L']) { bkpinfo->use_lzo = TRUE; if (run_program_and_log_output("which lzop", FALSE)) { retval++; log_to_screen ("Please install LZOP. You can't use '-L' until you do.\n"); } } if (!flag_set['o'] && !run_program_and_log_output ("egrep -i suse /etc/issue.net | egrep '9.0' | grep 64", TRUE)) { bkpinfo->make_cd_use_lilo = TRUE; log_to_screen ("Forcing you to use LILO. SuSE 9.0 (64-bit) has a broken mkfs.vfat binary."); } if (flag_set['o']) { bkpinfo->make_cd_use_lilo = TRUE; } #ifndef __FreeBSD__ else { if (!is_this_a_valid_disk_format("vfat")) { bkpinfo->make_cd_use_lilo = TRUE; log_to_screen ("Your kernel appears not to support vfat filesystems. I am therefore"); log_to_screen ("using LILO instead of SYSLINUX as the CD/floppy's boot loader."); } if (run_program_and_log_output("which mkfs.vfat", FALSE)) { bkpinfo->make_cd_use_lilo = TRUE; #ifdef __IA32__ log_to_screen ("Your filesystem is missing 'mkfs.vfat', so I cannot use SYSLINUX as"); log_to_screen ("your boot loader. I shall therefore use LILO instead."); #endif #ifdef __IA64__ log_to_screen ("Your filesystem is missing 'mkfs.vfat', so I cannot prepare the EFI"); log_to_screen("environment correctly. Please install it."); fatal_error("Aborting"); #endif } #ifdef __IA64__ /* We force ELILO usage on IA64 */ bkpinfo->make_cd_use_lilo = TRUE; #endif } #endif if (bkpinfo->make_cd_use_lilo && !does_file_exist("/boot/boot.b")) { paranoid_system("touch /boot/boot.b"); } i = flag_set['O'] + flag_set['V']; if (i == 0) { retval++; log_to_screen("Specify backup (-O), verify (-V) or both (-OV).\n"); } /* and finally... */ paranoid_free(tmp); paranoid_free(psz); return (retval); }
int run_external_binary_with_percentage_indicator_NEW(char *tt, char *cmd) { /*@ int *************************************************************** */ int res = 0; int percentage = 0; int maxpc = 100; int pcno = 0; int last_pcno = 0; int counter = 0; /*@ buffers *********************************************************** */ char *command; char *title; /*@ pointers ********************************************************** */ static int chldres = 0; int *pchild_result; pthread_t childthread; pchild_result = &chldres; assert_string_is_neither_NULL_nor_zerolength(cmd); assert_string_is_neither_NULL_nor_zerolength(tt); *pchild_result = 999; malloc_string(title); malloc_string(command); strcpy(title, tt); sprintf(command, "%s 2>> %s", cmd, MONDO_LOGFILE); log_msg(3, "command = '%s'", command); if ((res = pthread_create(&childthread, NULL, run_prog_in_bkgd_then_exit, (void *) command))) { fatal_error("Unable to create an archival thread"); } log_msg(8, "Parent running"); open_evalcall_form(title); for (sleep(1); command[0] != '\0'; sleep(1)) { pcno = grab_percentage_from_last_line_of_file(MONDO_LOGFILE); if (pcno <= 0 || pcno > 100) { log_msg(8, "Weird pc#"); continue; } percentage = pcno * 100 / maxpc; if (pcno <= 5 && last_pcno >= 40) { close_evalcall_form(); strcpy(title, "Verifying..."); open_evalcall_form(title); } if (counter++ >= 5) { counter = 0; log_file_end_to_screen(MONDO_LOGFILE, ""); } last_pcno = pcno; update_evalcall_form(percentage); } log_file_end_to_screen(MONDO_LOGFILE, ""); close_evalcall_form(); pthread_join(childthread, (void *) (&pchild_result)); if (pchild_result) { res = *pchild_result; } else { res = 666; } log_msg(3, "Parent res = %d", res); paranoid_free(command); paranoid_free(title); return (res); }
/** * Compare biggiefile number @p bigfileno with the filesystem mounted on @p MNT_RESTORING. * @param bkpinfo The backup information structure. Only used in insist_on_this_cd_number(). * @param bigfileno The biggiefile number (starting from 0) to compare. * @note This function uses an MD5 checksum. */ int compare_a_biggiefile(struct s_bkpinfo *bkpinfo, long bigfileno) { FILE *fin; FILE *fout; /** needs malloc *******/ char *checksum_ptr; char *original_cksum_ptr; char *bigfile_fname_ptr; char *tmp_ptr; char *command_ptr; char *checksum, *original_cksum, *bigfile_fname, *tmp, *command; char *p; int i; int retval = 0; struct s_filename_and_lstat_info biggiestruct; malloc_string(checksum); malloc_string(original_cksum); malloc_string(bigfile_fname); malloc_string(tmp); malloc_string(command); malloc_string(checksum_ptr); malloc_string(original_cksum_ptr); malloc_string(bigfile_fname_ptr); malloc_string(command_ptr); malloc_string(tmp_ptr); /********************************************************************* * allocate memory clear test sab 16 feb 2003 * *********************************************************************/ assert(bkpinfo != NULL); memset(checksum_ptr, '\0', sizeof(checksum)); memset(original_cksum_ptr, '\0', sizeof(original_cksum)); memset(bigfile_fname_ptr, '\0', sizeof(bigfile_fname)); memset(tmp_ptr, '\0', sizeof(tmp)); memset(command_ptr, '\0', sizeof(command)); /** end **/ if (!does_file_exist(slice_fname(bigfileno, 0, ARCHIVES_PATH, ""))) { if (does_file_exist(MNT_CDROM "/archives/NOT-THE-LAST")) { insist_on_this_cd_number(bkpinfo, (++g_current_media_number)); } else { sprintf(tmp_ptr, "No CD's left. No biggiefiles left. No prob, Bob."); log_msg(2, tmp_ptr); return (0); } } if (!(fin = fopen(slice_fname(bigfileno, 0, ARCHIVES_PATH, ""), "r"))) { sprintf(tmp_ptr, "Cannot open bigfile %ld (%s)'s info file", bigfileno + 1, bigfile_fname_ptr); log_to_screen(tmp_ptr); return (1); } fread((void *) &biggiestruct, 1, sizeof(biggiestruct), fin); paranoid_fclose(fin); strcpy(checksum_ptr, biggiestruct.checksum); strcpy(bigfile_fname_ptr, biggiestruct.filename); log_msg(2, "biggiestruct.filename = %s", biggiestruct.filename); log_msg(2, "biggiestruct.checksum = %s", biggiestruct.checksum); sprintf(tmp_ptr, "Comparing %s", bigfile_fname_ptr); if (!g_text_mode) { newtDrawRootText(0, 22, tmp_ptr); newtRefresh(); } if (!checksum[0]) { log_msg(2, "Warning - %s has no checksum", bigfile_fname_ptr); } if (!strncmp(bigfile_fname_ptr, "/dev/", 5)) { strcpy(original_cksum_ptr, "IGNORE"); } else { sprintf(command_ptr, "md5sum \"%s%s\" > /tmp/md5sum.txt 2> /tmp/errors.txt", MNT_RESTORING, bigfile_fname_ptr); } log_msg(2, command_ptr); paranoid_system ("cat /tmp/errors >> /tmp/mondo-restore.log 2> /dev/null"); if (system(command_ptr)) { log_OS_error("Warning - command failed"); original_cksum[0] = '\0'; return (1); } else { if (!(fin = fopen("/tmp/md5sum.txt", "r"))) { log_msg(2, "Unable to open /tmp/md5sum.txt; can't get live checksum"); original_cksum[0] = '\0'; return (1); } else { fgets(original_cksum_ptr, MAX_STR_LEN - 1, fin); paranoid_fclose(fin); for (i = strlen(original_cksum_ptr); i > 0 && original_cksum[i - 1] < 32; i--); original_cksum[i] = '\0'; p = (char *) strchr(original_cksum_ptr, ' '); if (p) { *p = '\0'; } } } sprintf(tmp_ptr, "bigfile #%ld ('%s') ", bigfileno + 1, bigfile_fname_ptr); if (!strcmp(checksum_ptr, original_cksum_ptr) != 0) { strcat(tmp_ptr, " ... OK"); } else { strcat(tmp_ptr, "... changed"); retval++; } log_msg(1, tmp_ptr); if (retval) { if (!(fout = fopen("/tmp/changed.txt", "a"))) { fatal_error("Cannot openout changed.txt"); } fprintf(fout, "%s\n", bigfile_fname_ptr); paranoid_fclose(fout); } paranoid_free(original_cksum_ptr); paranoid_free(original_cksum); paranoid_free(bigfile_fname_ptr); paranoid_free(bigfile_fname); paranoid_free(checksum_ptr); paranoid_free(checksum); paranoid_free(command_ptr); paranoid_free(command); paranoid_free(tmp_ptr); paranoid_free(tmp); return (retval); }
/** * Open a pipe to/from @c buffer. * If buffer does not work at all, we use `dd'. * @param device The device to read from/write to. * @param direction @c 'r' (reading) or @c 'w' (writing). * @return A file pointer to/from the @c buffer process. */ FILE *open_device_via_buffer(char *device, char direction, long internal_tape_block_size) { char sz_dir[32]; char keych; char *tmp; char *command; FILE *fres; int bufsize; // in megabytes int res; int wise_upper_limit; int wise_lower_limit; malloc_string(tmp); malloc_string(command); assert_string_is_neither_NULL_nor_zerolength(device); assert(direction == 'w' || direction == 'r'); sprintf(sz_dir, "%c", direction); wise_upper_limit = (am_I_in_disaster_recovery_mode()? 8 : 32); wise_lower_limit = 1; // wise_upper_limit/2 + 1; paranoid_system("sync"); for (bufsize = wise_upper_limit, res = -1; res != 0 && bufsize >= wise_lower_limit; bufsize--) { sprintf(tmp, "dd if=/dev/zero bs=1024 count=16k 2> /dev/null | buffer -o /dev/null -s %ld -m %d%c", internal_tape_block_size, bufsize, 'm'); res = run_program_and_log_output(tmp, 2); } if (!res) { bufsize++; sprintf(tmp, "Negotiated max buffer of %d MB ", bufsize); log_to_screen(tmp); } else { bufsize = 0; res = 0; log_to_screen ("Cannot negotiate a buffer of ANY size. Using dd instead."); } if (direction == 'r') { keych = 'i'; } else { keych = 'o'; } if (bufsize) { sprintf(g_sz_call_to_buffer, "buffer -m %d%c -p%d -B -s%ld -%c %s 2>> %s", bufsize, 'm', (direction == 'r') ? 20 : 75, internal_tape_block_size, keych, device, MONDO_LOGFILE); } else { sprintf(g_sz_call_to_buffer, "dd bs=%ld %cf=%s", internal_tape_block_size, keych, device); } log_msg(2, "Calling buffer --- command = '%s'", g_sz_call_to_buffer); fres = popen(g_sz_call_to_buffer, sz_dir); if (fres) { log_msg(2, "Successfully opened ('%c') tape device %s", direction, device); } else { log_msg(2, "Failed to open ('%c') tape device %s", direction, device); } sleep(2); sprintf(tmp, "ps wwax | grep \"%s\"", g_sz_call_to_buffer); if (run_program_and_log_output(tmp, 2)) { log_msg(2, "Warning - I think I failed to open tape, actually."); } g_tape_buffer_size_MB = bufsize; strcmp(tmp, g_sz_call_to_buffer); tmp[30] = '\0'; sprintf(command, "ps wwax | grep buffer | grep -v grep"); if (run_program_and_log_output(command, 1)) { fres = NULL; log_to_screen("Failed to open tape streamer. Buffer error."); } else { log_to_screen("Buffer successfully started."); } paranoid_free(command); paranoid_free(tmp); return (fres); }
int run_external_binary_with_percentage_indicator_OLD(char *tt, char *cmd) { /*@ int *************************************************************** */ int res = 0; int percentage = 0; int maxpc = 0; int pcno = 0; int last_pcno = 0; /*@ buffers *********************************************************** */ char *command; char *tempfile; char *title; /*@ pointers ********************************************************** */ FILE *pin; malloc_string(title); malloc_string(command); malloc_string(tempfile); assert_string_is_neither_NULL_nor_zerolength(cmd); assert_string_is_neither_NULL_nor_zerolength(title); strcpy(title, tt); strcpy(tempfile, call_program_and_get_last_line_of_output ("mktemp -q /tmp/mondo.XXXXXXXX")); sprintf(command, "%s >> %s 2>> %s; rm -f %s", cmd, tempfile, tempfile, tempfile); log_msg(3, command); open_evalcall_form(title); if (!(pin = popen(command, "r"))) { log_OS_error("fmt err"); return (1); } maxpc = 100; // OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD for (sleep(1); does_file_exist(tempfile); sleep(1)) { pcno = grab_percentage_from_last_line_of_file(MONDO_LOGFILE); if (pcno < 0 || pcno > 100) { log_msg(5, "Weird pc#"); continue; } percentage = pcno * 100 / maxpc; if (pcno <= 5 && last_pcno > 40) { close_evalcall_form(); strcpy(title, "Verifying..."); open_evalcall_form(title); } last_pcno = pcno; update_evalcall_form(percentage); } // OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD OLD close_evalcall_form(); if (pclose(pin)) { res++; log_OS_error("Unable to pclose"); } unlink(tempfile); paranoid_free(command); paranoid_free(tempfile); paranoid_free(title); return (res); }
/** * Verify one afioball from the CD. * You should be changed to the root directory (/) for this to work. * @param bkpinfo The backup information structure. Fields used: * - @c bkpinfo->use_lzo * - @c bkpinfo->tmpdir * - @c bkpinfo->zip_exe * - @c bkpinfo->zip_suffix * @param tarball_fname The filename of the afioball to verify. * @return 0, always. */ int verify_a_tarball(struct s_bkpinfo *bkpinfo, char *tarball_fname) { /*@ buffers ********************************************************* */ char *command; char *outlog; char *tmp; // char *p; /*@ pointers ******************************************************* */ FILE *pin; /*@ long *********************************************************** */ long diffs = 0; /* getcwd(old_pwd,MAX_STR_LEN-1); */ command = malloc(2000); malloc_string(outlog); malloc_string(tmp); assert(bkpinfo != NULL); assert_string_is_neither_NULL_nor_zerolength(tarball_fname); log_it("Verifying fileset '%s'", tarball_fname); /* chdir("/"); */ sprintf(outlog, "%s/afio.log", bkpinfo->tmpdir); /* if programmer forgot to say which compression thingy to use then find out */ if (strstr(tarball_fname, ".lzo") && strcmp(bkpinfo->zip_suffix, "lzo")) { log_msg(2, "OK, I'm going to start using lzop."); strcpy(bkpinfo->zip_exe, "lzop"); strcpy(bkpinfo->zip_suffix, "lzo"); bkpinfo->use_lzo = TRUE; } if (strstr(tarball_fname, ".bz2") && strcmp(bkpinfo->zip_suffix, "bz2")) { log_msg(2, "OK, I'm going to start using bzip2."); strcpy(bkpinfo->zip_exe, "bzip2"); strcpy(bkpinfo->zip_suffix, "bz2"); bkpinfo->use_lzo = FALSE; } unlink(outlog); if (strstr(tarball_fname, ".star")) { bkpinfo->use_star = TRUE; if (strstr(tarball_fname, ".bz2")) sprintf(command, "star -diff diffopts=mode,size,data file=%s %s >> %s 2>> %s", tarball_fname, (strstr(tarball_fname, ".bz2")) ? "-bz" : " ", outlog, outlog); } else { bkpinfo->use_star = FALSE; sprintf(command, "afio -r -P %s -Z %s >> %s 2>> %s", bkpinfo->zip_exe, tarball_fname, outlog, outlog); } log_msg(6, "command=%s", command); paranoid_system(command); if (length_of_file(outlog) < 10) { sprintf(command, "cat %s >> %s", outlog, MONDO_LOGFILE); } else { sprintf(command, "cat %s | cut -d':' -f%d | sort | uniq", outlog, (bkpinfo->use_star) ? 1 : 2); pin = popen(command, "r"); if (pin) { for (fgets(tmp, MAX_STR_LEN, pin); !feof(pin); fgets(tmp, MAX_STR_LEN, pin)) { if (bkpinfo->use_star) { if (!strstr(tmp, "diffopts=")) { while (strlen(tmp) > 0 && tmp[strlen(tmp) - 1] < 32) { tmp[strlen(tmp) - 1] = '\0'; } if (strchr(tmp, '/')) { if (!diffs) { log_msg(0, "'%s' - differences found", tarball_fname); } log_msg(0, "star: /%s", strip_afio_output_line(tmp)); diffs++; } } } else { if (!diffs) { log_msg(0, "'%s' - differences found", tarball_fname); } log_msg(0, "afio: /%s", strip_afio_output_line(tmp)); diffs++; } } paranoid_pclose(pin); } else { log_OS_error(command); } } /* chdir(old_pwd); */ // sprintf (tmp, "cat %s | uniq -u >> %s", "/tmp/mondo-verify.err", MONDO_LOGFILE); // paranoid_system (tmp); // unlink ("/tmp/mondo-verify.err"); paranoid_free(command); paranoid_free(outlog); paranoid_free(tmp); return (0); }
/** * Call mkisofs to create an ISO image. * @param bkpinfo The backup information structure. Fields used: * - @c bkpinfo->manual_cd_tray * - @c bkpinfo->backup_media_type * - @c bkpinfo->please_dont_eject_when_restoring * @param basic_call The call to mkisofs. May contain tokens that will be resolved to actual data. The tokens are: * - @c _ISO_ will become the ISO file (@p isofile) * - @c _CD#_ becomes the CD number (@p cd_no) * - @c _ERR_ becomes the logfile (@p g_logfile) * @param isofile Replaces @c _ISO_ in @p basic_call. Should probably be the ISO image to create (-o parameter to mkisofs). * @param cd_no Replaces @c _CD#_ in @p basic_call. Should probably be the CD number. * @param logstub Unused. * @param what_i_am_doing The action taking place (e.g. "Making ISO #1"). Used as the title of the progress dialog. * @return Exit code of @c mkisofs (0 is success, anything else indicates failure). * @bug @p logstub is unused. */ int eval_call_to_make_ISO(struct s_bkpinfo *bkpinfo, char *basic_call, char *isofile, int cd_no, char *logstub, char *what_i_am_doing) { /*@ int's *** */ int retval = 0; /*@ buffers *** */ char *midway_call, *ultimate_call, *tmp, *command, *incoming, *old_stderr, *cd_number_str; char *p; /*@*********** End Variables ***************************************/ log_msg(3, "Starting"); assert(bkpinfo != NULL); assert_string_is_neither_NULL_nor_zerolength(basic_call); assert_string_is_neither_NULL_nor_zerolength(isofile); assert_string_is_neither_NULL_nor_zerolength(logstub); if (!(midway_call = malloc(1200))) { fatal_error("Cannot malloc midway_call"); } if (!(ultimate_call = malloc(1200))) { fatal_error("Cannot malloc ultimate_call"); } if (!(tmp = malloc(1200))) { fatal_error("Cannot malloc tmp"); } if (!(command = malloc(1200))) { fatal_error("Cannot malloc command"); } malloc_string(incoming); malloc_string(old_stderr); malloc_string(cd_number_str); incoming[0] = '\0'; old_stderr[0] = '\0'; sprintf(cd_number_str, "%d", cd_no); resolve_naff_tokens(midway_call, basic_call, isofile, "_ISO_"); resolve_naff_tokens(tmp, midway_call, cd_number_str, "_CD#_"); resolve_naff_tokens(ultimate_call, tmp, MONDO_LOGFILE, "_ERR_"); log_msg(4, "basic call = '%s'", basic_call); log_msg(4, "midway_call = '%s'", midway_call); log_msg(4, "tmp = '%s'", tmp); log_msg(4, "ultimate call = '%s'", ultimate_call); sprintf(command, "%s >> %s", ultimate_call, MONDO_LOGFILE); log_to_screen ("Please be patient. Do not be alarmed by on-screen inactivity."); log_msg(4, "Calling open_evalcall_form() with what_i_am_doing='%s'", what_i_am_doing); strcpy(tmp, command); if (bkpinfo->manual_cd_tray) { p = strstr(tmp, "2>>"); if (p) { sprintf(p, " "); while (*p == ' ') { p++; } for (; *p != ' '; p++) { *p = ' '; } } strcpy(command, tmp); #ifndef _XWIN if (!g_text_mode) { newtSuspend(); } #endif log_msg(1, "command = '%s'", command); retval += system(command); if (!g_text_mode) { newtResume(); } if (retval) { log_msg(2, "Basic call '%s' returned an error.", basic_call); popup_and_OK("Press ENTER to continue."); popup_and_OK ("mkisofs and/or cdrecord returned an error. CD was not created"); } } /* if text mode then do the above & RETURN; if not text mode, do this... */ else { log_msg(3, "command = '%s'", command); // yes_this_is_a_goto: retval = run_external_binary_with_percentage_indicator_NEW (what_i_am_doing, command); } paranoid_free(midway_call); paranoid_free(ultimate_call); paranoid_free(tmp); paranoid_free(command); paranoid_free(incoming); paranoid_free(old_stderr); paranoid_free(cd_number_str); /* if (bkpinfo->backup_media_type == dvd && !bkpinfo->please_dont_eject_when_restoring) { log_msg(3, "Ejecting DVD device"); eject_device(bkpinfo->media_device); } */ return (retval); }
static void _b_torrent_init (b_torrent* tt, b_encode* bp) { b_dict* bd = bp->data.dpv; char buf[1024]; // printf("type=%d\n", bp->type); while(NULL != bd) { // printf("key=%s\n", bd->key); unsigned int key_len = strlen(bd->key); if(strncmp("announce-list", bd->key, max(key_len, 13)) == 0) { b_list* bl = bd->value->data.lpv; b_torrent_tracker head; b_torrent_tracker* tp = &head; tt->tracker_len = 0; while(NULL != bl) { b_encode* bll = bl->item->data.lpv->item; tp = tp->next = malloc_tracker(bll->data.cpv, bll->len); // printf("%s\n", tp->url); bl = bl->next; tt->tracker_len++; } tt->tracker = head.next; } if(strncmp("announce", bd->key, max(key_len, 8)) == 0) { tt->tracker_len = 0; if (NULL == tt->tracker) { b_encode* bp = bd->value; tt->tracker = malloc_tracker(bp->data.cpv, bp->len); tt->tracker_len = 1; } } if(strncmp("comment", bd->key, max(key_len, 7)) == 0) { tt->comment = malloc_string(bd->value->data.cpv, bd->value->len); } if(strncmp("encoding", bd->key, max(key_len, 8)) == 0) { tt->encoding = malloc_string(bd->value->data.cpv, bd->value->len); } if(strncmp("created by", bd->key, max(key_len, 10)) == 0) { tt->created_by = malloc_string(bd->value->data.cpv, bd->value->len); } if(strncmp("creation date", bd->key, max(key_len, 13)) == 0) { tt->create_date = bd->value->data.iv; } if (strncmp("length", bd->key, max(key_len, 6)) == 0) { tt->total_size = bd->value->data.iv; } if (strncmp("name", bd->key, max(key_len, 4)) == 0) { tt->name = malloc_string(bd->value->data.cpv, bd->value->len); } else if (strncmp("pieces", bd->key, max(key_len, 6)) == 0) { tt->pieces = malloc_string(bd->value->data.cpv, bd->value->len); } else if (strncmp("piece length", bd->key, max(key_len, 12)) == 0) { tt->piece_size = bd->value->data.iv; } else if (strncmp("files", bd->key, max(key_len, 5)) == 0) { b_list* list = bd->value->data.lpv; b_torrent_file head; b_torrent_file* tf = &head; tt->file_len = 0; while (list) { b_dict* ldict = list->item->data.dpv; int64_t size; unsigned int len = 0; for (; ldict != NULL; ldict = ldict->next) { key_len = strlen(ldict->key); if (strncmp("length", ldict->key, max(key_len, 6)) == 0) { size = ldict->value->data.iv; } if (strncmp("path", ldict->key, max(key_len, 4)) == 0) { b_list* paths = ldict->value->data.lpv; while (NULL != paths) { memcpy(buf + len, paths->item->data.cpv, paths->item->len); len += paths->item->len; paths = paths->next; } buf[len] = '\0'; } } // printf("file buffer: %s:%d\n", buf, size); tf = tf->next = malloc_file(buf, len, size); list = list->next; // set total size tt->total_size += size; tt->file_len++; // printf("%llu\n", (unsigned long long)tt->total_size); } tt->file = head.next; } else if (strncmp("info", bd->key, max(key_len, 4)) == 0) { _b_torrent_init(tt, bd->value); SHA1_CTX context; SHA1Init(&context); SHA1Update(&context, (unsigned char*)&bd->value->begin[0], bd->value->len); SHA1Final(tt->info_hash, &context); // tt->info_hash[20] = '\0'; } bd = bd->next; } // set peer_id srand_curr_time; sprintf((char*)tt->peer_id, "-XOY1000-%d", rand()); }
/** * Verify all afioballs from the opened tape/CD stream. * @param bkpinfo The backup information structure. Fields used: * - @c bkpinfo->restore_path * - @c bkpinfo->tmpdir * * @return 0 for success (even if there are differences); nonzero for a tape error. */ int verify_afioballs_from_stream(struct s_bkpinfo *bkpinfo) { /*@ int ********************************************************** */ int retval = 0; int res = 0; long current_afioball_number = 0; int ctrl_chr = 0; int total_afioballs = 0; /*@ buffers ***************************************************** */ char *tmp; char *fname; char *curr_xattr_list_fname; char *curr_acl_list_fname; /*@ long long *************************************************** */ long long size = 0; assert(bkpinfo != NULL); malloc_string(tmp); malloc_string(fname); malloc_string(curr_xattr_list_fname); malloc_string(curr_acl_list_fname); sprintf(curr_xattr_list_fname, XATTR_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir); sprintf(curr_acl_list_fname, ACL_BIGGLST_FNAME_RAW_SZ, bkpinfo->tmpdir); log_to_screen("Verifying regular archives on tape"); total_afioballs = get_last_filelist_number(bkpinfo) + 1; open_progress_form("Verifying filesystem", "I am verifying archives against your live filesystem now.", "Please wait. This may take a couple of hours.", "", total_afioballs); res = read_header_block_from_stream(&size, fname, &ctrl_chr); if (ctrl_chr != BLK_START_AFIOBALLS) { iamhere("YOU SHOULD NOT GET HERE"); iamhere("Grabbing the EXAT files"); if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) { res = read_EXAT_files_from_tape(bkpinfo, &size, fname, &ctrl_chr, curr_xattr_list_fname, curr_acl_list_fname); } } if (ctrl_chr != BLK_START_AFIOBALLS) { wrong_marker(BLK_START_AFIOBALLS, ctrl_chr); } for (res = read_header_block_from_stream(&size, fname, &ctrl_chr); ctrl_chr != BLK_STOP_AFIOBALLS; res = read_header_block_from_stream(&size, fname, &ctrl_chr)) { sprintf(curr_xattr_list_fname, XATTR_LIST_FNAME_RAW_SZ, bkpinfo->tmpdir, current_afioball_number); sprintf(curr_acl_list_fname, ACL_LIST_FNAME_RAW_SZ, bkpinfo->tmpdir, current_afioball_number); if (ctrl_chr == BLK_START_EXTENDED_ATTRIBUTES) { iamhere("Reading EXAT files from tape"); res = read_EXAT_files_from_tape(bkpinfo, &size, fname, &ctrl_chr, curr_xattr_list_fname, curr_acl_list_fname); } if (ctrl_chr != BLK_START_AN_AFIO_OR_SLICE) { wrong_marker(BLK_START_AN_AFIO_OR_SLICE, ctrl_chr); } sprintf(tmp, "Verifying fileset #%ld", current_afioball_number); /*log_it(tmp); */ update_progress_form(tmp); res = verify_an_afioball_from_stream(bkpinfo, fname, size); if (res) { sprintf(tmp, "Afioball %ld differs from live filesystem", current_afioball_number); log_to_screen(tmp); } retval += res; current_afioball_number++; g_current_progress++; res = read_header_block_from_stream(&size, fname, &ctrl_chr); if (ctrl_chr != BLK_STOP_AN_AFIO_OR_SLICE) { wrong_marker(BLK_STOP_AN_AFIO_OR_SLICE, ctrl_chr); } } log_msg(1, "All done with afioballs"); close_progress_form(); paranoid_free(tmp); paranoid_free(fname); paranoid_free(curr_xattr_list_fname); paranoid_free(curr_acl_list_fname); return (retval); }
/** * Verify the CD indicated by @c g_current_media_number. * @param bkpinfo The backup information structure. Fields used: * - @c bkpinfo->isodir * - @c bkpinfo->prefix * - @c bkpinfo->manual_cd_tray * - @c bkpinfo->media_device * - @c bkpinfo->nfs_remote_dir * - @c bkpinfo->tmpdir * - @c bkpinfo->verify_data * * @return 0 for success (even if differences are found), nonzero for failure. * @ingroup verifyGroup */ int verify_cd_image(struct s_bkpinfo *bkpinfo) { /*@ int ************************************************************ */ int retval = 0; /*@ buffers ******************************************************** */ char *mountpoint; char *command; char *tmp; char *fname; #ifdef __FreeBSD__ char mdd[32]; char *mddevice = mdd; int ret = 0; int vndev = 2; #else //skip #endif command = malloc(2000); malloc_string(mountpoint); malloc_string(tmp); malloc_string(fname); assert(bkpinfo != NULL); sprintf(mountpoint, "%s/cdrom", bkpinfo->tmpdir); sprintf(fname, "%s/%s/%s-%d.iso", bkpinfo->nfs_remote_dir, bkpinfo->isodir, bkpinfo->prefix, g_current_media_number); mkdir(mountpoint, 1777); sync(); if (!does_file_exist(fname)) { sprintf(tmp, "%s not found; assuming you backed up to CD; verifying CD...", fname); log_msg(2, tmp); if (bkpinfo->manual_cd_tray) { popup_and_OK("Please push CD tray closed."); } if (find_and_mount_actual_cd(bkpinfo, mountpoint)) { log_to_screen("failed to mount actual CD"); return (1); } } else { sprintf(tmp, "%s found; verifying ISO...", fname); #ifdef __FreeBSD__ ret = 0; vndev = 2; mddevice = make_vn(fname); if (ret) { sprintf(tmp, "make_vn of %s failed; unable to verify ISO\n", fname); log_to_screen(tmp); return (1); } sprintf(command, "mount_cd9660 %s %s", mddevice, mountpoint); #else sprintf(command, "mount -o loop,ro -t iso9660 %s %s", fname, mountpoint); #endif if (run_program_and_log_output(command, FALSE)) { sprintf(tmp, "%s failed; unable to mount ISO image\n", command); log_to_screen(tmp); return (1); } } log_msg(2, "OK, I've mounted the ISO/CD\n"); sprintf(tmp, "%s/archives/NOT-THE-LAST", mountpoint); if (!does_file_exist(tmp)) { log_msg (2, "This is the last CD. I am therefore setting bkpinfo->verify_data to FALSE."); bkpinfo->verify_data = FALSE; /* (a) It's an easy way to tell the calling subroutine that we've finished & there are no more CD's to be verified; (b) It stops the post-backup verifier from running after the per-CD verifier has run too. */ } verify_afioballs_on_CD(bkpinfo, mountpoint); iamhere("before verify_all_slices"); verify_all_slices_on_CD(bkpinfo, mountpoint); #ifdef __FreeBSD__ ret = 0; sprintf(command, "umount %s", mountpoint); ret += system(command); ret += kick_vn(mddevice); if (ret) #else sprintf(command, "umount %s", mountpoint); if (system(command)) #endif { sprintf(tmp, "%s failed; unable to unmount ISO image\n", command); log_to_screen(tmp); retval++; } else { log_msg(2, "OK, I've unmounted the ISO file\n"); } if (!does_file_exist(fname)) { sprintf(command, "umount %s", bkpinfo->media_device); run_program_and_log_output(command, 2); if (!bkpinfo->please_dont_eject && eject_device(bkpinfo->media_device)) { log_msg(2, "Failed to eject CD-ROM drive"); } } paranoid_free(command); paranoid_free(mountpoint); paranoid_free(tmp); paranoid_free(fname); return (retval); }
/** * Verify one biggiefile form the opened tape/CD stream. * @param bkpinfo The backup information structure. @c bkpinfo->tmpdir is the only field used. * @param biggie_fname The filename of the biggiefile to verify. * @param size The size in bytes of said biggiefile. * @return 0 for success (even if the file doesn't match); nonzero for a tape error. */ int verify_a_biggiefile_from_stream(struct s_bkpinfo *bkpinfo, char *biggie_fname, long long size) { /*@ int ************************************************************* */ int retval = 0; int res = 0; int current_slice_number = 0; int ctrl_chr = '\0'; /*@ char ************************************************************ */ char *test_file; char *biggie_cksum; char *orig_cksum; char *tmp; char *slice_fnam; /*@ pointers ******************************************************** */ char *p; /*@ long long ******************************************************* */ long long slice_siz; malloc_string(test_file); malloc_string(biggie_cksum); malloc_string(orig_cksum); malloc_string(tmp); malloc_string(slice_fnam); assert(bkpinfo != NULL); assert_string_is_neither_NULL_nor_zerolength(biggie_fname); p = strrchr(biggie_fname, '/'); if (!p) { p = biggie_fname; } else { p++; } sprintf(test_file, "%s/temporary-%s", bkpinfo->tmpdir, p); sprintf(tmp, "Temporarily copying biggiefile %s's slices from tape to '%s'", p, test_file); /* log_it(tmp); */ for (res = read_header_block_from_stream(&slice_siz, slice_fnam, &ctrl_chr); ctrl_chr != BLK_STOP_A_BIGGIE; res = read_header_block_from_stream(&slice_siz, slice_fnam, &ctrl_chr)) { if (ctrl_chr != BLK_START_AN_AFIO_OR_SLICE) { wrong_marker(BLK_START_AN_AFIO_OR_SLICE, ctrl_chr); } res = read_file_from_stream_to_file(bkpinfo, test_file, slice_siz); unlink(test_file); res = read_header_block_from_stream(&slice_siz, slice_fnam, &ctrl_chr); if (ctrl_chr != BLK_STOP_AN_AFIO_OR_SLICE) { log_msg(2, "test_file = %s", test_file); wrong_marker(BLK_STOP_AN_AFIO_OR_SLICE, ctrl_chr); } current_slice_number++; retval += res; } strcpy(biggie_cksum, slice_fnam); if (biggie_cksum[0] != '\0') { strcpy(orig_cksum, calc_checksum_of_file(biggie_fname)); if (strcmp(biggie_cksum, orig_cksum)) { sprintf(tmp, "orig cksum=%s; curr cksum=%s", biggie_cksum, orig_cksum); log_msg(2, tmp); sprintf(tmp, "%s has changed on live filesystem", biggie_fname); log_to_screen(tmp); sprintf(tmp, "echo \"%s\" >> /tmp/biggies.changed", biggie_fname); system(tmp); } } paranoid_free(test_file); paranoid_free(biggie_cksum); paranoid_free(orig_cksum); paranoid_free(tmp); paranoid_free(slice_fnam); return (retval); }
/** * Populate @p bkpinfo from the command-line parameters stored in @p argc and @p argv. * @param argc The argument count, including the program name; @p argc passed to main(). * @param argv The argument vector; @p argv passed to main(). * @param bkpinfo The backup information structure to populate. * @return The number of problems with the command line (0 for success). */ int handle_incoming_parameters(int argc, char *argv[], struct s_bkpinfo *bkpinfo) { /*@ int *** */ int res = 0; int retval = 0; int i = 0, j; /*@ buffers *************** */ char *tmp; char flag_val[128][MAX_STR_LEN]; bool flag_set[128]; malloc_string(tmp); sensibly_set_tmpdir_and_scratchdir(bkpinfo); for (i = 0; i < 128; i++) { flag_val[i][0] = '\0'; flag_set[i] = FALSE; } // strcpy (bkpinfo->tmpdir, "/root/images/mondo"); // strcpy (bkpinfo->scratchdir, "/home"); for (j = 1; j <= MAX_NOOF_MEDIA; j++) { bkpinfo->media_size[j] = 650; } /* default */ res = retrieve_switches_from_command_line(argc, argv, flag_val, flag_set); retval += res; if (!retval) { res = process_switches(bkpinfo, flag_val, flag_set); retval += res; } /* if (!retval) { */ log_msg(3, "Switches:-"); for (i = 0; i < 128; i++) { if (flag_set[i]) { sprintf(tmp, "-%c %s", i, flag_val[i]); log_msg(3, tmp); } } // } sprintf(tmp, "rm -Rf %s/tmp.mondo.*", bkpinfo->tmpdir); paranoid_system(tmp); sprintf(tmp, "rm -Rf %s/mondo.scratch.*", bkpinfo->scratchdir); paranoid_system(tmp); sprintf(bkpinfo->tmpdir + strlen(bkpinfo->tmpdir), "/tmp.mondo.%ld", random() % 32767); sprintf(bkpinfo->scratchdir + strlen(bkpinfo->scratchdir), "/mondo.scratch.%ld", random() % 32767); sprintf(tmp, "mkdir -p %s/tmpfs", bkpinfo->tmpdir); paranoid_system(tmp); sprintf(tmp, "mkdir -p %s", bkpinfo->scratchdir); paranoid_system(tmp); if (bkpinfo->nfs_mount[0] != '\0') { store_nfs_config(bkpinfo); } paranoid_free(tmp); return (retval); }
int copy_from_src_to_dest(FILE * f_orig, FILE * f_archived, char direction) { // if dir=='w' then copy from orig to archived // if dir=='r' then copy from archived to orig char *tmp; char *buf; long int bytes_to_be_read, bytes_read_in, bytes_written_out = 0, bufcap, subsliceno = 0; int retval = 0; FILE *fin; FILE *fout; FILE *ftmp; log_msg(5, "Opening."); malloc_string(tmp); tmp[0] = '\0'; bufcap = 256L * 1024L; if (!(buf = malloc(bufcap))) { fatal_error("Failed to malloc() buf"); } if (direction == 'w') { fin = f_orig; fout = f_archived; sprintf(tmp, "%-64s", PIMP_START_SZ); if (fwrite(tmp, 1, 64, fout) != 64) { fatal_error("Can't write the introductory block"); } while (1) { bytes_to_be_read = bytes_read_in = fread(buf, 1, bufcap, fin); if (bytes_read_in == 0) { break; } sprintf(tmp, "%-64ld", bytes_read_in); if (fwrite(tmp, 1, 64, fout) != 64) { fatal_error("Cannot write introductory block"); } log_msg(7, "subslice #%ld --- I have read %ld of %ld bytes in from f_orig", subsliceno, bytes_read_in, bytes_to_be_read); bytes_written_out += fwrite(buf, 1, bytes_read_in, fout); sprintf(tmp, "%-64ld", subsliceno); if (fwrite(tmp, 1, 64, fout) != 64) { fatal_error("Cannot write post-thingy block"); } log_msg(7, "Subslice #%d written OK", subsliceno); subsliceno++; } sprintf(tmp, "%-64ld", 0L); if (fwrite(tmp, 1, 64L, fout) != 64L) { fatal_error("Cannot write final introductory block"); } } else { fin = f_archived; fout = f_orig; if (fread(tmp, 1, 64L, fin) != 64L) { fatal_error("Cannot read the introductory block"); } log_msg(5, "tmp is %s", tmp); if (!strstr(tmp, PIMP_START_SZ)) { fatal_error("Can't find intro blk"); } if (fread(tmp, 1, 64L, fin) != 64L) { fatal_error("Cannot read introductory blk"); } bytes_to_be_read = atol(tmp); while (bytes_to_be_read > 0) { log_msg(7, "subslice#%ld, bytes=%ld", subsliceno, bytes_to_be_read); bytes_read_in = fread(buf, 1, bytes_to_be_read, fin); if (bytes_read_in != bytes_to_be_read) { fatal_error ("Danger, WIll Robinson. Failed to read whole subvol from archives."); } bytes_written_out += fwrite(buf, 1, bytes_read_in, fout); if (fread(tmp, 1, 64, fin) != 64) { fatal_error("Cannot read post-thingy block"); } if (atol(tmp) != subsliceno) { log_msg(1, "Wanted subslice %ld but got %ld ('%s')", subsliceno, atol(tmp), tmp); } log_msg(7, "Subslice #%ld read OK", subsliceno); subsliceno++; if (fread(tmp, 1, 64, fin) != 64) { fatal_error("Cannot read introductory block"); } bytes_to_be_read = atol(tmp); } } // log_msg(4, "Written %ld of %ld bytes", bytes_written_out, bytes_read_in); if (direction == 'w') { sprintf(tmp, "%-64s", PIMP_END_SZ); if (fwrite(tmp, 1, 64, fout) != 64) { fatal_error("Can't write the final block"); } } else { log_msg(1, "tmpA is %s", tmp); if (!strstr(tmp, PIMP_END_SZ)) { if (fread(tmp, 1, 64, fin) != 64) { fatal_error("Can't read the final block"); } log_msg(5, "tmpB is %s", tmp); if (!strstr(tmp, PIMP_END_SZ)) { ftmp = fopen("/tmp/out.leftover", "w"); bytes_read_in = fread(tmp, 1, 64, fin); log_msg(1, "bytes_read_in = %ld", bytes_read_in); // if (bytes_read_in!=128+64) { fatal_error("Can't read the terminating block"); } fwrite(tmp, 1, bytes_read_in, ftmp); sprintf(tmp, "I am here - %llu", ftello(fin)); // log_msg(0, tmp); fread(tmp, 1, 512, fin); log_msg(0, "tmp = '%s'", tmp); fwrite(tmp, 1, 512, ftmp); fclose(ftmp); fatal_error("Missing terminating block"); } } } paranoid_free(buf); paranoid_free(tmp); log_msg(3, "Successfully copied %ld bytes", bytes_written_out); return (retval); }
static b_torrent_file* malloc_file(char* str, int strlen, int64_t file_size) { b_torrent_file* tf = malloc(sizeof(b_torrent_file)); tf->size = file_size; tf->name = malloc_string(str, strlen); return tf; }