/*
 * An alternate 'shar' that uses uudecode instead of 'sed' to encode
 * file contents and can therefore be used to archive binary files.
 * In addition, this variant also attempts to restore ownership, file modes,
 * and other extended file information.
 */
int
archive_write_set_format_shar_dump(struct archive *_a)
{
	struct archive_write *a = (struct archive_write *)_a;
	struct shar *shar;

	archive_write_set_format_shar(&a->archive);
	shar = (struct shar *)a->format_data;
	shar->dump = 1;
	a->format_write_data = archive_write_shar_data_uuencode;
	a->archive.archive_format = ARCHIVE_FORMAT_SHAR_DUMP;
	a->archive.archive_format_name = "shar dump";
	return (ARCHIVE_OK);
}
Beispiel #2
0
/*
 * Initialize archive structure and create a shar archive.
 */
static struct archive *
shar_create(void)
{
	struct archive *a;

	if ((a = archive_write_new()) == NULL)
		errx(EXIT_FAILURE, "%s", archive_error_string(a));

	if (b_opt)
		archive_write_set_format_shar_dump(a);
	else
		archive_write_set_format_shar(a);
	archive_write_set_compression_none(a);

	if (archive_write_open_filename(a, o_arg) != ARCHIVE_OK)
		errx(EX_CANTCREAT, "%s", archive_error_string(a));

	return (a);
}
/* ArchiveWriter::__construct {{{
 *
*/
ZEND_METHOD(ArchiveWriter, __construct)
{
	archive_file_t *arch = NULL;
	int resource_id;
	zval *this = getThis();
	const char *error_string = NULL;
	char *filename;
	long error_num, filename_len, result, format=0, compression=0;
	zend_error_handling error_handling;

	zend_replace_error_handling(EH_THROW, ce_ArchiveException, &error_handling TSRMLS_CC);

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", &filename, &filename_len, &format, &compression) == FAILURE) {
		zend_restore_error_handling(&error_handling TSRMLS_CC);
		return;
	}

#if PHP_API_VERSION < 20100412
	if (PG(safe_mode) && (!php_checkuid(filename, NULL, CHECKUID_CHECK_FILE_AND_DIR))) {
		zend_restore_error_handling(&error_handling TSRMLS_CC);
		return;
	}
#endif

	if (php_check_open_basedir(filename TSRMLS_CC)) {
		zend_restore_error_handling(&error_handling TSRMLS_CC);
		return;
	}

	arch = (archive_file_t *) emalloc(sizeof(archive_file_t));

	arch->stream = NULL;

	ALLOC_HASHTABLE(arch->entries);
	zend_hash_init(arch->entries, 10, NULL, _archive_entries_hash_dtor, 0);

	arch->mode = PHP_ARCHIVE_WRITE_MODE;
	arch->buf = emalloc(PHP_ARCHIVE_BUF_LEN + 1);
	arch->filename = estrndup(filename, filename_len);
	arch->arch = archive_write_new();

	switch (compression) {
		case PHP_ARCHIVE_COMPRESSION_GZIP:
			if (archive_write_add_filter_gzip(arch->arch) != ARCHIVE_OK) {
				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Gzip compression is not supported in this build");
				zend_restore_error_handling(&error_handling TSRMLS_CC);
				return;
			}
			break;

		case PHP_ARCHIVE_COMPRESSION_BZIP2:
			if (archive_write_add_filter_bzip2(arch->arch) != ARCHIVE_OK) {
				php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bzip2 compression is not supported in this build");
				zend_restore_error_handling(&error_handling TSRMLS_CC);
				return;
			}
			break;
		case 0: /* default value */
		case PHP_ARCHIVE_COMPRESSION_NONE:
			/* always supported */
			break;
		default:
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported compression type %ld", compression);
			zend_restore_error_handling(&error_handling TSRMLS_CC);
			return;
			break;
	}

	switch (format) {
		case 0: /* default value */
		case PHP_ARCHIVE_FORMAT_TAR:
		case PHP_ARCHIVE_FORMAT_PAX_RESTRICTED:
			archive_write_set_format_pax_restricted(arch->arch);
			break;
		case PHP_ARCHIVE_FORMAT_PAX:
			archive_write_set_format_pax(arch->arch);
			break;
		case PHP_ARCHIVE_FORMAT_CPIO:
			archive_write_set_format_cpio(arch->arch);
			break;
		case PHP_ARCHIVE_FORMAT_SHAR:
			archive_write_set_format_shar(arch->arch);
			break;
		case PHP_ARCHIVE_FORMAT_USTAR:
			archive_write_set_format_ustar(arch->arch);
			break;
		default:
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported archive format: %ld", format);
			zend_restore_error_handling(&error_handling TSRMLS_CC);
			return;
			break;
	}

	archive_write_set_bytes_per_block(arch->arch, DEFAULT_BYTES_PER_BLOCK);
	result = archive_write_open(arch->arch, arch, _archive_open_clbk, _archive_write_clbk, _archive_close_clbk);
	/* do not pad the last block */
	archive_write_set_bytes_in_last_block(arch->arch, 1);

	if (result) {
		error_num = archive_errno(arch->arch);
		error_string = archive_error_string(arch->arch);
		efree(arch->filename);
		efree(arch->buf);
		efree(arch);
		if (error_num && error_string) {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to open file %s for writing: error #%ld, %s", filename, error_num, error_string);
		}
		else {
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to open file %s for writing: unknown error %ld", filename, result);
		}
		zend_restore_error_handling(&error_handling TSRMLS_CC);
		return;
	}

	resource_id = zend_list_insert(arch,le_archive);
	add_property_resource(this, "fd", resource_id);

	zend_restore_error_handling(&error_handling TSRMLS_CC);
	return;
}
Beispiel #4
0
const gchar* archive_create(const char* archive_name, GSList* files,
			COMPRESS_METHOD method, ARCHIVE_FORMAT format) {
	struct archive* arch;
	struct archive_entry* entry;
	char* buf = NULL;
	ssize_t len;
	int fd;
	struct stat st;
	struct file_info* file;
	gchar* filename = NULL;
	gchar* msg = NULL;

#ifndef _TEST
	gint num = 0;
	gint total = g_slist_length (files);
#endif

	g_return_val_if_fail(files != NULL, "No files for archiving");

	debug_print("File: %s\n", archive_name);
	arch = archive_write_new();
	switch (method) {
		case ZIP:
			if (archive_write_set_compression_gzip(arch) != ARCHIVE_OK)
				return archive_error_string(arch);
			break;
		case BZIP2:
			if (archive_write_set_compression_bzip2(arch) != ARCHIVE_OK)
				return archive_error_string(arch);
			break;
#if NEW_ARCHIVE_API
		case COMPRESS:
			if (archive_write_set_compression_compress(arch) != ARCHIVE_OK)
    			        return archive_error_string(arch);
			break;
#endif
		case NO_COMPRESS:
			if (archive_write_set_compression_none(arch) != ARCHIVE_OK)
				return archive_error_string(arch);
			break;
	}
	switch (format) {
		case TAR:
			if (archive_write_set_format_ustar(arch) != ARCHIVE_OK)
				return archive_error_string(arch);
			break;
		case SHAR:
			if (archive_write_set_format_shar(arch) != ARCHIVE_OK)
				return archive_error_string(arch);
			break;
		case PAX:
			if (archive_write_set_format_pax(arch) != ARCHIVE_OK)
				return archive_error_string(arch);
			break;
		case CPIO:
			if (archive_write_set_format_cpio(arch) != ARCHIVE_OK)
				return archive_error_string(arch);
			break;
		case NO_FORMAT:
			return "Missing archive format";
	}
	if (archive_write_open_file(arch, archive_name) != ARCHIVE_OK)
		return archive_error_string(arch);

	while (files && ! stop_action) {
#ifndef _TEST
		set_progress_print_all(num++, total, 30);
#endif
		file = (struct file_info *) files->data;
		if (!file)
			continue;
		filename = get_full_path(file);
		/* libarchive will crash if instructed to add archive to it self */
		if (g_utf8_collate(archive_name, filename) == 0) {
			buf = NULL;
			buf = g_strdup_printf(
						"%s: Not dumping to %s", archive_name, filename);
			g_warning("%s\n", buf);
#ifndef _TEST
			debug_print("%s\n", buf);
#endif
			g_free(buf);
		}
		else {
#ifndef _TEST
			debug_print("Adding: %s\n", filename);
			msg = g_strdup_printf("%s", filename);
			set_progress_file_label(msg);
			g_free(msg);
#endif
			entry = archive_entry_new();
			lstat(filename, &st);
			if ((fd = open(filename, O_RDONLY)) == -1) {
				perror("open file");
			}
			else {
				archive_entry_copy_stat(entry, &st);
				archive_entry_set_pathname(entry, filename);
				if (S_ISLNK(st.st_mode)) {
					buf = NULL;
					buf = malloc(PATH_MAX + 1);
					if ((len = readlink(filename, buf, PATH_MAX)) < 0)
						perror("error in readlink");
					else
						buf[len] = '\0';
					archive_entry_set_symlink(entry, buf);
					g_free(buf);
					archive_entry_set_size(entry, 0);
					archive_write_header(arch, entry);
				}
				else {
					if (archive_write_header(arch, entry) != ARCHIVE_OK)
						g_warning("%s", archive_error_string(arch));
					buf = NULL;
					buf = malloc(READ_BLOCK_SIZE);
					len = read(fd, buf, READ_BLOCK_SIZE);
					while (len > 0) {
						if (archive_write_data(arch, buf, len) == -1)
							g_warning("%s", archive_error_string(arch));
						memset(buf, 0, READ_BLOCK_SIZE);
						len = read(fd, buf, READ_BLOCK_SIZE);
					}
					g_free(buf);
				}
				close(fd);
				archive_entry_free(entry);
			}
		}
		g_free(filename);
		files = g_slist_next(files);
	}
#ifndef _TEST
	if (stop_action)
		unlink(archive_name);
	stop_action = FALSE;
#endif
	archive_write_close(arch);
	archive_write_finish(arch);
	return NULL;
}