int
archive_read_support_compression_bzip2(struct archive *_a)
{
	struct archive_read *a = (struct archive_read *)_a;
	struct archive_read_filter_bidder *reader = __archive_read_get_bidder(a);

	if (reader == NULL)
		return (ARCHIVE_FATAL);

	reader->data = NULL;
	reader->bid = bzip2_reader_bid;
	reader->init = bzip2_reader_init;
	reader->options = NULL;
	reader->free = bzip2_reader_free;
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
	return (ARCHIVE_OK);
#else
	archive_set_error(_a, ARCHIVE_ERRNO_MISC,
	    "Using external bunzip2 program");
	return (ARCHIVE_WARN);
#endif
}
Esempio n. 2
0
/*
 * Write file data to an archive entry.
 */
static int
shar_write_entry_data(struct archive *a, const int fd)
{
	ssize_t bytes_read, bytes_written;

	assert(a != NULL);
	assert(fd >= 0);

	bytes_read = read(fd, buffer, sizeof(buffer));
	while (bytes_read != 0) {
		if (bytes_read < 0) {
			archive_set_error(a, errno, "Read failed");
			return (ARCHIVE_WARN);
		}
		bytes_written = archive_write_data(a, buffer, bytes_read);
		if (bytes_written < 0)
			return (ARCHIVE_WARN);
		bytes_read = read(fd, buffer, sizeof(buffer));
	}

	return (ARCHIVE_OK);
}
Esempio n. 3
0
static int
ensure_in_buff_size(struct archive_read_filter *self,
    struct uudecode *uudecode, size_t size)
{

	if (size > uudecode->in_allocated) {
		unsigned char *ptr;
		size_t newsize;

		/*
		 * Calculate a new buffer size for in_buff.
		 * Increase its value until it has enough size we need.
		 */
		newsize = uudecode->in_allocated;
		do {
			if (newsize < IN_BUFF_SIZE*32)
				newsize <<= 1;
			else
				newsize += IN_BUFF_SIZE;
		} while (size > newsize);
		/* Allocate the new buffer. */
		ptr = malloc(newsize);
		if (ptr == NULL) {
			free(ptr);
			archive_set_error(&self->archive->archive,
			    ENOMEM,
    			    "Can't allocate data for uudecode");
			return (ARCHIVE_FATAL);
		}
		/* Move the remaining data in in_buff into the new buffer. */
		if (uudecode->in_cnt)
			memmove(ptr, uudecode->in_buff, uudecode->in_cnt);
		/* Replace in_buff with the new buffer. */
		free(uudecode->in_buff);
		uudecode->in_buff = ptr;
		uudecode->in_allocated = newsize;
	}
	return (ARCHIVE_OK);
}
Esempio n. 4
0
/*
 * Don't use _open_memory2() in production code; the archive_read_open_memory()
 * version is the one you really want.  This is just here so that
 * test harnesses can exercise block operations inside the library.
 */
int
archive_read_open_memory2(struct archive *a, const void *buff,
    size_t size, size_t read_size)
{
	struct read_memory_data *mine;

	mine = (struct read_memory_data *)calloc(1, sizeof(*mine));
	if (mine == NULL) {
		archive_set_error(a, ENOMEM, "No memory");
		return (ARCHIVE_FATAL);
	}
	mine->start = mine->p = (const unsigned char *)buff;
	mine->end = mine->start + size;
	mine->read_size = read_size;
	archive_read_set_open_callback(a, memory_read_open);
	archive_read_set_read_callback(a, memory_read);
	archive_read_set_seek_callback(a, memory_read_seek);
	archive_read_set_skip_callback(a, memory_read_skip);
	archive_read_set_close_callback(a, memory_read_close);
	archive_read_set_callback_data(a, mine);
	return (archive_read_open1(a));
}
Esempio n. 5
0
/**
 * archive_write_open_multitape(a, machinenum, cachedir, tapename, argc,
 *     argv, printstats, dryrun):
 * Open the multitape tape ${tapename} for writing and associate it with the
 * archive $a$.  If ${printstats} is non-zero, print archive statistics when
 * the tape is closed.  If ${dryrun} is non-zero, perform a dry run.  Return
 * a cookie which can be passed to the multitape layer.
 */
void *
archive_write_open_multitape(struct archive * a, uint64_t machinenum,
    const char * cachedir, const char * tapename, int argc,
    char ** argv, int printstats, int dryrun)
{
	struct multitape_write_internal * d;

	/* Clear any error messages from the archive. */
	archive_clear_error(a);

	if ((d = writetape_open(machinenum, cachedir, tapename,
	    argc, argv, printstats, dryrun)) == NULL) {
		archive_set_error(a, errno, "Error creating new archive");
		return (NULL);
	}

	if (archive_write_open(a, d, NULL, write_write, write_close)) {
		writetape_free(d);
		return (NULL);
	} else
		return (d);
}
Esempio n. 6
0
int
archive_read_open_FILE(struct archive *a, FILE *f)
{
	struct stat st;
	struct read_FILE_data *mine;
	size_t block_size = 128 * 1024;
	void *b;

	archive_clear_error(a);
	mine = (struct read_FILE_data *)malloc(sizeof(*mine));
	b = malloc(block_size);
	if (mine == NULL || b == NULL) {
		archive_set_error(a, ENOMEM, "No memory");
		free(mine);
		free(b);
		return (ARCHIVE_FATAL);
	}
	mine->block_size = block_size;
	mine->buffer = b;
	mine->f = f;
	/*
	 * If we can't fstat() the file, it may just be that it's not
	 * a file.  (FILE * objects can wrap many kinds of I/O
	 * streams, some of which don't support fileno()).)
	 */
	if (fstat(fileno(mine->f), &st) == 0 && S_ISREG(st.st_mode)) {
		archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino);
		/* Enable the seek optimization only for regular files. */
		mine->can_skip = 1;
	} else
		mine->can_skip = 0;

#if defined(__CYGWIN__) || defined(_WIN32)
	setmode(fileno(mine->f), O_BINARY);
#endif

	return (archive_read_open2(a, mine, NULL, file_read,
		    file_skip, file_close));
}
/*
 * Initialize the filter object.
 */
static int
lzop_bidder_init(struct archive_read_filter *self)
{
	struct read_lzop *state;

	self->code = ARCHIVE_FILTER_LZOP;
	self->name = "lzop";

	state = (struct read_lzop *)calloc(sizeof(*state), 1);
	if (state == NULL) {
		archive_set_error(&self->archive->archive, ENOMEM,
		    "Can't allocate data for lzop decompression");
		return (ARCHIVE_FATAL);
	}

	self->data = state;
	self->read = lzop_filter_read;
	self->skip = NULL; /* not supported */
	self->close = lzop_filter_close;

	return (ARCHIVE_OK);
}
/*
 * Read "uncompressed" data.  According to the current specification,
 * if ZIP_LENGTH_AT_END is specified, then the size fields in the
 * initial file header are supposed to be set to zero.  This would, of
 * course, make it impossible for us to read the archive, since we
 * couldn't determine the end of the file data.  Info-ZIP seems to
 * include the real size fields both before and after the data in this
 * case (the CRC only appears afterwards), so this works as you would
 * expect.
 *
 * Returns ARCHIVE_OK if successful, ARCHIVE_FATAL otherwise, sets
 * zip->end_of_entry if it consumes all of the data.
 */
static int
zip_read_data_none(struct archive_read *a, const void **buff,
    size_t *size, off_t *offset)
{
	struct zip *zip;
	ssize_t bytes_avail;

	zip = (struct zip *)(a->format->data);

	if (zip->entry_bytes_remaining == 0) {
		*buff = NULL;
		*size = 0;
		*offset = zip->entry_offset;
		zip->end_of_entry = 1;
		return (ARCHIVE_OK);
	}
	/*
	 * Note: '1' here is a performance optimization.
	 * Recall that the decompression layer returns a count of
	 * available bytes; asking for more than that forces the
	 * decompressor to combine reads by copying data.
	 */
	bytes_avail = (a->decompressor->read_ahead)(a, buff, 1);
	if (bytes_avail <= 0) {
		archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
		    "Truncated ZIP file data");
		return (ARCHIVE_FATAL);
	}
	if (bytes_avail > zip->entry_bytes_remaining)
		bytes_avail = zip->entry_bytes_remaining;
	(a->decompressor->consume)(a, bytes_avail);
	*size = bytes_avail;
	*offset = zip->entry_offset;
	zip->entry_offset += *size;
	zip->entry_bytes_remaining -= *size;
	zip->entry_uncompressed_bytes_read += *size;
	zip->entry_compressed_bytes_read += *size;
	return (ARCHIVE_OK);
}
/*
 * Device entries have one of the following forms:
 * raw dev_t
 * format,major,minor[,subdevice]
 *
 * Just use major and minor, no translation etc is done
 * between formats.
 */
static int
parse_device(struct archive *a, struct archive_entry *entry, char *val)
{
	char *comma1, *comma2;

	comma1 = strchr(val, ',');
	if (comma1 == NULL) {
		archive_entry_set_dev(entry, mtree_atol10(&val));
		return (ARCHIVE_OK);
	}
	++comma1;
	comma2 = strchr(comma1, ',');
	if (comma2 == NULL) {
		archive_set_error(a, ARCHIVE_ERRNO_FILE_FORMAT,
		    "Malformed device attribute");
		return (ARCHIVE_WARN);
	}
	++comma2;
	archive_entry_set_rdevmajor(entry, mtree_atol(&comma1));
	archive_entry_set_rdevminor(entry, mtree_atol(&comma2));
	return (ARCHIVE_OK);
}
Esempio n. 10
0
/*
 * Used internally by read format handlers to register their bid and
 * initialization functions.
 */
int
__archive_read_register_format(struct archive_read *a,
    void *format_data,
    const char *name,
    int (*bid)(struct archive_read *),
    int (*options)(struct archive_read *, const char *, const char *),
    int (*read_header)(struct archive_read *, struct archive_entry *),
    int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
    int (*read_data_skip)(struct archive_read *),
    int (*cleanup)(struct archive_read *))
{
	int i, number_slots;

	archive_check_magic(&a->archive,
	    ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
	    "__archive_read_register_format");

	number_slots = sizeof(a->formats) / sizeof(a->formats[0]);

	for (i = 0; i < number_slots; i++) {
		if (a->formats[i].bid == bid)
			return (ARCHIVE_WARN); /* We've already installed */
		if (a->formats[i].bid == NULL) {
			a->formats[i].bid = bid;
			a->formats[i].options = options;
			a->formats[i].read_header = read_header;
			a->formats[i].read_data = read_data;
			a->formats[i].read_data_skip = read_data_skip;
			a->formats[i].cleanup = cleanup;
			a->formats[i].data = format_data;
			a->formats[i].name = name;
			return (ARCHIVE_OK);
		}
	}

	archive_set_error(&a->archive, ENOMEM,
	    "Not enough slots for format registration");
	return (ARCHIVE_FATAL);
}
Esempio n. 11
0
int
archive_read_add_passphrase(struct archive *_a, const char *passphrase)
{
	struct archive_read *a = (struct archive_read *)_a;
	struct archive_read_passphrase *p;

	archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
		"archive_read_add_passphrase");

	if (passphrase == NULL || passphrase[0] == '\0') {
		archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
		    "Empty passphrase is unacceptable");
		return (ARCHIVE_FAILED);
	}

	p = new_read_passphrase(a, passphrase);
	if (p == NULL)
		return (ARCHIVE_FATAL);
	add_passphrase_to_tail(a, p);

	return (ARCHIVE_OK);
}
/*
 * Initialize the filter object
 */
static int
zstd_bidder_init(struct archive_read_filter *self)
{
	struct private_data *state;
	const size_t out_block_size = ZSTD_DStreamOutSize();
	void *out_block;
	ZSTD_DStream *dstream;

	self->code = ARCHIVE_FILTER_ZSTD;
	self->name = "zstd";

	state = (struct private_data *)calloc(sizeof(*state), 1);
	out_block = (unsigned char *)malloc(out_block_size);
	dstream = ZSTD_createDStream();

	if (state == NULL || out_block == NULL || dstream == NULL) {
		free(out_block);
		free(state);
		ZSTD_freeDStream(dstream); /* supports free on NULL */
		archive_set_error(&self->archive->archive, ENOMEM,
		    "Can't allocate data for zstd decompression");
		return (ARCHIVE_FATAL);
	}

	self->data = state;

	state->out_block_size = out_block_size;
	state->out_block = out_block;
	state->dstream = dstream;
	self->read = zstd_filter_read;
	self->skip = NULL; /* not supported */
	self->close = zstd_filter_close;

	state->eof = 0;
	state->in_frame = 0;

	return (ARCHIVE_OK);
}
int
archive_read_support_format_ar(struct archive *_a)
{
	struct archive_read *a = (struct archive_read *)_a;
	struct ar *ar;
	int r;

	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
	    ARCHIVE_STATE_NEW, "archive_read_support_format_ar");

	ar = (struct ar *)malloc(sizeof(*ar));
	if (ar == NULL) {
		archive_set_error(&a->archive, ENOMEM,
		    "Can't allocate ar data");
		return (ARCHIVE_FATAL);
	}
	memset(ar, 0, sizeof(*ar));
	ar->strtab = NULL;

	r = __archive_read_register_format(a,
	    ar,
	    "ar",
	    archive_read_format_ar_bid,
	    NULL,
	    archive_read_format_ar_read_header,
	    archive_read_format_ar_read_data,
	    archive_read_format_ar_skip,
	    NULL,
	    archive_read_format_ar_cleanup,
	    NULL,
	    NULL);

	if (r != ARCHIVE_OK) {
		free(ar);
		return (r);
	}
	return (ARCHIVE_OK);
}
static const char *
lookup_gname_helper(struct name_cache *cache, id_t id)
{
	struct group	grent, *result;
	int r;

	if (cache->buff_size == 0) {
		cache->buff_size = 256;
		cache->buff = malloc(cache->buff_size);
	}
	if (cache->buff == NULL)
		return (NULL);
	for (;;) {
		result = &grent; /* Old getgrgid_r ignores last arg. */
		r = getgrgid_r((gid_t)id, &grent,
			       cache->buff, cache->buff_size, &result);
		if (r == 0)
			break;
		if (r != ERANGE)
			break;
		/* ERANGE means our buffer was too small, but POSIX
		 * doesn't tell us how big the buffer should be, so
		 * we just double it and try again. */
		cache->buff_size *= 2;
		cache->buff = realloc(cache->buff, cache->buff_size);
		if (cache->buff == NULL)
			break;
	}
	if (r != 0) {
		archive_set_error(cache->archive, errno,
		    "Can't lookup group for id %d", (int)id);
		return (NULL);
	}
	if (result == NULL)
		return (NULL);

	return strdup(result->gr_name);
}
static int
header_bin_be(struct archive_read *a, struct cpio *cpio,
    struct archive_entry *entry, size_t *namelength, size_t *name_pad)
{
	const void *h;
	const unsigned char *header;

	a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_BE;
	a->archive.archive_format_name = "cpio (big-endian binary)";

	/* Read fixed-size portion of header. */
	h = __archive_read_ahead(a, bin_header_size, NULL);
	if (h == NULL) {
	    archive_set_error(&a->archive, 0,
		"End of file trying to read next cpio header");
	    return (ARCHIVE_FATAL);
	}

	/* Parse out binary fields. */
	header = (const unsigned char *)h;

	archive_entry_set_dev(entry, header[bin_dev_offset] * 256 + header[bin_dev_offset + 1]);
	archive_entry_set_ino(entry, header[bin_ino_offset] * 256 + header[bin_ino_offset + 1]);
	archive_entry_set_mode(entry, header[bin_mode_offset] * 256 + header[bin_mode_offset + 1]);
	archive_entry_set_uid(entry, header[bin_uid_offset] * 256 + header[bin_uid_offset + 1]);
	archive_entry_set_gid(entry, header[bin_gid_offset] * 256 + header[bin_gid_offset + 1]);
	archive_entry_set_nlink(entry, header[bin_nlink_offset] * 256 + header[bin_nlink_offset + 1]);
	archive_entry_set_rdev(entry, header[bin_rdev_offset] * 256 + header[bin_rdev_offset + 1]);
	archive_entry_set_mtime(entry, be4(header + bin_mtime_offset), 0);
	*namelength = header[bin_namesize_offset] * 256 + header[bin_namesize_offset + 1];
	*name_pad = *namelength & 1; /* Pad to even. */

	cpio->entry_bytes_remaining = be4(header + bin_filesize_offset);
	archive_entry_set_size(entry, cpio->entry_bytes_remaining);
	cpio->entry_padding = cpio->entry_bytes_remaining & 1; /* Pad to even. */
	    __archive_read_consume(a, bin_header_size);
	return (ARCHIVE_OK);
}
Esempio n. 16
0
int64_t
__archive_read_filter_consume(struct archive_read_filter * filter,
    int64_t request)
{
	int64_t skipped;

	if (request < 0)
		return ARCHIVE_FATAL;
	if (request == 0)
		return 0;

	skipped = advance_file_pointer(filter, request);
	if (skipped == request)
		return (skipped);
	/* We hit EOF before we satisfied the skip request. */
	if (skipped < 0)  /* Map error code to 0 for error message below. */
		skipped = 0;
	archive_set_error(&filter->archive->archive,
	    ARCHIVE_ERRNO_MISC,
	    "Truncated input file (needed %jd bytes, only %jd available)",
	    (intmax_t)request, (intmax_t)skipped);
	return (ARCHIVE_FATAL);
}
int
archive_read_support_format_mtree(struct archive *_a)
{
	struct archive_read *a = (struct archive_read *)_a;
	struct mtree *mtree;
	int r;

	mtree = (struct mtree *)malloc(sizeof(*mtree));
	if (mtree == NULL) {
		archive_set_error(&a->archive, ENOMEM,
		    "Can't allocate mtree data");
		return (ARCHIVE_FATAL);
	}
	memset(mtree, 0, sizeof(*mtree));
	mtree->fd = -1;

	r = __archive_read_register_format(a, mtree, "mtree",
	    mtree_bid, NULL, read_header, read_data, skip, cleanup);

	if (r != ARCHIVE_OK)
		free(mtree);
	return (ARCHIVE_OK);
}
/*
 * Clean up the decompressor.
 */
static int
lzma_filter_close(struct archive_read_filter *self)
{
	struct private_data *state;
	int ret;

	state = (struct private_data *)self->data;
	ret = ARCHIVE_OK;
	switch (lzmadec_end(&(state->stream))) {
	case LZMADEC_OK:
		break;
	default:
		archive_set_error(&(self->archive->archive),
		    ARCHIVE_ERRNO_MISC,
		    "Failed to clean up %s compressor",
		    self->archive->archive.compression_name);
		ret = ARCHIVE_FATAL;
	}

	free(state->out_block);
	free(state);
	return (ret);
}
int
archive_read_support_compression_xz(struct archive *_a)
{
	struct archive_read *a = (struct archive_read *)_a;
	struct archive_read_filter_bidder *bidder = __archive_read_get_bidder(a);

	archive_clear_error(_a);
	if (bidder == NULL)
		return (ARCHIVE_FATAL);

	bidder->data = NULL;
	bidder->bid = xz_bidder_bid;
	bidder->init = xz_bidder_init;
	bidder->options = NULL;
	bidder->free = NULL;
#if HAVE_LZMA_H && HAVE_LIBLZMA
	return (ARCHIVE_OK);
#else
	archive_set_error(_a, ARCHIVE_ERRNO_MISC,
	    "Using external unxz program for xz decompression");
	return (ARCHIVE_WARN);
#endif
}
/*
 * Set output format to 'GNU tar' format.
 */
int
archive_write_set_format_gnutar(struct archive *_a)
{
	struct archive_write *a = (struct archive_write *)_a;
	struct gnutar *gnutar;

	gnutar = (struct gnutar *)calloc(1, sizeof(*gnutar));
	if (gnutar == NULL) {
		archive_set_error(&a->archive, ENOMEM, "Can't allocate gnutar data");
		return (ARCHIVE_FATAL);
	}
	a->format_data = gnutar;
	a->format_name = "gnutar";
	a->format_options = archive_write_gnutar_options;
	a->format_write_header = archive_write_gnutar_header;
	a->format_write_data = archive_write_gnutar_data;
	a->format_close = archive_write_gnutar_close;
	a->format_free = archive_write_gnutar_free;
	a->format_finish_entry = archive_write_gnutar_finish_entry;
	a->archive.archive_format = ARCHIVE_FORMAT_TAR_GNUTAR;
	a->archive.archive_format_name = "GNU tar";
	return (ARCHIVE_OK);
}
int
archive_read_support_filter_lrzip(struct archive *_a)
{
	struct archive_read *a = (struct archive_read *)_a;
	struct archive_read_filter_bidder *reader;

	archive_check_magic(_a, ARCHIVE_READ_MAGIC,
	    ARCHIVE_STATE_NEW, "archive_read_support_filter_lrzip");

	if (__archive_read_get_bidder(a, &reader) != ARCHIVE_OK)
		return (ARCHIVE_FATAL);

	reader->data = NULL;
	reader->name = "lrzip";
	reader->bid = lrzip_bidder_bid;
	reader->init = lrzip_bidder_init;
	reader->options = NULL;
	reader->free = lrzip_reader_free;
	/* This filter always uses an external program. */
	archive_set_error(_a, ARCHIVE_ERRNO_MISC,
	    "Using external lrzip program for lrzip decompression");
	return (ARCHIVE_WARN);
}
static int
rpm_bidder_init(struct archive_read_filter *self)
{
	struct rpm   *rpm;

	self->code = ARCHIVE_FILTER_RPM;
	self->name = "rpm";
	self->read = rpm_filter_read;
	self->skip = NULL; /* not supported */
	self->close = rpm_filter_close;

	rpm = (struct rpm *)calloc(sizeof(*rpm), 1);
	if (rpm == NULL) {
		archive_set_error(&self->archive->archive, ENOMEM,
		    "Can't allocate data for rpm");
		return (ARCHIVE_FATAL);
	}

	self->data = rpm;
	rpm->state = ST_LEAD;

	return (ARCHIVE_OK);
}
Esempio n. 23
0
/*
 * Write data to the filter stream.
 */
int
__archive_write_program_write(struct archive_write_filter *f,
    struct archive_write_program_data *data, const void *buff, size_t length)
{
	ssize_t ret;
	const char *buf;

	if (data->child == 0)
		return (ARCHIVE_OK);

	buf = buff;
	while (length > 0) {
		ret = child_write(f, data, buf, length);
		if (ret == -1 || ret == 0) {
			archive_set_error(f->archive, EIO,
			    "Can't write to filter");
			return (ARCHIVE_FATAL);
		}
		length -= ret;
		buf += ret;
	}
	return (ARCHIVE_OK);
}
int
archive_read_support_compression_gzip(struct archive *_a)
{
	struct archive_read *a = (struct archive_read *)_a;
	struct archive_read_filter_bidder *bidder = __archive_read_get_bidder(a);

	if (bidder == NULL)
		return (ARCHIVE_FATAL);

	bidder->data = NULL;
	bidder->bid = gzip_bidder_bid;
	bidder->init = gzip_bidder_init;
	bidder->options = NULL;
	bidder->free = NULL; /* No data, so no cleanup necessary. */
	/* Signal the extent of gzip support with the return value here. */
#if HAVE_ZLIB_H
	return (ARCHIVE_OK);
#else
	archive_set_error(_a, ARCHIVE_ERRNO_MISC,
	    "Using external gunzip program");
	return (ARCHIVE_WARN);
#endif
}
static int
archive_write_zip_options(struct archive_write *a, const char *key,
    const char *value)
{
	struct zip *zip = a->format_data;

	if (strcmp(key, "compression") == 0) {
		if (strcmp(value, "deflate") == 0) {
#ifdef HAVE_ZLIB_H
			zip->compression = COMPRESSION_DEFLATE;
#else
			archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
			    "deflate compression not supported");
			return ARCHIVE_WARN;
#endif
		} else if (strcmp(value, "store") == 0)
			zip->compression = COMPRESSION_STORE;
		else
			return (ARCHIVE_WARN);
		return (ARCHIVE_OK);
	}
	return (ARCHIVE_WARN);
}
Esempio n. 26
0
static int
file_open(struct archive *a, void *client_data)
{
	struct write_fd_data *mine;
	struct stat st;

	mine = (struct write_fd_data *)client_data;

	if (fstat(mine->fd, &st) != 0) {
		archive_set_error(a, errno, "Couldn't stat fd %d", mine->fd);
		return (ARCHIVE_FATAL);
	}

	/*
	 * If this is a regular file, don't add it to itself.
	 */
	if (S_ISREG(st.st_mode))
		archive_write_set_skip_file(a, st.st_dev, st.st_ino);

	/*
	 * If client hasn't explicitly set the last block handling,
	 * then set it here.
	 */
	if (archive_write_get_bytes_in_last_block(a) < 0) {
		/* If the output is a block or character device, fifo,
		 * or stdout, pad the last block, otherwise leave it
		 * unpadded. */
		if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) ||
		    S_ISFIFO(st.st_mode) || (mine->fd == 1))
			/* Last block will be fully padded. */
			archive_write_set_bytes_in_last_block(a, 0);
		else
			archive_write_set_bytes_in_last_block(a, 1);
	}

	return (ARCHIVE_OK);
}
static int
ar_parse_gnu_filename_table(struct archive_read *a)
{
	struct ar *ar;
	char *p;
	size_t size;

	ar = (struct ar*)(a->format->data);
	size = ar->strtab_size;

	for (p = ar->strtab; p < ar->strtab + size - 1; ++p) {
		if (*p == '/') {
			*p++ = '\0';
			if (*p != '\n')
				goto bad_string_table;
			*p = '\0';
		}
	}
	/*
	 * GNU ar always pads the table to an even size.
	 * The pad character is either '\n' or '`'.
	 */
	if (p != ar->strtab + size && *p != '\n' && *p != '`')
		goto bad_string_table;

	/* Enforce zero termination. */
	ar->strtab[size - 1] = '\0';

	return (ARCHIVE_OK);

bad_string_table:
	archive_set_error(&a->archive, EINVAL,
	    "Invalid string table");
	free(ar->strtab);
	ar->strtab = NULL;
	return (ARCHIVE_FATAL);
}
/*
 * Generic initialization.
 */
static int
archive_write_set_format_ar(struct archive_write *a)
{
	struct ar_w *ar;

	/* If someone else was already registered, unregister them. */
	if (a->format_free != NULL)
		(a->format_free)(a);

	ar = (struct ar_w *)calloc(1, sizeof(*ar));
	if (ar == NULL) {
		archive_set_error(&a->archive, ENOMEM, "Can't allocate ar data");
		return (ARCHIVE_FATAL);
	}
	a->format_data = ar;

	a->format_name = "ar";
	a->format_write_header = archive_write_ar_header;
	a->format_write_data = archive_write_ar_data;
	a->format_close = archive_write_ar_close;
	a->format_free = archive_write_ar_free;
	a->format_finish_entry = archive_write_ar_finish_entry;
	return (ARCHIVE_OK);
}
Esempio n. 29
0
/*
 * Convenience function to perform all exclusion tests.
 *
 * Returns 1 if archive entry is excluded.
 * Returns 0 if archive entry is not excluded.
 * Returns <0 if something error happened.
 */
int
archive_match_excluded(struct archive *_a, struct archive_entry *entry)
{
	struct archive_match *a;
	int r;

	archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
	    ARCHIVE_STATE_NEW, "archive_match_excluded_ae");

	a = (struct archive_match *)_a;
	if (entry == NULL) {
		archive_set_error(&(a->archive), EINVAL, "entry is NULL");
		return (ARCHIVE_FAILED);
	}

	r = 0;
	if (a->setflag & PATTERN_IS_SET) {
#if defined(_WIN32) && !defined(__CYGWIN__)
		r = path_excluded(a, 0, archive_entry_pathname_w(entry));
#else
		r = path_excluded(a, 1, archive_entry_pathname(entry));
#endif
		if (r != 0)
			return (r);
	}

	if (a->setflag & TIME_IS_SET) {
		r = time_excluded(a, entry);
		if (r != 0)
			return (r);
	}

	if (a->setflag & ID_IS_SET)
		r = owner_excluded(a, entry);
	return (r);
}
Esempio n. 30
0
static la_ssize_t libarchive_read_cb( libarchive_t* p_arc, void* p_obj,
  const void** pp_dst )
{
    VLC_UNUSED( p_arc );

    libarchive_callback_t* p_cb = (libarchive_callback_t*)p_obj;

    stream_t*  p_source = p_cb->p_source;
    private_sys_t* p_sys = p_cb->p_sys;

    ssize_t i_ret = vlc_stream_Read( p_source, &p_sys->buffer,
      sizeof( p_sys->buffer ) );

    if( i_ret < 0 )
    {
        archive_set_error( p_sys->p_archive, ARCHIVE_FATAL,
          "libarchive_read_cb failed = %zd", i_ret );

        return ARCHIVE_FATAL;
    }

    *pp_dst = &p_sys->buffer;
    return i_ret;
}