/**************************************************************************
 * 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);
}
Esempio n. 3
0
/* ------------------------------------------------------------------------- */
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);
}
Esempio n. 8
0
/* ------------------------------------------------------------------------- */
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);
}
Esempio n. 16
0
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;
}
Esempio n. 17
0
/**
 * 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);
}
Esempio n. 24
0
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);
}
Esempio n. 28
0
/**
 * 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);
}
Esempio n. 30
0
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;
}