Exemplo n.º 1
0
Reader *Reader::read_open_filename(const char *filename, const char *cmd, bool raw) 
{
    struct archive *ar = archive_read_new();

    try {
        if(cmd) {
            if(archive_read_support_filter_program(ar, cmd) != ARCHIVE_OK)
                throw 0;
        } else {
            if(archive_read_support_filter_all(ar) != ARCHIVE_OK)
                throw 0;
        }

        if(raw) {
            if(archive_read_support_format_raw(ar) != ARCHIVE_OK)
                throw 0;
        } else {
            if(archive_read_support_format_all(ar) != ARCHIVE_OK)
                throw 0;
        }

        if(archive_read_open_filename(ar, filename, 1024) != ARCHIVE_OK)
            throw 0;

    } catch(...) {
        std::string error_msg = archive_error_string(ar);
        archive_read_free(ar);
        throw Error(error_msg);
    }

    return new Reader(ar);
}
Exemplo n.º 2
0
int
cset_read_support_filter_program(struct creation_set *cset, struct archive *a)
{
	int cnt = 0, i;

	for (i = 0; i < cset->filter_count; i++) {
		if (cset->filters[i].program) {
			archive_read_support_filter_program(a,
			    cset->filters[i].filter_name);
			++cnt;
		}
	}
	return (cnt);
}
Exemplo n.º 3
0
Reader *Reader::read_open_memory(const char *string, size_t length,
    const char *cmd, bool raw)
{
    struct archive *ar = archive_read_new();

    if (!ar) {
        throw Error("Unable to allocate libarchive handle!");
    }

    char *content = (char*) malloc(length);

    if (!content) {
        archive_read_free(ar);
        throw Error("Unable to allocate memory when duplicating buffer");
    }

    memcpy((void*) content, (void*) string, length);

    try {
        if(cmd) {
            if(archive_read_support_filter_program(ar, cmd) != ARCHIVE_OK)
                throw 0;
        } else {
            if(archive_read_support_filter_all(ar) != ARCHIVE_OK)
                throw 0;
        }

        if(raw) {
            if(archive_read_support_format_raw(ar) != ARCHIVE_OK)
                throw 0;
        } else {
            if(archive_read_support_format_all(ar) != ARCHIVE_OK)
                throw 0;
        }

        if(archive_read_open_memory(ar, (void*) content, length) != ARCHIVE_OK)
            throw 0;

    } catch(...) {
        std::string error_msg = archive_error_string(ar);
        archive_read_free(ar);
        free(content);
        throw Error(error_msg);
    }

    Reader *reader_obj = new Reader(ar);
    reader_obj->_archive_content = content;
    return reader_obj;
}
/* Deprecated; remove in libarchive 4.0 */
int
archive_read_support_compression_program(struct archive *a, const char *cmd)
{
	return archive_read_support_filter_program(a, cmd);
}
Exemplo n.º 5
0
/*
 * Handle 'x' and 't' modes.
 */
static void
read_archive(struct bsdtar *bsdtar, char mode, struct archive *writer)
{
	struct progress_data	progress_data;
	FILE			 *out;
	struct archive		 *a;
	struct archive_entry	 *entry;
	int			  r;
	time_t			  sec;
	long			  nsec;

	while (*bsdtar->argv) {
		lafe_include(&bsdtar->matching, *bsdtar->argv);
		bsdtar->argv++;
	}

	if (bsdtar->names_from_file != NULL)
		lafe_include_from_file(&bsdtar->matching,
		    bsdtar->names_from_file, bsdtar->option_null);

	a = archive_read_new();
	if (bsdtar->compress_program != NULL)
		archive_read_support_filter_program(a, bsdtar->compress_program);
	else
		archive_read_support_filter_all(a);
	archive_read_support_format_all(a);
	if (ARCHIVE_OK != archive_read_set_options(a, bsdtar->option_options))
		lafe_errc(1, 0, "%s", archive_error_string(a));
	if (archive_read_open_file(a, bsdtar->filename, bsdtar->bytes_per_block))
		lafe_errc(1, 0, "Error opening archive: %s",
		    archive_error_string(a));

	do_chdir(bsdtar);

	if (mode == 'x') {
		/* Set an extract callback so that we can handle SIGINFO. */
		progress_data.bsdtar = bsdtar;
		progress_data.archive = a;
		archive_read_extract_set_progress_callback(a, progress_func,
		    &progress_data);
	}

	if (mode == 'x' && bsdtar->option_chroot) {
#if HAVE_CHROOT
		if (chroot(".") != 0)
			lafe_errc(1, errno, "Can't chroot to \".\"");
#else
		lafe_errc(1, 0,
		    "chroot isn't supported on this platform");
#endif
	}

	for (;;) {
		/* Support --fast-read option */
		if (bsdtar->option_fast_read &&
		    lafe_unmatched_inclusions(bsdtar->matching) == 0)
			break;

		r = archive_read_next_header(a, &entry);
		progress_data.entry = entry;
		if (r == ARCHIVE_EOF)
			break;
		if (r < ARCHIVE_OK)
			lafe_warnc(0, "%s", archive_error_string(a));
		if (r <= ARCHIVE_WARN)
			bsdtar->return_value = 1;
		if (r == ARCHIVE_RETRY) {
			/* Retryable error: try again */
			lafe_warnc(0, "Retrying...");
			continue;
		}
		if (r == ARCHIVE_FATAL)
			break;

		if (bsdtar->uid >= 0) {
			archive_entry_set_uid(entry, bsdtar->uid);
			archive_entry_set_uname(entry, NULL);
		}
		if (bsdtar->gid >= 0) {
			archive_entry_set_gid(entry, bsdtar->gid);
			archive_entry_set_gname(entry, NULL);
		}
		if (bsdtar->uname)
			archive_entry_set_uname(entry, bsdtar->uname);
		if (bsdtar->gname)
			archive_entry_set_gname(entry, bsdtar->gname);

		/*
		 * Exclude entries that are too old.
		 */
		if (bsdtar->newer_ctime_filter) {
			/* Use ctime if format provides, else mtime. */
			if (archive_entry_ctime_is_set(entry)) {
				sec = archive_entry_ctime(entry);
				nsec = archive_entry_ctime_nsec(entry);
			} else if (archive_entry_mtime_is_set(entry)) {
				sec = archive_entry_mtime(entry);
				nsec = archive_entry_mtime_nsec(entry);
			} else {
				sec = 0;
				nsec = 0;
			}
			if (sec < bsdtar->newer_ctime_sec)
				continue; /* Too old, skip it. */
			if (sec == bsdtar->newer_ctime_sec
			    && nsec <= bsdtar->newer_ctime_nsec)
				continue; /* Too old, skip it. */
		}
		if (bsdtar->newer_mtime_filter) {
			if (archive_entry_mtime_is_set(entry)) {
				sec = archive_entry_mtime(entry);
				nsec = archive_entry_mtime_nsec(entry);
			} else {
				sec = 0;
				nsec = 0;
			}
			if (sec < bsdtar->newer_mtime_sec)
				continue; /* Too old, skip it. */
			if (sec == bsdtar->newer_mtime_sec
			    && nsec <= bsdtar->newer_mtime_nsec)
				continue; /* Too old, skip it. */
		}

		/*
		 * Note that pattern exclusions are checked before
		 * pathname rewrites are handled.  This gives more
		 * control over exclusions, since rewrites always lose
		 * information.  (For example, consider a rewrite
		 * s/foo[0-9]/foo/.  If we check exclusions after the
		 * rewrite, there would be no way to exclude foo1/bar
		 * while allowing foo2/bar.)
		 */
		if (lafe_excluded(bsdtar->matching, archive_entry_pathname(entry)))
			continue; /* Excluded by a pattern test. */

		if (mode == 't') {
			/* Perversely, gtar uses -O to mean "send to stderr"
			 * when used with -t. */
			out = bsdtar->option_stdout ? stderr : stdout;

			/*
			 * TODO: Provide some reasonable way to
			 * preview rewrites.  gtar always displays
			 * the unedited path in -t output, which means
			 * you cannot easily preview rewrites.
			 */
			if (bsdtar->verbose < 2)
				safe_fprintf(out, "%s",
				    archive_entry_pathname(entry));
			else
				list_item_verbose(bsdtar, out, entry);
			fflush(out);
			r = archive_read_data_skip(a);
			if (r == ARCHIVE_WARN) {
				fprintf(out, "\n");
				lafe_warnc(0, "%s",
				    archive_error_string(a));
			}
			if (r == ARCHIVE_RETRY) {
				fprintf(out, "\n");
				lafe_warnc(0, "%s",
				    archive_error_string(a));
			}
			if (r == ARCHIVE_FATAL) {
				fprintf(out, "\n");
				lafe_warnc(0, "%s",
				    archive_error_string(a));
				bsdtar->return_value = 1;
				break;
			}
			fprintf(out, "\n");
		} else {
			/* Note: some rewrite failures prevent extraction. */
			if (edit_pathname(bsdtar, entry))
				continue; /* Excluded by a rewrite failure. */

			if (bsdtar->option_interactive &&
			    !yes("extract '%s'", archive_entry_pathname(entry)))
				continue;

			/*
			 * Format here is from SUSv2, including the
			 * deferred '\n'.
			 */
			if (bsdtar->verbose) {
				safe_fprintf(stderr, "x %s",
				    archive_entry_pathname(entry));
				fflush(stderr);
			}

			/* TODO siginfo_printinfo(bsdtar, 0); */

			if (bsdtar->option_stdout)
				r = archive_read_data_into_fd(a, 1);
			else
				r = archive_read_extract2(a, entry, writer);
			if (r != ARCHIVE_OK) {
				if (!bsdtar->verbose)
					safe_fprintf(stderr, "%s",
					    archive_entry_pathname(entry));
				safe_fprintf(stderr, ": %s",
				    archive_error_string(a));
				if (!bsdtar->verbose)
					fprintf(stderr, "\n");
				bsdtar->return_value = 1;
			}
			if (bsdtar->verbose)
				fprintf(stderr, "\n");
			if (r == ARCHIVE_FATAL)
				break;
		}
	}


	r = archive_read_close(a);
	if (r != ARCHIVE_OK)
		lafe_warnc(0, "%s", archive_error_string(a));
	if (r <= ARCHIVE_WARN)
		bsdtar->return_value = 1;

	if (bsdtar->verbose > 2)
		fprintf(stdout, "Archive Format: %s,  Compression: %s\n",
		    archive_format_name(a), archive_compression_name(a));

	archive_read_free(a);
}