예제 #1
0
    void archive_options_isolate::set_entrepot(const entrepot & entr)
    {
	if(x_entrepot != NULL)
	    delete x_entrepot;

	x_entrepot = entr.clone();
	if(x_entrepot == NULL)
	    throw Ememory("archive_options_isolate::set_entrepot");
    }
예제 #2
0
파일: fichier.cpp 프로젝트: bradc6/libdar
    void fichier_global::copy_from(const fichier_global & ref)
    {
	if(ref.x_dialog != NULL)
	{
	    x_dialog = ref.x_dialog->clone();
	    if(x_dialog == NULL)
		throw Ememory("fichier_global::copy_from");
	}
	else
	    x_dialog = NULL;
    }
예제 #3
0
    void archive_options_listing::set_user_slicing(const infinint & slicing_first, const infinint & slicing_others)
    {
	if(x_slicing_first == NULL)
	{
	    x_slicing_first = new (get_pool()) infinint(slicing_first);
	    if(x_slicing_first == NULL)
		throw Ememory("archive_options_listing::set_user_slicing");
	}
	else
	    *x_slicing_first = slicing_first;

	if(x_slicing_others == NULL)
	{
	    x_slicing_others = new (get_pool()) infinint(slicing_others);
	    if(x_slicing_others == NULL)
		throw Ememory("archive_options_listing::set_user_slicing");
	}
	else
	    *x_slicing_others = slicing_others;
    }
예제 #4
0
    void archive_options_listing::copy_from(const archive_options_listing & ref)
    {
	x_selection = NULL;
	x_subtree = NULL;
	x_slicing_first = NULL;
	x_slicing_others = NULL;

	try
	{
	    if(ref.x_selection == NULL)
		throw SRC_BUG;
	    x_selection = ref.x_selection->clone();
	    x_subtree = ref.x_subtree->clone();
	    if(x_selection == NULL || x_subtree == NULL)
		throw Ememory("archive_options_listing::copy_from");
	    if(ref.x_slicing_first != NULL)
	    {
		x_slicing_first = new (get_pool()) infinint(*ref.x_slicing_first);
		if(x_slicing_first == NULL)
		    throw Ememory("archive_options_listing::copy_from");
	    }
	    if(ref.x_slicing_others != NULL)
	    {
		x_slicing_others = new (get_pool()) infinint(*ref.x_slicing_others);
		if(x_slicing_others == NULL)
		    throw Ememory("archive_options_listing::copy_from");
	    }

	    x_info_details = ref.x_info_details;
	    x_list_mode = ref.x_list_mode;
	    x_filter_unsaved = ref.x_filter_unsaved;
	    x_display_ea = ref.x_display_ea;
	}
	catch(...)
	{
	    clear();
	    throw;
	}
    }
예제 #5
0
    void archive_options_read::clear()
    {

	    // setting the default values for all options

	detruit();

	x_crypto = crypto_none;
	x_pass.clear();
	x_crypto_size = default_crypto_size;
	x_input_pipe = "";
	x_output_pipe = "";
	x_execute = "";
	x_info_details = false;
	x_lax = false;
	x_sequential_read = false;
	x_slice_min_digits = 0;
	x_entrepot = new (get_pool()) entrepot_local("", "", false); // never using furtive_mode to read slices
	if(x_entrepot == NULL)
	    throw Ememory("archive_options_read::clear");
	x_ignore_signature_check_failure = false;
	x_multi_threaded = true;

	    //
	external_cat = false;
	x_ref_chem = default_ref_chem;
	x_ref_basename = "";
	x_ref_crypto = crypto_none;
	x_ref_pass.clear();
	x_ref_crypto_size = default_crypto_size;
	x_ref_execute = "";
	x_ref_slice_min_digits = 0;
	x_ref_entrepot = new (get_pool()) entrepot_local("", "", false); // never using furtive_mode to read slices
	if(x_ref_entrepot == NULL)
	    throw Ememory("archive_options_read::clear");
    }
예제 #6
0
    void archive_options_create::set_compr_mask(const mask & compr_mask)
    {
	NLS_SWAP_IN;
	try
	{
	    archive_option_destroy_mask(x_compr_mask);
	    x_compr_mask = compr_mask.clone();
	    if(x_compr_mask == NULL)
		throw Ememory("archive_options_create::set_compr_mask");
	}
	catch(...)
	{
	    NLS_SWAP_OUT;
	    throw;
	}
	NLS_SWAP_OUT;
    }
예제 #7
0
    void archive_options_merge::set_subtree(const mask & subtree)
    {
	NLS_SWAP_IN;
	try
	{
	    archive_option_destroy_mask(x_subtree);
	    x_subtree = subtree.clone();
	    if(x_subtree == NULL)
		throw Ememory("archive_options_merge::set_subtree");
	}
        catch(...)
        {
            NLS_SWAP_OUT;
            throw;
        }
        NLS_SWAP_OUT;
    }
예제 #8
0
    void archive_options_merge::set_overwriting_rules(const crit_action & overwrite)
    {
	NLS_SWAP_IN;
	try
	{
	    archive_option_destroy_crit_action(x_overwrite);
	    x_overwrite = overwrite.clone();
	    if(x_overwrite == NULL)
		throw Ememory("archive_options_merge::set_overwriting_rules");
	}
        catch(...)
        {
            NLS_SWAP_OUT;
            throw;
        }
        NLS_SWAP_OUT;
    }
예제 #9
0
    void archive_options_extract::set_selection(const mask & selection)
    {
	NLS_SWAP_IN;
	try
	{
	    archive_option_destroy_mask(x_selection);
	    x_selection = selection.clone();
	    if(x_selection == NULL)
		throw Ememory("archive_options_extract::set_selection");
	}
	catch(...)
	{
	    NLS_SWAP_OUT;
	    throw;
	}
	NLS_SWAP_OUT;
    }
예제 #10
0
    void archive_options_merge::set_ea_mask(const mask & ea_mask)
    {
	NLS_SWAP_IN;
	try
	{
	    archive_option_destroy_mask(x_ea_mask);
	    x_ea_mask = ea_mask.clone();
	    if(x_ea_mask == NULL)
		throw Ememory("archive_options_merge::set_ea_mask");
	}
	catch(...)
	{
	    NLS_SWAP_OUT;
	    throw;
	}
	NLS_SWAP_OUT;
    }
예제 #11
0
    void archive_options_extract::copy_from(const archive_options_extract & ref)
    {
	x_selection = NULL;
	x_subtree = NULL;
	x_ea_mask = NULL;
	x_overwrite = NULL;

	try
	{
	    if(ref.x_selection == NULL)
		throw SRC_BUG;
	    if(ref.x_subtree == NULL)
		throw SRC_BUG;
	    if(ref.x_ea_mask == NULL)
		throw SRC_BUG;
	    if(ref.x_overwrite == NULL)
		throw SRC_BUG;
	    x_selection = ref.x_selection->clone();
	    x_subtree = ref.x_subtree->clone();
	    x_ea_mask = ref.x_ea_mask->clone();
	    x_overwrite = ref.x_overwrite->clone();

	    if(x_selection == NULL || x_subtree == NULL || x_ea_mask == NULL || x_overwrite == NULL)
		throw Ememory("archive_options_extract::copy_from");

	    x_warn_over = ref.x_warn_over;
	    x_info_details = ref.x_info_details;
	    x_display_treated = ref.x_display_treated;
	    x_display_treated_only_dir = ref.x_display_treated_only_dir;
	    x_display_skipped = ref.x_display_skipped;
	    x_flat = ref.x_flat;
	    x_what_to_check = ref.x_what_to_check;
	    x_warn_remove_no_match = ref.x_warn_remove_no_match;
	    x_empty = ref.x_empty;
	    x_empty_dir = ref.x_empty_dir;
	    x_dirty = ref.x_dirty;
	    x_only_deleted = ref.x_only_deleted;
	    x_ignore_deleted = ref.x_ignore_deleted;
	    x_scope = ref.x_scope;
	}
	catch(...)
	{
	    clear();
	    throw;
	}
    }
예제 #12
0
    void escape_catalogue::copy_from(const escape_catalogue & ref)
    {
	pdesc = ref.pdesc;
	x_reading_ver = ref.x_reading_ver;
	x_default_algo = ref.x_default_algo;
	x_lax = ref.x_lax;
	corres = ref.corres;
	status = ref.status;
	if(ref.cat_det == NULL)
	    cat_det = NULL;
	else
	    cat_det = new (get_pool()) catalogue(*ref.cat_det);
	if(cat_det == NULL)
	    throw Ememory("escape_catalogue::copy_from");
	min_read_offset = ref.min_read_offset;
	depth = ref.depth;
	wait_parent_depth = ref.wait_parent_depth;
    }
예제 #13
0
    void archive_options_isolate::clear()
    {
	NLS_SWAP_IN;
	try
	{
	    destroy();

	    x_allow_over = true;
	    x_warn_over = true;
	    x_info_details = false;
	    x_pause = 0;
	    x_algo = none;
	    x_compression_level = 9;
	    x_file_size = 0;
	    x_first_file_size = 0;
	    x_execute = "";
	    x_crypto = crypto_none;
	    x_pass.clear();
	    x_crypto_size = default_crypto_size;
	    x_gnupg_recipients.clear();
	    x_gnupg_key_size = default_gnupg_key_size;
	    x_gnupg_signatories.clear();
	    x_empty = false;
	    x_slice_permission = "";
	    x_slice_user_ownership = "";
	    x_slice_group_ownership = "";
	    x_user_comment = default_user_comment;
	    x_hash = hash_none;
	    x_slice_min_digits = 0;
	    x_sequential_marks = true;
	    x_entrepot = new (get_pool()) entrepot_local("", "", false); // never using furtive_mode to read slices
	    if(x_entrepot == NULL)
		throw Ememory("archive_options_isolate::clear");
	    x_multi_threaded = true;
	}
	catch(...)
	{
	    NLS_SWAP_OUT;
	    throw;
	}
	NLS_SWAP_OUT;
    }
예제 #14
0
    void archive_options_create::set_backup_hook(const std::string & execute, const mask & which_files)
    {

	NLS_SWAP_IN;
	try
	{
	    archive_option_destroy_mask(x_backup_hook_file_mask);
	    x_backup_hook_file_mask = which_files.clone();
	    if(x_backup_hook_file_mask == NULL)
		throw Ememory("archive_options_create::set_backup_hook");

	    x_backup_hook_file_execute = execute;
	}
	catch(...)
	{
	    NLS_SWAP_OUT;
	    throw;
	}
	NLS_SWAP_OUT;
    }
예제 #15
0
    void archive_options_diff::copy_from(const archive_options_diff & ref)
    {
	x_selection = NULL;
	x_subtree = NULL;
	x_ea_mask = NULL;

	try
	{
	    if(ref.x_selection == NULL)
		throw SRC_BUG;
	    if(ref.x_subtree == NULL)
		throw SRC_BUG;
	    if(ref.x_ea_mask == NULL)
		throw SRC_BUG;

	    x_selection = ref.x_selection->clone();
	    x_subtree = ref.x_subtree->clone();
	    x_ea_mask = ref.x_ea_mask->clone();

	    if(x_selection == NULL || x_subtree == NULL || x_ea_mask == NULL)
		throw Ememory("archive_options_extract::copy_from");

	    x_info_details = ref.x_info_details;
	    x_display_treated = ref.x_display_treated;
	    x_display_treated_only_dir = ref.x_display_treated_only_dir;
	    x_display_skipped = ref.x_display_skipped;
	    x_what_to_check = ref.x_what_to_check;
	    x_alter_atime = ref.x_alter_atime;
	    x_old_alter_atime = ref.x_old_alter_atime;
	    x_furtive_read = ref.x_furtive_read;
	    x_hourshift = ref.x_hourshift;
	    x_compare_symlink_date = ref.x_compare_symlink_date;
	    x_scope = ref.x_scope;
	}
	catch(...)
	{
	    clear();
	    throw;
	}
    }
예제 #16
0
    bool escape_catalogue::read(const cat_entree * & ref) const
    {
	escape_catalogue *ceci = const_cast<escape_catalogue *>(this);
	const cat_directory *ref_dir = NULL;
	const cat_eod *ref_eod = NULL;
	bool stop = false;

	if(pdesc.esc == NULL)
	    throw SRC_BUG;
	ref = NULL;

	    // if we have already read the whole archive contents (included detruits object),
	    // we do not need inspect the archive again, we instead use the data in memory
	if(status == ec_completed)
	    return catalogue::read(ref);

	pdesc.stack->flush_read_above(pdesc.esc);
	try
	{
	    while(ref == NULL && !stop)
	    {
		switch(status)
		{
		case ec_init:
		    ceci->status = ec_marks;
			// no break;
		case ec_marks:
		    if(min_read_offset > pdesc.esc->get_position())
		    {
			    // for some reason, like datacorruption, bad CRC or missing CRC in hard linked inode
			    // we skipped back to the hard linked inode information (it failed to be restored the first time)
			    // We must not read again and again the same data, so we skip forward to min_read_offset

			ceci->pdesc.esc->skip(min_read_offset);
		    }

		    if(pdesc.esc->skip_to_next_mark(escape::seqt_file, true))
		    {
			ceci->min_read_offset = pdesc.esc->get_position();
			try
			{
			    ref = cat_entree::read(get_ui(),
						   get_pool(),
						   pdesc,
						   x_reading_ver,
						   ceci->access_stats(),
						   ceci->corres,
						   ceci->x_default_algo,
						   false, // lax mode
						   false, // only_detruit
						   true); // always a small read in that context
			    if(pdesc.esc->next_to_read_is_mark(escape::seqt_failed_backup))
			    {
				if(!pdesc.esc->skip_to_next_mark(escape::seqt_failed_backup, false))
				    throw SRC_BUG;
				if(ref != NULL)
				{
				    delete ref;
				    ref = NULL;
				}
				continue; // restarts the while loop
			    }

			    ref_dir = dynamic_cast<const cat_directory *>(ref);
			    if(ref_dir != NULL)
				++(ceci->depth);

			    ref_eod = dynamic_cast<const cat_eod *>(ref);
			    if(ref_eod != NULL)
			    {
				if(depth > 0)
				    --(ceci->depth);
				else
				    if(!x_lax)
					throw Erange("escape_catalogue::read", gettext("Escape sequences used for reading lead the archive to place some files out of the specified root. To overcome this problem, try reading the archive in direct mode (not using sequential reading), try repairing the archive using Parchive if redundancy data has been created or in last resort try using the lax mode"));
				    else // lax mode
				    {
					get_ui().warning(gettext("LAX MODE: Archive directory structure is corrupted, it would lead to place some files out of the specified root directory. Restoring different directory contents at the root not out of it, which will put files of different directories in the specified root directory"));
					if(ref == NULL)
					    throw SRC_BUG;
					delete ref; // this is the CAT_EOD object
					ref = NULL;
					continue; // restarts the while loop
				    }
			    }
			}
			catch(Erange & e)
			{
			    if(!x_lax)
				throw;
			    else
			    {
				get_ui().warning(gettext("LAX MODE: found unknown catalogue entry, assuming data corruption occurred. Skipping to the next entry, this may lead to improper directory structure being restored, if the corrupted data was a directory"));
				ref = NULL;
				continue; // restarts the while loop
			    }
			}

			if(ref == NULL)
			    throw Erange("escape_catalogue::read", gettext("Corrupted entry following an escape mark in the archive"));
			else
			{
			    bool is_eod = ref_eod != NULL;
			    cat_entree *ref_nc = const_cast<cat_entree *>(ref);

			    ceci->add(ref_nc);
			    if(wait_parent_depth > 0) // we must not return this object as it is member of a skipped dir
			    {
				if(depth < wait_parent_depth) // we are back out of the skipped directory
				{
				    if(is_eod)
					ceci->wait_parent_depth = 0;
				    else
					throw SRC_BUG; // we should get out of the directory reading a CAT_EOD !
				}

				ref = NULL; // must not release object except, they are now part of catalogue
				continue;   // ignore this entry and skip to the next one
			    }

			    if(is_eod)
				ref = get_r_eod_address();
			}
		    }
		    else // no more file to read from in-sequence marks
		    {
			if(depth != 0)
			{
			    get_ui().warning(gettext("Uncompleted archive! Assuming it has been interrupted during the backup process. If an error has been reported just above, simply ignore it, this is about the file that was saved at the time of the interruption."));
			    ceci->status = ec_eod;
			    ref = get_r_eod_address();
			    if(ref == NULL)
				throw SRC_BUG;
			    --(ceci->depth);
			}
			else
			{
				// we no more need the hard link correspondance map so we free the memory it uses
			    ceci->corres.clear();
			    ceci->status = ec_detruits;
			    label tmp;
			    tmp.clear();

			    if(pdesc.compr == NULL)
				throw SRC_BUG;
			    if(pdesc.compr->is_compression_suspended())
			    {
				pdesc.compr->resume_compression();
				if(pdesc.compr->get_algo() != none)
				    pdesc.stack->flush_read_above(pdesc.compr);
			    }

				// build the catalogue to get detruit objects
			    if(pdesc.esc->skip_to_next_mark(escape::seqt_catalogue, true))
			    {
				bool only_detruit = !is_empty(); // we read the whole catalogue if we could not find any entry before the catalogue mark
				    // this situation is either an extracted catalogue, or a normal archive which only has detruit objects
				    // in any case, it does not hurt considering the whole catalogue

 				ceci->cat_det = new (get_pool()) catalogue(get_ui(),
									   pdesc,
									   x_reading_ver,
									   x_default_algo,
									   x_lax,  // lax
									   tmp,    // we do not modify the catalogue data_name even in lax mode
									   only_detruit);  // only_detruit

				if(ceci->cat_det == NULL)
				    throw Ememory("escape_catalogue::read");

				cat_det->reset_read();
				if(only_detruit)
				    ceci->status = ec_detruits;
				else
				{
				    ceci->status = ec_completed;
				    ceci->swap_stuff(*(ceci->cat_det));
				    delete ceci->cat_det;
				    ceci->cat_det = NULL;
				}
				stop = false;
				ref = NULL;
			    }
			    else // no more file and no catalogue entry found (interrupted archive)
			    {
				ceci->status = ec_completed;

				if(!x_lax)
				    throw Erange("escape_catalogue::read", gettext("Cannot extract from the internal catalogue the list of files to remove"));
				else
				{
				    get_ui().warning("LAX MODE: Cannot extract from the internal catalogue the list of files to remove, skipping this step");
				    ref = NULL;
				    stop = true;
				}
			    }
			}
		    }
		    break;
		case ec_eod:
		    if(depth > 0)
		    {
			ref = get_r_eod_address();
			if(ref == NULL)
			    throw SRC_BUG;
			--(ceci->depth);
		    }
		    else
			ceci->status = ec_marks;
		    break;
		case ec_detruits:
		    if(cat_det == NULL)
			throw SRC_BUG;
		    if(!cat_det->read(ref))
		    {
			ceci->merge_cat_det();
			ceci->status = ec_completed;
			ref = NULL;
			stop = true;
		    }
		    else
			if(ref == NULL)
			    throw SRC_BUG;
		    break;
		case ec_completed:
		    return catalogue::read(ref);
		default:
		    throw SRC_BUG;
		}
	    }
	}
	catch(...)
	{
	    if(ref != NULL && cat_det == NULL && ref != get_r_eod_address()) // we must not delete objects owned by cat_det
		delete ref;
	    ref = NULL;
	    throw;
	}

	return ref != NULL;
    }
예제 #17
0
    U_I compressor::gzip_read(char *a, U_I size)
    {
        S_I ret;
        S_I flag = WR_NO_FLUSH;
	U_I mem_avail_out = 0;
	enum { normal, no_more_input, eof } processing = normal;

        if(size == 0)
            return 0;

        decompr->wrap.set_next_out(a);
        decompr->wrap.set_avail_out(size);

        do
        {
                // feeding the input buffer if necessary
            if(decompr->wrap.get_avail_in() == 0)
            {
                decompr->wrap.set_next_in(decompr->buffer);
                decompr->wrap.set_avail_in(compressed->read(decompr->buffer,
                                                            decompr->size));

		if(decompr->wrap.get_avail_in() == 0)
		    mem_avail_out = decompr->wrap.get_avail_out();
		    // could not add compressed data, so if no more clear data is produced
		    // we must break the endless loop if WR_STREAM_END is not returned by decompress()
		    // this situation can occur upon data corruption
		else
		    mem_avail_out = 0;
            }
	    if(decompr->wrap.get_avail_in() == 0)
		processing = no_more_input;

            ret = decompr->wrap.decompress(flag);
	    if(ret == 0 && processing == no_more_input) // nothing extracted from decompression engine and no more compression data available
		processing = eof;


            switch(ret)
            {
            case WR_OK:
            case WR_STREAM_END:
                break;
            case WR_DATA_ERROR:
                throw Erange("compressor::gzip_read", gettext("compressed data CRC error"));
            case WR_MEM_ERROR:
                throw Ememory("compressor::gzip_read");
            case WR_BUF_ERROR:
                    // no process is possible:
                if(decompr->wrap.get_avail_in() == 0) // because we reached EOF
                    ret = WR_STREAM_END; // lib did not returned WR_STREAM_END (why ?)
                else // nothing explains why no process is possible:
                    if(decompr->wrap.get_avail_out() == 0)
                        throw SRC_BUG; // bug from DAR: no output possible
                    else
                        throw SRC_BUG; // unexpected comportment from lib
                break;
            default:
                throw SRC_BUG;
            }
        }
        while(decompr->wrap.get_avail_out() != mem_avail_out && ret != WR_STREAM_END && processing != eof);

        return decompr->wrap.get_next_out() - a;
    }
예제 #18
0
    void compressor::init(compression algo, generic_file *compressed_side, U_I compression_level)
    {
            // these are eventually overwritten below
        wrapperlib_mode wr_mode = zlib_mode;
        current_algo = algo;
	current_level = compression_level;

        if(compressed_side == NULL)
            throw SRC_BUG;
        if(compression_level > 9)
            throw SRC_BUG;

        compr = decompr = NULL;
	lzo_read_buffer = lzo_write_buffer = NULL;
	lzo_compressed = NULL;
	lzo_wrkmem = NULL;

        switch(algo)
        {
        case none:
            read_ptr = &compressor::none_read;
            write_ptr = &compressor::none_write;
            break;
        case bzip2:
            wr_mode = bzlib_mode;
                // NO BREAK !
        case gzip:
            read_ptr = &compressor::gzip_read;
            write_ptr = &compressor::gzip_write;
            compr = new (nothrow) xfer(BUFFER_SIZE, wr_mode);
            if(compr == NULL)
                throw Ememory("compressor::compressor");
            decompr = new (nothrow) xfer(BUFFER_SIZE, wr_mode);
            if(decompr == NULL)
            {
                delete compr;
		compr = NULL;
                throw Ememory("compressor::compressor");
            }

            switch(compr->wrap.compressInit(compression_level))
            {
            case WR_OK:
                break;
            case WR_MEM_ERROR:
                delete compr;
		compr = NULL;
                delete decompr;
		decompr = NULL;
                throw Ememory("compressor::compressor");
            case WR_VERSION_ERROR:
                delete compr;
		compr = NULL;
                delete decompr;
		decompr = NULL;
                throw Erange("compressor::compressor", gettext("incompatible Zlib version"));
            case WR_STREAM_ERROR:
            default:
                delete compr;
		compr = NULL;
                delete decompr;
		decompr = NULL;
                throw SRC_BUG;
            }

            switch(decompr->wrap.decompressInit())
            {
            case WR_OK:
                decompr->wrap.set_avail_in(0);
                break;
            case WR_MEM_ERROR:
                compr->wrap.compressEnd();
                delete compr;
		compr = NULL;
                delete decompr;
		decompr = NULL;
                throw Ememory("compressor::compressor");
            case WR_VERSION_ERROR:
                compr->wrap.compressEnd();
                delete compr;
		compr = NULL;
                delete decompr;
		decompr = NULL;
                throw Erange("compressor::compressor", gettext("incompatible Zlib version"));
            case WR_STREAM_ERROR:
            default:
                compr->wrap.compressEnd();
                delete compr;
		compr = NULL;
                delete decompr;
		decompr = NULL;
                throw SRC_BUG;
            }
            break;
	case lzo:
#if LIBLZO2_AVAILABLE
	    read_ptr = &compressor::lzo_read;
	    write_ptr = &compressor::lzo_write;
	    lzo_read_size = lzo_write_size = 0;
	    lzo_read_start = 0;
	    lzo_write_flushed = true;
	    lzo_read_reached_eof = false;
	    try
	    {
		lzo_read_buffer = new (nothrow) char[LZO_CLEAR_BUFFER_SIZE];
		lzo_write_buffer = new (nothrow) char[LZO_CLEAR_BUFFER_SIZE];
		lzo_compressed = new (nothrow) char[LZO_COMPRESSED_BUFFER_SIZE];
		lzo_wrkmem = new (nothrow) char[LZO1X_999_MEM_COMPRESS];
		if(lzo_read_buffer == NULL || lzo_write_buffer == NULL || lzo_compressed == NULL || lzo_wrkmem == NULL)
		    throw Ememory("compressor::init");
	    }
	    catch(...)
	    {
		if(lzo_read_buffer != NULL)
		{
		    delete [] lzo_read_buffer;
		    lzo_read_buffer = NULL;
		}
		if(lzo_write_buffer != NULL)
		{
		    delete [] lzo_write_buffer;
		    lzo_write_buffer = NULL;
		}
		if(lzo_compressed != NULL)
		{
		    delete [] lzo_compressed;
		    lzo_compressed = NULL;
		}
		if(lzo_wrkmem != NULL)
		{
		    delete [] lzo_wrkmem;
		    lzo_wrkmem = NULL;
		}
		throw;
	    }
	    break;
#else
	    throw Ecompilation("lzo compression support");
#endif
        default :
            throw SRC_BUG;
        }

        compressed = compressed_side;
    }
예제 #19
0
    void crypto_asym::build_key_list(const vector<string> & recipients_email, gpgme_key_t * & ciphering_keys, bool signatories)
    {
	U_I size = recipients_email.size() + 1;

	ciphering_keys = new (nothrow) gpgme_key_t[size];
	if(ciphering_keys == NULL)
	    throw Ememory("crypto_asym::build_key_list");

	    // clearing all fields in order to be able to know which
	    // index has been allocated and need to be restored in case of error
	for(U_I i = 0; i < size ; ++i)
	    ciphering_keys[i] = NULL;

	try
	{
	    gpgme_error_t err = GPG_ERR_NO_ERROR;
	    gpgme_user_id_t id = NULL;
	    bool found = false;
	    bool eof = false;
	    bool loop = false;
	    U_I offset = 0;

		// for each recipient, listing all keys to find a match

	    for(U_I i = 0; i < recipients_email.size(); ++i)
	    {
		err = gpgme_op_keylist_start(context, NULL, 0);
		switch(gpgme_err_code(err))
		{
		case GPG_ERR_NO_ERROR:
		    break;
		case GPG_ERR_INV_VALUE:
		    throw SRC_BUG;
		default:
		    throw Erange("crypto_asym::decrypt", string(gettext("Unexpected error reported by GPGME: ")) + tools_gpgme_strerror_r(err));
		}

		found = false;
		eof = false;
		do
		{
			// getting the next key

		    err = gpgme_op_keylist_next(context, &(ciphering_keys[i - offset]));
		    switch(gpgme_err_code(err))
		    {
		    case GPG_ERR_EOF:
			eof = true;
			break;
		    case GPG_ERR_NO_ERROR:
			id = ciphering_keys[i - offset]->uids;
			loop = true;

			    // for each key, listing all identies associated with it to find a match
			do
			{
			    found = (strncmp(recipients_email[i].c_str(), id->email, recipients_email[i].size()) == 0);

			    if(found)
			    {
				if(ciphering_keys[i - offset]->revoked
				   || ciphering_keys[i - offset]->expired
				   || ciphering_keys[i - offset]->disabled
				   || ciphering_keys[i - offset]->invalid)
				    found = false;
				if(signatories)
				{
				    if(!ciphering_keys[i - offset]->can_sign)
					found = false;
				}
				else
				{
				    if(!ciphering_keys[i - offset]->can_encrypt)
					found = false;
				}
			    }

			    if(!found && id->next != NULL)
				id = id->next;
			    else
				loop = false;
			}
			while(loop);

			    // if not identity match found for that key deleting the key

			if(!found)
			{
			    gpgme_key_unref(ciphering_keys[i - offset]);
			    ciphering_keys[i - offset] = NULL;
			}
			break;
		    default:
			throw Erange("crypto_asym::decrypt", string(gettext("Unexpected error reported by GPGME: ")) + tools_gpgme_strerror_r(err));
		    }
		}
		while(!found && !eof);

		    // if we exit before gpgme_op_keylist_next() return GPG_ERR_EOF
		    // we must update the state of the context to end the key listing operation

		if(!eof)
		    (void)gpgme_op_keylist_end(context);

		if(!found)
		{
		    if(signatories)
			get_ui().printf(gettext("No valid signing key could be find for %S"), &(recipients_email[i]));
		    else
			get_ui().printf(gettext("No valid encryption key could be find for %S"), &(recipients_email[i]));
		    get_ui().pause("Do you want to continue without this recipient?");
		    ++offset;
		}
	    }

		// if no recipient could be found at all aborting the operation

	    if(offset + 1 >= size)
	    {
		if(signatories)
		    throw Erange("crypto_asym::build_key_list", gettext("No signatory remain with a valid key, signing is impossible, aborting"));
		else
		    throw Erange("crypto_asym::build_key_list", gettext("No recipient remain with a valid key, encryption is impossible, aborting"));
	    }

		// the key list must end wth a NULL entry

	    if(ciphering_keys[size - 1 - offset] != NULL)
		throw SRC_BUG;
	}
	catch(...)
	{
	    release_key_list(ciphering_keys);
	    throw;
	}
    }
예제 #20
0
    void archive_options_create::clear()
    {
	NLS_SWAP_IN;
	try
	{

	    destroy();

	    archive_option_clean_mask(x_selection, get_pool());
	    archive_option_clean_mask(x_subtree, get_pool());
	    archive_option_clean_mask(x_ea_mask, get_pool());
	    archive_option_clean_mask(x_compr_mask, get_pool());
	    archive_option_clean_mask(x_backup_hook_file_mask, get_pool(), false);
	    x_ref_arch = NULL;
	    x_allow_over = true;
	    x_warn_over = true;
	    x_info_details = false;
	    x_display_treated = false;
	    x_display_treated_only_dir = false;
	    x_display_skipped = false;
	    x_display_finished = false;
	    x_pause = 0;
	    x_empty_dir = false;
	    x_compr_algo = none;
	    x_compression_level = 9;
	    x_file_size = 0;
	    x_first_file_size = 0;
	    x_execute = "";
	    x_crypto = crypto_none;
	    x_pass.clear();
	    x_crypto_size = default_crypto_size;
	    x_gnupg_recipients.clear();
	    x_gnupg_key_size = default_gnupg_key_size;
	    x_gnupg_signatories.clear();
	    x_min_compr_size = default_min_compr_size;
	    x_nodump = false;
	    exclude_by_ea = "";
	    x_what_to_check = default_comparison_fields;
	    x_hourshift = 0;
	    x_empty = false;
	    x_alter_atime = true;
	    x_old_alter_atime = true;
#if FURTIVE_READ_MODE_AVAILABLE
	    x_furtive_read = true;
#else
	    x_furtive_read = false;
#endif
	    x_same_fs = false;
	    x_snapshot = false;
	    x_cache_directory_tagging = false;
	    x_fixed_date = 0;
	    x_slice_permission = "";
	    x_slice_user_ownership = "";
	    x_slice_group_ownership = "";
	    x_repeat_count = 3;
	    x_repeat_byte = 1;
	    x_sequential_marks = true;
	    x_sparse_file_min_size = 15;  // min value to activate the feature (0 means no detection of sparse_file)
	    x_security_check = true;
	    x_user_comment = default_user_comment;
	    x_hash = hash_none;
	    x_slice_min_digits = 0;
	    x_backup_hook_file_execute = "";
	    x_ignore_unknown = false;
	    x_entrepot = new (get_pool()) entrepot_local( "", "", false); // never using furtive_mode to read slices
	    if(x_entrepot == NULL)
		throw Ememory("archive_options_create::clear");
	    x_scope = all_fsa_families();
	    x_multi_threaded = true;
	}
	catch(...)
	{
	    NLS_SWAP_OUT;
	    throw;
	}
	NLS_SWAP_OUT;
    }
예제 #21
0
    void archive_options_merge::copy_from(const archive_options_merge & ref)
    {
	x_selection = NULL;
	x_subtree = NULL;
	x_ea_mask = NULL;
	x_compr_mask = NULL;
	x_overwrite = NULL;
	x_entrepot = NULL;

	try
	{
	    if(ref.x_selection == NULL)
		throw SRC_BUG;
	    if(ref.x_subtree == NULL)
		throw SRC_BUG;
	    if(ref.x_ea_mask == NULL)
		throw SRC_BUG;
	    if(ref.x_compr_mask == NULL)
		throw SRC_BUG;
	    if(ref.x_overwrite == NULL)
		throw SRC_BUG;
	    if(ref.x_entrepot == NULL)
		throw SRC_BUG;

	    x_selection = ref.x_selection->clone();
	    x_subtree = ref.x_subtree->clone();
	    x_ea_mask = ref.x_ea_mask->clone();
	    x_compr_mask = ref.x_compr_mask->clone();
	    x_overwrite = ref.x_overwrite->clone();
	    x_entrepot = ref.x_entrepot->clone();

	    if(x_selection == NULL || x_subtree == NULL || x_ea_mask == NULL || x_compr_mask == NULL || x_overwrite == NULL || x_entrepot == NULL)
		throw Ememory("archive_options_extract::copy_from");

	    x_ref = ref.x_ref;
	    x_allow_over = ref.x_allow_over;
	    x_warn_over = ref.x_warn_over;
	    x_info_details = ref.x_info_details;
	    x_display_treated = ref.x_display_treated;
	    x_display_treated_only_dir = ref.x_display_treated_only_dir;
	    x_display_skipped = ref.x_display_skipped;
	    x_pause = ref.x_pause;
	    x_empty_dir = ref.x_empty_dir;
	    x_compr_algo = ref.x_compr_algo;
	    x_compression_level = ref.x_compression_level;
	    x_file_size = ref.x_file_size;
	    x_first_file_size = ref.x_first_file_size;
	    x_execute = ref.x_execute;
	    x_crypto = ref.x_crypto;
	    x_pass = ref.x_pass;
	    x_crypto_size = ref.x_crypto_size;
	    x_gnupg_recipients = ref.x_gnupg_recipients;
	    x_gnupg_key_size = ref.x_gnupg_key_size;
	    x_gnupg_signatories = ref.x_gnupg_signatories;
	    x_min_compr_size = ref.x_min_compr_size;
	    x_empty = ref.x_empty;
	    x_keep_compressed = ref.x_keep_compressed;
	    x_slice_permission = ref.x_slice_permission;
	    x_slice_user_ownership = ref.x_slice_user_ownership;
	    x_slice_group_ownership = ref.x_slice_group_ownership;
	    x_decremental = ref.x_decremental;
	    x_sequential_marks = ref.x_sequential_marks;
	    x_sparse_file_min_size = ref.x_sparse_file_min_size;
	    x_user_comment = ref.x_user_comment;
	    x_hash = ref.x_hash;
	    x_slice_min_digits = ref.x_slice_min_digits;
	    x_scope = ref.x_scope;
	    x_multi_threaded = ref.x_multi_threaded;
	}
	catch(...)
	{
	    clear();
	    throw;
	}
    }
예제 #22
0
    void archive_options_create::copy_from(const archive_options_create & ref)
    {
	x_selection = NULL;
	x_subtree = NULL;
	x_ea_mask = NULL;
	x_compr_mask = NULL;
	x_backup_hook_file_mask = NULL;
	x_entrepot = NULL;

	if(ref.x_selection == NULL)
	    throw SRC_BUG;
	if(ref.x_subtree == NULL)
	    throw SRC_BUG;
	if(ref.x_ea_mask == NULL)
	    throw SRC_BUG;
	if(ref.x_compr_mask == NULL)
	    throw SRC_BUG;
	if(ref.x_backup_hook_file_mask == NULL)
	    throw SRC_BUG;
	x_selection = ref.x_selection->clone();
	x_subtree = ref.x_subtree->clone();
	x_ea_mask = ref.x_ea_mask->clone();
	x_compr_mask = ref.x_compr_mask->clone();
	x_backup_hook_file_mask = ref.x_backup_hook_file_mask->clone();

	if(x_selection == NULL || x_subtree == NULL || x_ea_mask == NULL || x_compr_mask == NULL || x_backup_hook_file_mask == NULL)
	    throw Ememory("archive_options_create::copy_from");

	x_ref_arch = ref.x_ref_arch;
	x_allow_over = ref.x_allow_over;
	x_warn_over = ref.x_warn_over;
	x_info_details = ref.x_info_details;
	x_display_treated = ref.x_display_treated;
	x_display_treated_only_dir = ref.x_display_treated_only_dir;
	x_display_skipped = ref.x_display_skipped;
	x_display_finished = ref.x_display_finished;
	x_pause = ref.x_pause;
	x_empty_dir = ref.x_empty_dir;
	x_compr_algo = ref.x_compr_algo;
	x_compression_level = ref.x_compression_level;
	x_file_size = ref.x_file_size;
	x_first_file_size = ref.x_first_file_size;
	x_execute = ref.x_execute;
	x_crypto = ref.x_crypto;
	x_pass = ref.x_pass;
	x_crypto_size = ref.x_crypto_size;
	x_gnupg_recipients = ref.x_gnupg_recipients;
	x_gnupg_key_size = ref.x_gnupg_key_size;
	x_gnupg_signatories = ref.x_gnupg_signatories;
	x_min_compr_size = ref.x_min_compr_size;
	x_nodump = ref.x_nodump;
	x_what_to_check = ref.x_what_to_check;
	x_hourshift = ref.x_hourshift;
	x_empty = ref.x_empty;
	x_alter_atime = ref.x_alter_atime;
	x_old_alter_atime = ref.x_old_alter_atime;
	x_furtive_read = ref.x_furtive_read;
	x_same_fs = ref.x_same_fs;
	x_snapshot = ref.x_snapshot;
	x_cache_directory_tagging = ref.x_cache_directory_tagging;
	x_fixed_date = ref.x_fixed_date;
	x_slice_permission = ref.x_slice_permission;
	x_slice_user_ownership = ref.x_slice_user_ownership;
	x_slice_group_ownership = ref.x_slice_group_ownership;
	x_repeat_count = ref.x_repeat_count;
	x_repeat_byte = ref.x_repeat_byte;
	x_sequential_marks = ref.x_sequential_marks;
	x_sparse_file_min_size = ref.x_sparse_file_min_size;
	x_security_check = ref.x_security_check;
	x_user_comment = ref.x_user_comment;
	x_hash = ref.x_hash;
	x_slice_min_digits = ref.x_slice_min_digits;
	x_backup_hook_file_execute = ref.x_backup_hook_file_execute;
	x_ignore_unknown = ref.x_ignore_unknown;
	if(x_entrepot != NULL)
	    throw SRC_BUG;
	x_entrepot = ref.x_entrepot->clone();
	if(x_entrepot == NULL)
	    throw Ememory("archive_options_create::copy_from");
	x_scope = ref.x_scope;
	x_multi_threaded = ref.x_multi_threaded;
    }
    void filesystem_specific_attribute_list::read(generic_file & f)
    {
	infinint size = infinint(f);
	U_I sub_size;

	do
	{
	    sub_size = 0;
	    size.unstack(sub_size);
	    if(size > 0 && sub_size == 0)
		throw SRC_BUG;

	    while(sub_size > 0)
	    {
		char buffer[FAM_SIG_WIDTH + NAT_SIG_WIDTH + 1];
		fsa_family fam;
		fsa_nature nat;
		filesystem_specific_attribute *ptr = NULL;

		f.read(buffer, FAM_SIG_WIDTH);
		buffer[FAM_SIG_WIDTH] = '\0';
		fam = signature_to_family(buffer);

		f.read(buffer, NAT_SIG_WIDTH);
		buffer[NAT_SIG_WIDTH] = '\0';
		nat = signature_to_nature(buffer);

		switch(nat)
		{
		case fsan_unset:
		    throw SRC_BUG;
		case fsan_creation_date:
		    ptr = new (nothrow) fsa_infinint(f, fam, nat);
		    break;
		case fsan_append_only:
		case fsan_compressed:
		case fsan_no_dump:
		case fsan_immutable:
		case fsan_data_journalling:
		case fsan_secure_deletion:
		case fsan_no_tail_merging:
		case fsan_undeletable:
		case fsan_noatime_update:
		case fsan_synchronous_directory:
		case fsan_synchronous_update:
		case fsan_top_of_dir_hierarchy:
		    ptr = new (nothrow) fsa_bool(f, fam, nat);
		    break;
		default:
		    throw SRC_BUG;
		}

		if(ptr == NULL)
		    throw Ememory("filesystem_specific_attribute_list::read");
		fsa.push_back(ptr);
		ptr = NULL;

		--sub_size;
	    }
	}
	while(size > 0);

	update_familes();
	sort_fsa();
    }
예제 #24
0
    fichier_global *entrepot::open(user_interaction & dialog,
				   const std::string & filename,
				   gf_mode mode,
				   bool force_permission,
				   U_I permission,
				   bool fail_if_exists,
				   bool erase,
				   hash_algo algo) const
    {
	fichier_global *ret = NULL;

	    // sanity check
	if(algo != hash_none && (mode != gf_write_only || (!erase && !fail_if_exists)))
	    throw SRC_BUG; // if hashing is asked, we cannot accept to open an existing file without erasing its contents


	    // creating the file to write data to
	ret = inherited_open(dialog,
			     filename,
			     mode,
			     force_permission,
			     permission,
			     fail_if_exists,
			     erase);

	if(ret == NULL)
	    throw SRC_BUG;

	try
	{
	    if(algo != hash_none)
	    {
		fichier_global *hash_file = NULL;
		fichier_global *tmp = NULL;

		    // creating the file to write hash to

		try
		{
		    hash_file = inherited_open(dialog,
					       filename+"."+hash_algo_to_string(algo),
					       gf_write_only,
					       force_permission,
					       permission,
					       fail_if_exists,
					       erase);

		    if(hash_file == NULL)
			throw SRC_BUG;

		    try
		    {
			tmp = new (get_pool()) hash_fichier(dialog,
							    ret,
							    filename,
							    hash_file,
							    algo);
			if(tmp == NULL)
			    throw Ememory("entrepot::entrepot");
			else
			{
			    ret = tmp;
			    hash_file = NULL;
			}
		    }
		    catch(...)
		    {
			if(hash_file != NULL)
			    delete hash_file;
			throw;
		    }

		}
		catch(Egeneric & e)
		{
		    e.prepend_message(gettext("Error met while creating the hash file: "));
		    throw;
		}
	    }
	}
	catch(...)
	{
	    if(ret != NULL)
	    {
		delete ret;
		ret = NULL;
	    }
	    throw;
	}

	return ret;
    }