Beispiel #1
0
static void
progress_func(void *cookie)
{
	struct progress_data *progress_data = cookie;
	struct bsdtar *bsdtar = progress_data->bsdtar;
	struct archive *a = progress_data->archive;
	struct archive_entry *entry = progress_data->entry;
	uint64_t comp, uncomp;
	int compression;

	if (!need_report())
		return;

	if (bsdtar->verbose)
		fprintf(stderr, "\n");
	if (a != NULL) {
		comp = archive_position_compressed(a);
		uncomp = archive_position_uncompressed(a);
		if (comp > uncomp)
			compression = 0;
		else
			compression = (int)((uncomp - comp) * 100 / uncomp);
		fprintf(stderr,
		    "In: %s bytes, compression %d%%;",
		    tar_i64toa(comp), compression);
		fprintf(stderr, "  Out: %d files, %s bytes\n",
		    archive_file_count(a), tar_i64toa(uncomp));
	}
	if (entry != NULL) {
		safe_fprintf(stderr, "Current: %s",
		    archive_entry_pathname(entry));
		fprintf(stderr, " (%s bytes)\n",
		    tar_i64toa(archive_entry_size(entry)));
	}
}
Beispiel #2
0
/* Helper function to copy data between archives. */
static int
copy_file_data(struct bsdtar *bsdtar, struct archive *a,
    struct archive *ina, struct archive_entry *entry)
{
	ssize_t	bytes_read;
	ssize_t	bytes_written;
	int64_t	progress = 0;

	bytes_read = archive_read_data(ina, bsdtar->buff, bsdtar->buff_size);
	while (bytes_read > 0) {
		if (need_report())
			report_write(bsdtar, a, entry, progress);

		bytes_written = archive_write_data(a, bsdtar->buff,
		    bytes_read);
		if (bytes_written < bytes_read) {
			lafe_warnc(0, "%s", archive_error_string(a));
			return (-1);
		}
		progress += bytes_written;
		bytes_read = archive_read_data(ina, bsdtar->buff, bsdtar->buff_size);
	}

	return (0);
}
Beispiel #3
0
static int
append_archive(struct bsdtar *bsdtar, struct archive *a, struct archive *ina)
{
    struct archive_entry *in_entry;
    int e;

    while (ARCHIVE_OK == (e = archive_read_next_header(ina, &in_entry))) {
        if (archive_match_excluded(bsdtar->matching, in_entry))
            continue;
        if (bsdtar->option_interactive &&
                !yes("copy '%s'", archive_entry_pathname(in_entry)))
            continue;
        if (bsdtar->verbose > 1) {
            safe_fprintf(stderr, "a ");
            list_item_verbose(bsdtar, stderr, in_entry);
        } else if (bsdtar->verbose > 0)
            safe_fprintf(stderr, "a %s",
                         archive_entry_pathname(in_entry));
        if (need_report())
            report_write(bsdtar, a, in_entry, 0);

        e = archive_write_header(a, in_entry);
        if (e != ARCHIVE_OK) {
            if (!bsdtar->verbose)
                lafe_warnc(0, "%s: %s",
                           archive_entry_pathname(in_entry),
                           archive_error_string(a));
            else
                fprintf(stderr, ": %s", archive_error_string(a));
        }
        if (e == ARCHIVE_FATAL)
            exit(1);

        if (e >= ARCHIVE_WARN) {
            if (archive_entry_size(in_entry) == 0)
                archive_read_data_skip(ina);
            else if (copy_file_data_block(bsdtar, a, ina, in_entry))
                exit(1);
        }

        if (bsdtar->verbose)
            fprintf(stderr, "\n");
    }

    return (e == ARCHIVE_EOF ? ARCHIVE_OK : e);
}
Beispiel #4
0
/* Helper function to copy file to archive. */
static int
write_file_data(struct bsdtar *bsdtar, struct archive *a,
    struct archive_entry *entry, int fd, size_t align)
{
	ssize_t	bytes_read;
	ssize_t	bytes_written;
	int64_t	progress = 0;
	size_t  buff_size;
	char   *buff = bsdtar->buff;

	/* Round 'buff' up to the next multiple of 'align' and reduce
	 * 'buff_size' accordingly. */
	buff = (char *)((((uintptr_t)buff + align - 1) / align) * align);
	buff_size = bsdtar->buff + bsdtar->buff_size - buff;
	buff_size = (buff_size / align) * align;
	
	bytes_read = read(fd, buff, buff_size);
	while (bytes_read > 0) {
		if (need_report())
			report_write(bsdtar, a, entry, progress);

		bytes_written = archive_write_data(a, buff, bytes_read);
		if (bytes_written < 0) {
			/* Write failed; this is bad */
			lafe_warnc(0, "%s", archive_error_string(a));
			return (-1);
		}
		if (bytes_written < bytes_read) {
			/* Write was truncated; warn but continue. */
			lafe_warnc(0,
			    "%s: Truncated write; file may have grown while being archived.",
			    archive_entry_pathname(entry));
			return (0);
		}
		progress += bytes_written;
		bytes_read = read(fd, buff, buff_size);
	}
	return 0;
}
Beispiel #5
0
/* Helper function to copy file to archive. */
static int
copy_file_data_block(struct bsdtar *bsdtar, struct archive *a,
    struct archive *in_a, struct archive_entry *entry)
{
	size_t	bytes_read;
	ssize_t	bytes_written;
	int64_t	offset, progress = 0;
	char *null_buff = NULL;
	const void *buff;
	int r;

	while ((r = archive_read_data_block(in_a, &buff,
	    &bytes_read, &offset)) == ARCHIVE_OK) {
		if (need_report())
			report_write(bsdtar, a, entry, progress);

		if (offset > progress) {
			int64_t sparse = offset - progress;
			size_t ns;

			if (null_buff == NULL) {
				null_buff = bsdtar->buff;
				memset(null_buff, 0, bsdtar->buff_size);
			}

			while (sparse > 0) {
				if (sparse > (int64_t)bsdtar->buff_size)
					ns = bsdtar->buff_size;
				else
					ns = (size_t)sparse;
				bytes_written =
				    archive_write_data(a, null_buff, ns);
				if (bytes_written < 0) {
					/* Write failed; this is bad */
					lafe_warnc(0, "%s",
					     archive_error_string(a));
					return (-1);
				}
				if ((size_t)bytes_written < ns) {
					/* Write was truncated; warn but
					 * continue. */
					lafe_warnc(0,
					    "%s: Truncated write; file may "
					    "have grown while being archived.",
					    archive_entry_pathname(entry));
					return (0);
				}
				progress += bytes_written;
				sparse -= bytes_written;
			}
		}

		bytes_written = archive_write_data(a, buff, bytes_read);
		if (bytes_written < 0) {
			/* Write failed; this is bad */
			lafe_warnc(0, "%s", archive_error_string(a));
			return (-1);
		}
		if ((size_t)bytes_written < bytes_read) {
			/* Write was truncated; warn but continue. */
			lafe_warnc(0,
			    "%s: Truncated write; file may have grown "
			    "while being archived.",
			    archive_entry_pathname(entry));
			return (0);
		}
		progress += bytes_written;
	}
	if (r < ARCHIVE_WARN) {
		lafe_warnc(archive_errno(a), "%s", archive_error_string(a));
		return (-1);
	}
	return (0);
}