Пример #1
0
int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix)
{
	struct argv_array sent_argv = ARGV_ARRAY_INIT;
	const char *arg_cmd = "argument ";

	if (argc != 2)
		usage(upload_archive_usage);

	if (!enter_repo(argv[1], 0))
		die("'%s' does not appear to be a git repository", argv[1]);

	/* put received options in sent_argv[] */
	argv_array_push(&sent_argv, "git-upload-archive");
	for (;;) {
		char *buf = packet_read_line(0, NULL);
		if (!buf)
			break;	/* got a flush */
		if (sent_argv.argc > MAX_ARGS)
			die("Too many options (>%d)", MAX_ARGS - 1);

		if (prefixcmp(buf, arg_cmd))
			die("'argument' token or flush expected");
		argv_array_push(&sent_argv, buf + strlen(arg_cmd));
	}

	/* parse all options sent by the client */
	return write_archive(sent_argv.argc, sent_argv.argv, prefix, 0, NULL, 1);
}
Пример #2
0
int cmd_archive(int argc, const char **argv, const char *prefix)
{
	const char *exec = "git-upload-archive";
	const char *output = NULL;
	const char *remote = NULL;
	struct option local_opts[] = {
		OPT_STRING('o', "output", &output, N_("file"),
			N_("write the archive to this file")),
		OPT_STRING(0, "remote", &remote, N_("repo"),
			N_("retrieve the archive from remote repository <repo>")),
		OPT_STRING(0, "exec", &exec, N_("command"),
			N_("path to the remote git-upload-archive command")),
		OPT_END()
	};

	argc = parse_options(argc, argv, prefix, local_opts, NULL,
			     PARSE_OPT_KEEP_ALL);

	if (output)
		create_output_file(output);

	if (remote)
		return run_remote_archiver(argc, argv, remote, exec, output);

	setvbuf(stderr, NULL, _IOLBF, BUFSIZ);

	return write_archive(argc, argv, prefix, 1, output, 0);
}
Пример #3
0
int main2(int argc, const char **argv)
{
	const char *outname;
	argv++;
	outname = *argv++;
	write_archive(outname, argv);
	return 0;
}
Пример #4
0
int cmd_archive(int argc, const char **argv, const char *prefix)
{
	const char *exec = "git-upload-archive";
	const char *output = NULL;
	const char *remote = NULL;
	const char *format_option = NULL;
	struct option local_opts[] = {
		OPT_STRING('o', "output", &output, "file",
			"write the archive to this file"),
		OPT_STRING(0, "remote", &remote, "repo",
			"retrieve the archive from remote repository <repo>"),
		OPT_STRING(0, "exec", &exec, "cmd",
			"path to the remote git-upload-archive command"),
		OPT_END()
	};

	argc = parse_options(argc, argv, prefix, local_opts, NULL,
			     PARSE_OPT_KEEP_ALL);

	if (output) {
		create_output_file(output);
		format_option = format_from_name(output);
	}

	/*
	 * We have enough room in argv[] to muck it in place, because
	 * --output must have been given on the original command line
	 * if we get to this point, and parse_options() must have eaten
	 * it, i.e. we can add back one element to the array.
	 *
	 * We add a fake --format option at the beginning, with the
	 * format inferred from our output filename.  This way explicit
	 * --format options can override it, and the fake option is
	 * inserted before any "--" that might have been given.
	 */
	if (format_option) {
		memmove(argv + 2, argv + 1, sizeof(*argv) * argc);
		argv[1] = format_option;
		argv[++argc] = NULL;
	}

	if (remote)
		return run_remote_archiver(argc, argv, remote, exec);

	setvbuf(stderr, NULL, _IOLBF, BUFSIZ);

	return write_archive(argc, argv, prefix, 1);
}
Пример #5
0
void
tar_mode_c(struct bsdtar *bsdtar)
{
    struct archive *a;
    const void *filter_name;
    int r;

    if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL)
        lafe_errc(1, 0, "no files or directories specified");

    a = archive_write_new();

    /* Support any format that the library supports. */
    if (cset_get_format(bsdtar->cset) == NULL) {
        r = archive_write_set_format_pax_restricted(a);
        cset_set_format(bsdtar->cset, "pax restricted");
    } else {
        r = archive_write_set_format_by_name(a,
                                             cset_get_format(bsdtar->cset));
    }
    if (r != ARCHIVE_OK) {
        fprintf(stderr, "Can't use format %s: %s\n",
                cset_get_format(bsdtar->cset),
                archive_error_string(a));
        usage();
    }

    archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block);
    archive_write_set_bytes_in_last_block(a, bsdtar->bytes_in_last_block);

    r = cset_write_add_filters(bsdtar->cset, a, &filter_name);
    if (r < ARCHIVE_WARN) {
        lafe_errc(1, 0, "Unsupported compression option --%s",
                  (const char *)filter_name);
    }

    set_writer_options(bsdtar, a);
    if (bsdtar->passphrase != NULL)
        r = archive_write_set_passphrase(a, bsdtar->passphrase);
    else
        r = archive_write_set_passphrase_callback(a, bsdtar,
                &passphrase_callback);
    if (r != ARCHIVE_OK)
        lafe_errc(1, 0, "%s", archive_error_string(a));
    if (ARCHIVE_OK != archive_write_open_filename(a, bsdtar->filename))
        lafe_errc(1, 0, "%s", archive_error_string(a));
    write_archive(a, bsdtar);
}
Пример #6
0
static int run_upload_archive(int argc, const char **argv, const char *prefix)
{
	const char *sent_argv[MAX_ARGS];
	const char *arg_cmd = "argument ";
	char *p, buf[4096];
	int sent_argc;
	int len;

	if (argc != 2)
		usage(upload_archive_usage);

	if (strlen(argv[1]) + 1 > sizeof(buf))
		die("insanely long repository name");

	strcpy(buf, argv[1]); /* enter-repo smudges its argument */

	if (!enter_repo(buf, 0))
		die("'%s' does not appear to be a git repository", buf);

	/* put received options in sent_argv[] */
	sent_argc = 1;
	sent_argv[0] = "git-upload-archive";
	for (p = buf;;) {
		/* This will die if not enough free space in buf */
		len = packet_read_line(0, p, (buf + sizeof buf) - p);
		if (len == 0)
			break;	/* got a flush */
		if (sent_argc > MAX_ARGS - 2)
			die("Too many options (>%d)", MAX_ARGS - 2);

		if (p[len-1] == '\n') {
			p[--len] = 0;
		}
		if (len < strlen(arg_cmd) ||
		    strncmp(arg_cmd, p, strlen(arg_cmd)))
			die("'argument' token or flush expected");

		len -= strlen(arg_cmd);
		memmove(p, p + strlen(arg_cmd), len);
		sent_argv[sent_argc++] = p;
		p += len;
		*p++ = 0;
	}
	sent_argv[sent_argc] = NULL;

	/* parse all options sent by the client */
	return write_archive(sent_argc, sent_argv, prefix, 0);
}
Пример #7
0
void
tar_mode_u(struct bsdtar *bsdtar)
{
	int64_t			 end_offset;
	struct archive		*a;
	struct archive_entry	*entry;
	int			 format;
	struct archive_dir_entry	*p;
	struct archive_dir	 archive_dir;

	bsdtar->archive_dir = &archive_dir;
	memset(&archive_dir, 0, sizeof(archive_dir));

	format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;

	/* Sanity-test some arguments and the file. */
	test_for_append(bsdtar);

	bsdtar->fd = open(bsdtar->filename, O_RDWR | O_BINARY);
	if (bsdtar->fd < 0)
		lafe_errc(1, errno,
		    "Cannot open %s", bsdtar->filename);

	a = archive_read_new();
	archive_read_support_filter_all(a);
	archive_read_support_format_tar(a);
	archive_read_support_format_gnutar(a);
	set_reader_options(bsdtar, a);
	if (archive_read_open_fd(a, bsdtar->fd, bsdtar->bytes_per_block)
	    != ARCHIVE_OK) {
		lafe_errc(1, 0,
		    "Can't open %s: %s", bsdtar->filename,
		    archive_error_string(a));
	}

	/* Build a list of all entries and their recorded mod times. */
	while (0 == archive_read_next_header(a, &entry)) {
		if (archive_filter_code(a, 0) != ARCHIVE_FILTER_NONE) {
			archive_read_free(a);
			close(bsdtar->fd);
			lafe_errc(1, 0,
			    "Cannot append to compressed archive.");
		}
		if (archive_match_exclude_entry(bsdtar->matching,
		    ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER |
		    ARCHIVE_MATCH_EQUAL, entry) != ARCHIVE_OK)
			lafe_errc(1, 0, "Error : %s",
			    archive_error_string(bsdtar->matching));
		/* Record the last format determination we see */
		format = archive_format(a);
		/* Keep going until we hit end-of-archive */
	}

	end_offset = archive_read_header_position(a);
	archive_read_free(a);

	/* Re-open archive for writing. */
	a = archive_write_new();
	/*
	 * Set format to same one auto-detected above.
	 */
	archive_write_set_format(a, format);
	archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block);
	archive_write_set_bytes_in_last_block(a, bsdtar->bytes_in_last_block);

	if (lseek(bsdtar->fd, end_offset, SEEK_SET) < 0)
		lafe_errc(1, errno, "Could not seek to archive end");
	set_writer_options(bsdtar, a);
	if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd))
		lafe_errc(1, 0, "%s", archive_error_string(a));

	write_archive(a, bsdtar);

	close(bsdtar->fd);
	bsdtar->fd = -1;

	while (bsdtar->archive_dir->head != NULL) {
		p = bsdtar->archive_dir->head->next;
		free(bsdtar->archive_dir->head->name);
		free(bsdtar->archive_dir->head);
		bsdtar->archive_dir->head = p;
	}
	bsdtar->archive_dir->tail = NULL;
}
Пример #8
0
/*
 * Same as 'c', except we only support tar or empty formats in
 * uncompressed files on disk.
 */
void
tar_mode_r(struct bsdtar *bsdtar)
{
	int64_t	end_offset;
	int	format;
	struct archive *a;
	struct archive_entry *entry;
	int	r;

	/* Sanity-test some arguments and the file. */
	test_for_append(bsdtar);

	format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;

#if defined(__BORLANDC__)
	bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY);
#else
	bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT | O_BINARY, 0666);
#endif
	if (bsdtar->fd < 0)
		lafe_errc(1, errno,
		    "Cannot open %s", bsdtar->filename);

	a = archive_read_new();
	archive_read_support_filter_all(a);
	archive_read_support_format_empty(a);
	archive_read_support_format_tar(a);
	archive_read_support_format_gnutar(a);
	set_reader_options(bsdtar, a);
	r = archive_read_open_fd(a, bsdtar->fd, 10240);
	if (r != ARCHIVE_OK)
		lafe_errc(1, archive_errno(a),
		    "Can't read archive %s: %s", bsdtar->filename,
		    archive_error_string(a));
	while (0 == archive_read_next_header(a, &entry)) {
		if (archive_filter_code(a, 0) != ARCHIVE_FILTER_NONE) {
			archive_read_free(a);
			close(bsdtar->fd);
			lafe_errc(1, 0,
			    "Cannot append to compressed archive.");
		}
		/* Keep going until we hit end-of-archive */
		format = archive_format(a);
	}

	end_offset = archive_read_header_position(a);
	archive_read_free(a);

	/* Re-open archive for writing */
	a = archive_write_new();
	/*
	 * Set the format to be used for writing.  To allow people to
	 * extend empty files, we need to allow them to specify the format,
	 * which opens the possibility that they will specify a format that
	 * doesn't match the existing format.  Hence, the following bit
	 * of arcane ugliness.
	 */

	if (cset_get_format(bsdtar->cset) != NULL) {
		/* If the user requested a format, use that, but ... */
		archive_write_set_format_by_name(a,
		    cset_get_format(bsdtar->cset));
		/* ... complain if it's not compatible. */
		format &= ARCHIVE_FORMAT_BASE_MASK;
		if (format != (int)(archive_format(a) & ARCHIVE_FORMAT_BASE_MASK)
		    && format != ARCHIVE_FORMAT_EMPTY) {
			lafe_errc(1, 0,
			    "Format %s is incompatible with the archive %s.",
			    cset_get_format(bsdtar->cset), bsdtar->filename);
		}
	} else {
		/*
		 * Just preserve the current format, with a little care
		 * for formats that libarchive can't write.
		 */
		if (format == ARCHIVE_FORMAT_EMPTY)
			format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
		archive_write_set_format(a, format);
	}
	if (lseek(bsdtar->fd, end_offset, SEEK_SET) < 0)
		lafe_errc(1, errno, "Could not seek to archive end");
	set_writer_options(bsdtar, a);
	if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd))
		lafe_errc(1, 0, "%s", archive_error_string(a));

	write_archive(a, bsdtar); /* XXX check return val XXX */

	close(bsdtar->fd);
	bsdtar->fd = -1;
}
Пример #9
0
void
tar_mode_c(struct bsdtar *bsdtar)
{
	struct archive *a;
	int r;

	if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL)
		lafe_errc(1, 0, "no files or directories specified");

	a = archive_write_new();

	/* Support any format that the library supports. */
	if (bsdtar->create_format == NULL) {
		r = archive_write_set_format_pax_restricted(a);
		bsdtar->create_format = "pax restricted";
	} else {
		r = archive_write_set_format_by_name(a, bsdtar->create_format);
	}
	if (r != ARCHIVE_OK) {
		fprintf(stderr, "Can't use format %s: %s\n",
		    bsdtar->create_format,
		    archive_error_string(a));
		usage();
	}

	archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block);
	archive_write_set_bytes_in_last_block(a, bsdtar->bytes_in_last_block);

	if (bsdtar->compress_program) {
		archive_write_set_compression_program(a, bsdtar->compress_program);
	} else {
		switch (bsdtar->create_compression) {
		case 0:
			r = ARCHIVE_OK;
			break;
		case 'j': case 'y':
			r = archive_write_set_compression_bzip2(a);
			break;
		case 'J':
			r = archive_write_set_compression_xz(a);
			break;
		case OPTION_LZIP:
			r = archive_write_set_compression_lzip(a);
			break;
		case OPTION_LZMA:
			r = archive_write_set_compression_lzma(a);
			break;
		case 'z':
			r = archive_write_set_compression_gzip(a);
			break;
		case 'Z':
			r = archive_write_set_compression_compress(a);
			break;
		default:
			lafe_errc(1, 0,
			    "Unrecognized compression option -%c",
			    bsdtar->create_compression);
		}
		if (r != ARCHIVE_OK) {
			lafe_errc(1, 0,
			    "Unsupported compression option -%c",
			    bsdtar->create_compression);
		}
	}

	if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options))
		lafe_errc(1, 0, "%s", archive_error_string(a));
	if (ARCHIVE_OK != archive_write_open_file(a, bsdtar->filename))
		lafe_errc(1, 0, "%s", archive_error_string(a));
	write_archive(a, bsdtar);
}
Пример #10
0
void
tarsnap_mode_c(struct bsdtar *bsdtar)
{
	struct archive *a;
	size_t i;

	if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL)
		bsdtar_errc(bsdtar, 1, 0, "no files or directories specified");

	for (i = 0; bsdtar->argv[i] != NULL; i++) {
		if (bsdtar->argv[i][0] == '-' && bsdtar->argv[i][1] == '-') {
			bsdtar_warnc(bsdtar, 0,
			    "List of objects to archive includes '%s'."
			    "  This might not be what you intended.",
			    bsdtar->argv[i]);
			break;
		}
	}

	a = archive_write_new();

	/* We only support the pax restricted format. */
	archive_write_set_format_pax_restricted(a);

	/* Set the block size to zero -- we don't want buffering. */
	archive_write_set_bytes_per_block(a, 0);

	/* Open the archive, keeping a cookie for talking to the tape layer. */
	bsdtar->write_cookie = archive_write_open_multitape(a,
	    bsdtar->machinenum, bsdtar->cachedir, bsdtar->tapenames[0],
	    bsdtar->argc_orig, bsdtar->argv_orig,
	    bsdtar->option_print_stats, bsdtar->option_dryrun,
	    bsdtar->creationtime);
	if (bsdtar->write_cookie == NULL)
		bsdtar_errc(bsdtar, 1, 0, "%s", archive_error_string(a));

	/*
	 * Remember the device and inode numbers of the cache directory, so
	 * that we can skip is in write_hierarchy().
	 */
	if (getdevino(a, bsdtar->cachedir,
	    &bsdtar->cachedir_dev, &bsdtar->cachedir_ino))
		bsdtar_errc(bsdtar, 1, 0, "%s", archive_error_string(a));

	/* If the chunkification cache is enabled, read it. */
	if ((bsdtar->cachecrunch < 2) && (bsdtar->cachedir != NULL)) {
		bsdtar->chunk_cache = ccache_read(bsdtar->cachedir);
		if (bsdtar->chunk_cache == NULL)
			bsdtar_errc(bsdtar, 1, errno, "Error reading cache");
	}

	write_archive(a, bsdtar);

	/*
	 * If this isn't a dry run and we're running with the chunkification
	 * cache enabled, write the cache back to disk.
	 */
	if ((bsdtar->option_dryrun == 0) && (bsdtar->cachecrunch < 2)) {
		if (ccache_write(bsdtar->chunk_cache, bsdtar->cachedir))
			bsdtar_errc(bsdtar, 1, errno, "Error writing cache");
	}

	/* Free the chunkification cache. */
	if (bsdtar->cachecrunch < 2)
		ccache_free(bsdtar->chunk_cache);
}
Пример #11
0
void
tar_mode_u(struct bsdtar *bsdtar)
{
	off_t			 end_offset;
	struct archive		*a;
	struct archive_entry	*entry;
	int			 format;
	struct archive_dir_entry	*p;
	struct archive_dir	 archive_dir;

	bsdtar->archive_dir = &archive_dir;
	memset(&archive_dir, 0, sizeof(archive_dir));

	format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;

	/* Sanity-test some arguments and the file. */
	test_for_append(bsdtar);

	bsdtar->fd = open(bsdtar->filename, O_RDWR);
	if (bsdtar->fd < 0)
		bsdtar_errc(bsdtar, 1, errno,
		    "Cannot open %s", bsdtar->filename);

	a = archive_read_new();
	archive_read_support_compression_all(a);
	archive_read_support_format_tar(a);
	archive_read_support_format_gnutar(a);
	if (archive_read_open_fd(a, bsdtar->fd,
	    bsdtar->bytes_per_block != 0 ? bsdtar->bytes_per_block :
		DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) {
		bsdtar_errc(bsdtar, 1, 0,
		    "Can't open %s: %s", bsdtar->filename,
		    archive_error_string(a));
	}

	/* Build a list of all entries and their recorded mod times. */
	while (0 == archive_read_next_header(a, &entry)) {
		if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) {
			archive_read_finish(a);
			close(bsdtar->fd);
			bsdtar_errc(bsdtar, 1, 0,
			    "Cannot append to compressed archive.");
		}
		add_dir_list(bsdtar, archive_entry_pathname(entry),
		    archive_entry_mtime(entry),
		    archive_entry_mtime_nsec(entry));
		/* Record the last format determination we see */
		format = archive_format(a);
		/* Keep going until we hit end-of-archive */
	}

	end_offset = archive_read_header_position(a);
	archive_read_finish(a);

	/* Re-open archive for writing. */
	a = archive_write_new();
	archive_write_set_compression_none(a);
	/*
	 * Set format to same one auto-detected above, except that
	 * we don't write GNU tar format, so use ustar instead.
	 */
	if (format == ARCHIVE_FORMAT_TAR_GNUTAR)
		format = ARCHIVE_FORMAT_TAR_USTAR;
	archive_write_set_format(a, format);
	if (bsdtar->bytes_per_block != 0) {
		archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block);
		archive_write_set_bytes_in_last_block(a,
		    bsdtar->bytes_per_block);
	} else
		archive_write_set_bytes_per_block(a, DEFAULT_BYTES_PER_BLOCK);
	lseek(bsdtar->fd, end_offset, SEEK_SET);
	ftruncate(bsdtar->fd, end_offset);
	if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options))
		bsdtar_errc(bsdtar, 1, 0, archive_error_string(a));
	if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd))
		bsdtar_errc(bsdtar, 1, 0, archive_error_string(a));

	write_archive(a, bsdtar);

	close(bsdtar->fd);
	bsdtar->fd = -1;

	while (bsdtar->archive_dir->head != NULL) {
		p = bsdtar->archive_dir->head->next;
		free(bsdtar->archive_dir->head->name);
		free(bsdtar->archive_dir->head);
		bsdtar->archive_dir->head = p;
	}
	bsdtar->archive_dir->tail = NULL;
}
Пример #12
0
/*
 * Same as 'c', except we only support tar or empty formats in
 * uncompressed files on disk.
 */
void
tar_mode_r(struct bsdtar *bsdtar)
{
	off_t	end_offset;
	int	format;
	struct archive *a;
	struct archive_entry *entry;
	int	r;

	/* Sanity-test some arguments and the file. */
	test_for_append(bsdtar);

	format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;

	bsdtar->fd = open(bsdtar->filename, O_RDWR | O_CREAT, 0666);
	if (bsdtar->fd < 0)
		bsdtar_errc(bsdtar, 1, errno,
		    "Cannot open %s", bsdtar->filename);

	a = archive_read_new();
	archive_read_support_compression_all(a);
	archive_read_support_format_tar(a);
	archive_read_support_format_gnutar(a);
	r = archive_read_open_fd(a, bsdtar->fd, 10240);
	if (r != ARCHIVE_OK)
		bsdtar_errc(bsdtar, 1, archive_errno(a),
		    "Can't read archive %s: %s", bsdtar->filename,
		    archive_error_string(a));
	while (0 == archive_read_next_header(a, &entry)) {
		if (archive_compression(a) != ARCHIVE_COMPRESSION_NONE) {
			archive_read_finish(a);
			close(bsdtar->fd);
			bsdtar_errc(bsdtar, 1, 0,
			    "Cannot append to compressed archive.");
		}
		/* Keep going until we hit end-of-archive */
		format = archive_format(a);
	}

	end_offset = archive_read_header_position(a);
	archive_read_finish(a);

	/* Re-open archive for writing */
	a = archive_write_new();
	archive_write_set_compression_none(a);
	/*
	 * Set the format to be used for writing.  To allow people to
	 * extend empty files, we need to allow them to specify the format,
	 * which opens the possibility that they will specify a format that
	 * doesn't match the existing format.  Hence, the following bit
	 * of arcane ugliness.
	 */

	if (bsdtar->create_format != NULL) {
		/* If the user requested a format, use that, but ... */
		archive_write_set_format_by_name(a,
		    bsdtar->create_format);
		/* ... complain if it's not compatible. */
		format &= ARCHIVE_FORMAT_BASE_MASK;
		if (format != (int)(archive_format(a) & ARCHIVE_FORMAT_BASE_MASK)
		    && format != ARCHIVE_FORMAT_EMPTY) {
			bsdtar_errc(bsdtar, 1, 0,
			    "Format %s is incompatible with the archive %s.",
			    bsdtar->create_format, bsdtar->filename);
		}
	} else {
		/*
		 * Just preserve the current format, with a little care
		 * for formats that libarchive can't write.
		 */
		if (format == ARCHIVE_FORMAT_TAR_GNUTAR)
			/* TODO: When gtar supports pax, use pax restricted. */
			format = ARCHIVE_FORMAT_TAR_USTAR;
		if (format == ARCHIVE_FORMAT_EMPTY)
			format = ARCHIVE_FORMAT_TAR_PAX_RESTRICTED;
		archive_write_set_format(a, format);
	}
	lseek(bsdtar->fd, end_offset, SEEK_SET); /* XXX check return val XXX */
	if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options))
		bsdtar_errc(bsdtar, 1, 0, archive_error_string(a));
	if (ARCHIVE_OK != archive_write_open_fd(a, bsdtar->fd))
		bsdtar_errc(bsdtar, 1, 0, archive_error_string(a));

	write_archive(a, bsdtar); /* XXX check return val XXX */

	close(bsdtar->fd);
	bsdtar->fd = -1;
}
Пример #13
0
void
tar_mode_c(struct bsdtar *bsdtar)
{
	struct archive *a;
	int r;

	if (*bsdtar->argv == NULL && bsdtar->names_from_file == NULL)
		bsdtar_errc(bsdtar, 1, 0, "no files or directories specified");

	a = archive_write_new();

	/* Support any format that the library supports. */
	if (bsdtar->create_format == NULL) {
		r = archive_write_set_format_pax_restricted(a);
		bsdtar->create_format = "pax restricted";
	} else {
		r = archive_write_set_format_by_name(a, bsdtar->create_format);
	}
	if (r != ARCHIVE_OK) {
		fprintf(stderr, "Can't use format %s: %s\n",
		    bsdtar->create_format,
		    archive_error_string(a));
		usage(bsdtar);
	}

	/*
	 * If user explicitly set the block size, then assume they
	 * want the last block padded as well.  Otherwise, use the
	 * default block size and accept archive_write_open_file()'s
	 * default padding decisions.
	 */
	if (bsdtar->bytes_per_block != 0) {
		archive_write_set_bytes_per_block(a, bsdtar->bytes_per_block);
		archive_write_set_bytes_in_last_block(a,
		    bsdtar->bytes_per_block);
	} else
		archive_write_set_bytes_per_block(a, DEFAULT_BYTES_PER_BLOCK);

	if (bsdtar->compress_program) {
		archive_write_set_compression_program(a, bsdtar->compress_program);
	} else {
		switch (bsdtar->create_compression) {
		case 0:
			archive_write_set_compression_none(a);
			break;
#ifdef HAVE_LIBBZ2
		case 'j': case 'y':
			archive_write_set_compression_bzip2(a);
			break;
#endif
#ifdef HAVE_LIBLZMA
		case 'J':
			archive_write_set_compression_xz(a);
			break;
		case OPTION_LZMA:
			archive_write_set_compression_lzma(a);
			break;
#endif
#ifdef HAVE_LIBZ
		case 'z':
			archive_write_set_compression_gzip(a);
			break;
#endif
		case 'Z':
			archive_write_set_compression_compress(a);
			break;
		default:
			bsdtar_errc(bsdtar, 1, 0,
			    "Unrecognized compression option -%c",
			    bsdtar->create_compression);
		}
	}

	if (ARCHIVE_OK != archive_write_set_options(a, bsdtar->option_options))
		bsdtar_errc(bsdtar, 1, 0, archive_error_string(a));
	if (ARCHIVE_OK != archive_write_open_file(a, bsdtar->filename))
		bsdtar_errc(bsdtar, 1, 0, archive_error_string(a));
	write_archive(a, bsdtar);
}