nifi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From phroc...@apache.org
Subject [04/51] [partial] nifi-minifi-cpp git commit: MINIFICPP-72: Add Tar and Zip Support for MergeContent
Date Fri, 20 Oct 2017 17:18:15 GMT
http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_string_sprintf.c
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_string_sprintf.c b/thirdparty/libarchive-3.3.2/libarchive/archive_string_sprintf.c
new file mode 100644
index 0000000..969a560
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_string_sprintf.c
@@ -0,0 +1,192 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_string_sprintf.c 189435 2009-03-06 05:14:55Z kientzle $");
+
+/*
+ * The use of printf()-family functions can be troublesome
+ * for space-constrained applications.  In addition, correctly
+ * implementing this function in terms of vsnprintf() requires
+ * two calls (one to determine the size, another to format the
+ * result), which in turn requires duplicating the argument list
+ * using va_copy, which isn't yet universally available. <sigh>
+ *
+ * So, I've implemented a bare minimum of printf()-like capability
+ * here.  This is only used to format error messages, so doesn't
+ * require any floating-point support or field-width handling.
+ */
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <stdio.h>
+
+#include "archive_string.h"
+#include "archive_private.h"
+
+/*
+ * Utility functions to format signed/unsigned integers and append
+ * them to an archive_string.
+ */
+static void
+append_uint(struct archive_string *as, uintmax_t d, unsigned base)
+{
+	static const char digits[] = "0123456789abcdef";
+	if (d >= base)
+		append_uint(as, d/base, base);
+	archive_strappend_char(as, digits[d % base]);
+}
+
+static void
+append_int(struct archive_string *as, intmax_t d, unsigned base)
+{
+	uintmax_t ud;
+
+	if (d < 0) {
+		archive_strappend_char(as, '-');
+		ud = (d == INTMAX_MIN) ? (uintmax_t)(INTMAX_MAX) + 1 : (uintmax_t)(-d);
+	} else
+		ud = d;
+	append_uint(as, ud, base);
+}
+
+
+void
+archive_string_sprintf(struct archive_string *as, const char *fmt, ...)
+{
+	va_list ap;
+
+	va_start(ap, fmt);
+	archive_string_vsprintf(as, fmt, ap);
+	va_end(ap);
+}
+
+/*
+ * Like 'vsprintf', but ensures the target is big enough, resizing if
+ * necessary.
+ */
+void
+archive_string_vsprintf(struct archive_string *as, const char *fmt,
+    va_list ap)
+{
+	char long_flag;
+	intmax_t s; /* Signed integer temp. */
+	uintmax_t u; /* Unsigned integer temp. */
+	const char *p, *p2;
+	const wchar_t *pw;
+
+	if (archive_string_ensure(as, 64) == NULL)
+		__archive_errx(1, "Out of memory");
+
+	if (fmt == NULL) {
+		as->s[0] = 0;
+		return;
+	}
+
+	for (p = fmt; *p != '\0'; p++) {
+		const char *saved_p = p;
+
+		if (*p != '%') {
+			archive_strappend_char(as, *p);
+			continue;
+		}
+
+		p++;
+
+		long_flag = '\0';
+		switch(*p) {
+		case 'j':
+		case 'l':
+		case 'z':
+			long_flag = *p;
+			p++;
+			break;
+		}
+
+		switch (*p) {
+		case '%':
+			archive_strappend_char(as, '%');
+			break;
+		case 'c':
+			s = va_arg(ap, int);
+			archive_strappend_char(as, (char)s);
+			break;
+		case 'd':
+			switch(long_flag) {
+			case 'j': s = va_arg(ap, intmax_t); break;
+			case 'l': s = va_arg(ap, long); break;
+			case 'z': s = va_arg(ap, ssize_t); break;
+			default:  s = va_arg(ap, int); break;
+			}
+		        append_int(as, s, 10);
+			break;
+		case 's':
+			switch(long_flag) {
+			case 'l':
+				pw = va_arg(ap, wchar_t *);
+				if (pw == NULL)
+					pw = L"(null)";
+				if (archive_string_append_from_wcs(as, pw,
+				    wcslen(pw)) != 0 && errno == ENOMEM)
+					__archive_errx(1, "Out of memory");
+				break;
+			default:
+				p2 = va_arg(ap, char *);
+				if (p2 == NULL)
+					p2 = "(null)";
+				archive_strcat(as, p2);
+				break;
+			}
+			break;
+		case 'S':
+			pw = va_arg(ap, wchar_t *);
+			if (pw == NULL)
+				pw = L"(null)";
+			if (archive_string_append_from_wcs(as, pw,
+			    wcslen(pw)) != 0 && errno == ENOMEM)
+				__archive_errx(1, "Out of memory");
+			break;
+		case 'o': case 'u': case 'x': case 'X':
+			/* Common handling for unsigned integer formats. */
+			switch(long_flag) {
+			case 'j': u = va_arg(ap, uintmax_t); break;
+			case 'l': u = va_arg(ap, unsigned long); break;
+			case 'z': u = va_arg(ap, size_t); break;
+			default:  u = va_arg(ap, unsigned int); break;
+			}
+			/* Format it in the correct base. */
+			switch (*p) {
+			case 'o': append_uint(as, u, 8); break;
+			case 'u': append_uint(as, u, 10); break;
+			default: append_uint(as, u, 16); break;
+			}
+			break;
+		default:
+			/* Rewind and print the initial '%' literally. */
+			p = saved_p;
+			archive_strappend_char(as, *p);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_util.3
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_util.3 b/thirdparty/libarchive-3.3.2/libarchive/archive_util.3
new file mode 100644
index 0000000..99ab842
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_util.3
@@ -0,0 +1,224 @@
+.\" Copyright (c) 2003-2007 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 2, 2012
+.Dt ARCHIVE_UTIL 3
+.Os
+.Sh NAME
+.Nm archive_clear_error ,
+.Nm archive_compression ,
+.Nm archive_compression_name ,
+.Nm archive_copy_error ,
+.Nm archive_errno ,
+.Nm archive_error_string ,
+.Nm archive_file_count ,
+.Nm archive_filter_code ,
+.Nm archive_filter_count ,
+.Nm archive_filter_name ,
+.Nm archive_format ,
+.Nm archive_format_name ,
+.Nm archive_position ,
+.Nm archive_set_error
+.Nd libarchive utility functions
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
+.Sh SYNOPSIS
+.In archive.h
+.Ft void
+.Fn archive_clear_error "struct archive *"
+.Ft int
+.Fn archive_compression "struct archive *"
+.Ft const char *
+.Fn archive_compression_name "struct archive *"
+.Ft void
+.Fn archive_copy_error "struct archive *" "struct archive *"
+.Ft int
+.Fn archive_errno "struct archive *"
+.Ft const char *
+.Fn archive_error_string "struct archive *"
+.Ft int
+.Fn archive_file_count "struct archive *"
+.Ft int
+.Fn archive_filter_code "struct archive *" "int"
+.Ft int
+.Fn archive_filter_count "struct archive *" "int"
+.Ft const char *
+.Fn archive_filter_name "struct archive *" "int"
+.Ft int
+.Fn archive_format "struct archive *"
+.Ft const char *
+.Fn archive_format_name "struct archive *"
+.Ft int64_t
+.Fn archive_position "struct archive *" "int"
+.Ft void
+.Fo archive_set_error
+.Fa "struct archive *"
+.Fa "int error_code"
+.Fa "const char *fmt"
+.Fa "..."
+.Fc
+.Sh DESCRIPTION
+These functions provide access to various information about the
+.Tn struct archive
+object used in the
+.Xr libarchive 3
+library.
+.Bl -tag -compact -width indent
+.It Fn archive_clear_error
+Clears any error information left over from a previous call.
+Not generally used in client code.
+.It Fn archive_compression
+Synonym for
+.Fn archive_filter_code(a, 0) .
+.It Fn archive_compression_name
+Synonym for
+.Fn archive_filter_name(a, 0) .
+.It Fn archive_copy_error
+Copies error information from one archive to another.
+.It Fn archive_errno
+Returns a numeric error code (see
+.Xr errno 2 )
+indicating the reason for the most recent error return.
+Note that this can not be reliably used to detect whether an
+error has occurred.
+It should be used only after another libarchive function
+has returned an error status.
+.It Fn archive_error_string
+Returns a textual error message suitable for display.
+The error message here is usually more specific than that
+obtained from passing the result of
+.Fn archive_errno
+to
+.Xr strerror 3 .
+.It Fn archive_file_count
+Returns a count of the number of files processed by this archive object.
+The count is incremented by calls to
+.Xr archive_write_header 3
+or
+.Xr archive_read_next_header 3 .
+.It Fn archive_filter_code
+Returns a numeric code identifying the indicated filter.
+See
+.Fn archive_filter_count
+for details of the numbering.
+.It Fn archive_filter_count
+Returns the number of filters in the current pipeline.
+For read archive handles, these filters are added automatically
+by the automatic format detection.
+For write archive handles, these filters are added by calls to the various
+.Fn archive_write_add_filter_XXX
+functions.
+Filters in the resulting pipeline are numbered so that filter 0
+is the filter closest to the format handler.
+As a convenience, functions that expect a filter number will
+accept -1 as a synonym for the highest-numbered filter.
+.Pp
+For example, when reading a uuencoded gzipped tar archive, there
+are three filters:
+filter 0 is the gunzip filter,
+filter 1 is the uudecode filter,
+and filter 2 is the pseudo-filter that wraps the archive read functions.
+In this case, requesting
+.Fn archive_position(a, -1)
+would be a synonym for
+.Fn archive_position(a, 2)
+which would return the number of bytes currently read from the archive, while
+.Fn archive_position(a, 1)
+would return the number of bytes after uudecoding, and
+.Fn archive_position(a, 0)
+would return the number of bytes after decompression.
+.It Fn archive_filter_name
+Returns a textual name identifying the indicated filter.
+See
+.Fn archive_filter_count
+for details of the numbering.
+.It Fn archive_format
+Returns a numeric code indicating the format of the current
+archive entry.
+This value is set by a successful call to
+.Fn archive_read_next_header .
+Note that it is common for this value to change from
+entry to entry.
+For example, a tar archive might have several entries that
+utilize GNU tar extensions and several entries that do not.
+These entries will have different format codes.
+.It Fn archive_format_name
+A textual description of the format of the current entry.
+.It Fn archive_position
+Returns the number of bytes read from or written to the indicated filter.
+In particular,
+.Fn archive_position(a, 0)
+returns the number of bytes read or written by the format handler, while
+.Fn archive_position(a, -1)
+returns the number of bytes read or written to the archive.
+See
+.Fn archive_filter_count
+for details of the numbering here.
+.It Fn archive_set_error
+Sets the numeric error code and error description that will be returned
+by
+.Fn archive_errno
+and
+.Fn archive_error_string .
+This function should be used within I/O callbacks to set system-specific
+error codes and error descriptions.
+This function accepts a printf-like format string and arguments.
+However, you should be careful to use only the following printf
+format specifiers:
+.Dq %c ,
+.Dq %d ,
+.Dq %jd ,
+.Dq %jo ,
+.Dq %ju ,
+.Dq %jx ,
+.Dq %ld ,
+.Dq %lo ,
+.Dq %lu ,
+.Dq %lx ,
+.Dq %o ,
+.Dq %u ,
+.Dq %s ,
+.Dq %x ,
+.Dq %% .
+Field-width specifiers and other printf features are
+not uniformly supported and should not be used.
+.El
+.Sh SEE ALSO
+.Xr archive_read 3 ,
+.Xr archive_write 3 ,
+.Xr libarchive 3 ,
+.Xr printf 3
+.Sh HISTORY
+The
+.Nm libarchive
+library first appeared in
+.Fx 5.3 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm libarchive
+library was written by
+.An Tim Kientzle Aq kientzle@acm.org .

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_util.c
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_util.c b/thirdparty/libarchive-3.3.2/libarchive/archive_util.c
new file mode 100644
index 0000000..bac9ba1
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_util.c
@@ -0,0 +1,585 @@
+/*-
+ * Copyright (c) 2009-2012,2014 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:14Z kientzle $");
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#if defined(HAVE_WINCRYPT_H) && !defined(__CYGWIN__)
+#include <wincrypt.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+#ifdef HAVE_LZMA_H
+#include <lzma.h>
+#endif
+#ifdef HAVE_BZLIB_H
+#include <bzlib.h>
+#endif
+#ifdef HAVE_LZ4_H
+#include <lz4.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_random_private.h"
+#include "archive_string.h"
+
+#ifndef O_CLOEXEC
+#define O_CLOEXEC	0
+#endif
+
+static int archive_utility_string_sort_helper(char **, unsigned int);
+
+/* Generic initialization of 'struct archive' objects. */
+int
+__archive_clean(struct archive *a)
+{
+	archive_string_conversion_free(a);
+	return (ARCHIVE_OK);
+}
+
+int
+archive_version_number(void)
+{
+	return (ARCHIVE_VERSION_NUMBER);
+}
+
+const char *
+archive_version_string(void)
+{
+	return (ARCHIVE_VERSION_STRING);
+}
+
+int
+archive_errno(struct archive *a)
+{
+	return (a->archive_error_number);
+}
+
+const char *
+archive_error_string(struct archive *a)
+{
+
+	if (a->error != NULL  &&  *a->error != '\0')
+		return (a->error);
+	else
+		return (NULL);
+}
+
+int
+archive_file_count(struct archive *a)
+{
+	return (a->file_count);
+}
+
+int
+archive_format(struct archive *a)
+{
+	return (a->archive_format);
+}
+
+const char *
+archive_format_name(struct archive *a)
+{
+	return (a->archive_format_name);
+}
+
+
+int
+archive_compression(struct archive *a)
+{
+	return archive_filter_code(a, 0);
+}
+
+const char *
+archive_compression_name(struct archive *a)
+{
+	return archive_filter_name(a, 0);
+}
+
+
+/*
+ * Return a count of the number of compressed bytes processed.
+ */
+int64_t
+archive_position_compressed(struct archive *a)
+{
+	return archive_filter_bytes(a, -1);
+}
+
+/*
+ * Return a count of the number of uncompressed bytes processed.
+ */
+int64_t
+archive_position_uncompressed(struct archive *a)
+{
+	return archive_filter_bytes(a, 0);
+}
+
+void
+archive_clear_error(struct archive *a)
+{
+	archive_string_empty(&a->error_string);
+	a->error = NULL;
+	a->archive_error_number = 0;
+}
+
+void
+archive_set_error(struct archive *a, int error_number, const char *fmt, ...)
+{
+	va_list ap;
+
+	a->archive_error_number = error_number;
+	if (fmt == NULL) {
+		a->error = NULL;
+		return;
+	}
+
+	archive_string_empty(&(a->error_string));
+	va_start(ap, fmt);
+	archive_string_vsprintf(&(a->error_string), fmt, ap);
+	va_end(ap);
+	a->error = a->error_string.s;
+}
+
+void
+archive_copy_error(struct archive *dest, struct archive *src)
+{
+	dest->archive_error_number = src->archive_error_number;
+
+	archive_string_copy(&dest->error_string, &src->error_string);
+	dest->error = dest->error_string.s;
+}
+
+void
+__archive_errx(int retvalue, const char *msg)
+{
+	static const char msg1[] = "Fatal Internal Error in libarchive: ";
+	size_t s;
+
+	s = write(2, msg1, strlen(msg1));
+	(void)s; /* UNUSED */
+	s = write(2, msg, strlen(msg));
+	(void)s; /* UNUSED */
+	s = write(2, "\n", 1);
+	(void)s; /* UNUSED */
+	exit(retvalue);
+}
+
+/*
+ * Create a temporary file
+ */
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+/*
+ * Do not use Windows tmpfile() function.
+ * It will make a temporary file under the root directory
+ * and it'll cause permission error if a user who is
+ * non-Administrator creates temporary files.
+ * Also Windows version of mktemp family including _mktemp_s
+ * are not secure.
+ */
+int
+__archive_mktemp(const char *tmpdir)
+{
+	static const wchar_t prefix[] = L"libarchive_";
+	static const wchar_t suffix[] = L"XXXXXXXXXX";
+	static const wchar_t num[] = {
+		L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
+		L'8', L'9', L'A', L'B', L'C', L'D', L'E', L'F',
+		L'G', L'H', L'I', L'J', L'K', L'L', L'M', L'N',
+		L'O', L'P', L'Q', L'R', L'S', L'T', L'U', L'V',
+		L'W', L'X', L'Y', L'Z', L'a', L'b', L'c', L'd',
+		L'e', L'f', L'g', L'h', L'i', L'j', L'k', L'l',
+		L'm', L'n', L'o', L'p', L'q', L'r', L's', L't',
+		L'u', L'v', L'w', L'x', L'y', L'z'
+	};
+	HCRYPTPROV hProv;
+	struct archive_wstring temp_name;
+	wchar_t *ws;
+	DWORD attr;
+	wchar_t *xp, *ep;
+	int fd;
+
+	hProv = (HCRYPTPROV)NULL;
+	fd = -1;
+	ws = NULL;
+	archive_string_init(&temp_name);
+
+	/* Get a temporary directory. */
+	if (tmpdir == NULL) {
+		size_t l;
+		wchar_t *tmp;
+
+		l = GetTempPathW(0, NULL);
+		if (l == 0) {
+			la_dosmaperr(GetLastError());
+			goto exit_tmpfile;
+		}
+		tmp = malloc(l*sizeof(wchar_t));
+		if (tmp == NULL) {
+			errno = ENOMEM;
+			goto exit_tmpfile;
+		}
+		GetTempPathW((DWORD)l, tmp);
+		archive_wstrcpy(&temp_name, tmp);
+		free(tmp);
+	} else {
+		if (archive_wstring_append_from_mbs(&temp_name, tmpdir,
+		    strlen(tmpdir)) < 0)
+			goto exit_tmpfile;
+		if (temp_name.s[temp_name.length-1] != L'/')
+			archive_wstrappend_wchar(&temp_name, L'/');
+	}
+
+	/* Check if temp_name is a directory. */
+	attr = GetFileAttributesW(temp_name.s);
+	if (attr == (DWORD)-1) {
+		if (GetLastError() != ERROR_FILE_NOT_FOUND) {
+			la_dosmaperr(GetLastError());
+			goto exit_tmpfile;
+		}
+		ws = __la_win_permissive_name_w(temp_name.s);
+		if (ws == NULL) {
+			errno = EINVAL;
+			goto exit_tmpfile;
+		}
+		attr = GetFileAttributesW(ws);
+		if (attr == (DWORD)-1) {
+			la_dosmaperr(GetLastError());
+			goto exit_tmpfile;
+		}
+	}
+	if (!(attr & FILE_ATTRIBUTE_DIRECTORY)) {
+		errno = ENOTDIR;
+		goto exit_tmpfile;
+	}
+
+	/*
+	 * Create a temporary file.
+	 */
+	archive_wstrcat(&temp_name, prefix);
+	archive_wstrcat(&temp_name, suffix);
+	ep = temp_name.s + archive_strlen(&temp_name);
+	xp = ep - wcslen(suffix);
+
+	if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
+		CRYPT_VERIFYCONTEXT)) {
+		la_dosmaperr(GetLastError());
+		goto exit_tmpfile;
+	}
+
+	for (;;) {
+		wchar_t *p;
+		HANDLE h;
+
+		/* Generate a random file name through CryptGenRandom(). */
+		p = xp;
+		if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t),
+		    (BYTE*)p)) {
+			la_dosmaperr(GetLastError());
+			goto exit_tmpfile;
+		}
+		for (; p < ep; p++)
+			*p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
+
+		free(ws);
+		ws = __la_win_permissive_name_w(temp_name.s);
+		if (ws == NULL) {
+			errno = EINVAL;
+			goto exit_tmpfile;
+		}
+		/* Specifies FILE_FLAG_DELETE_ON_CLOSE flag is to
+		 * delete this temporary file immediately when this
+		 * file closed. */
+		h = CreateFileW(ws,
+		    GENERIC_READ | GENERIC_WRITE | DELETE,
+		    0,/* Not share */
+		    NULL,
+		    CREATE_NEW,/* Create a new file only */
+		    FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
+		    NULL);
+		if (h == INVALID_HANDLE_VALUE) {
+			/* The same file already exists. retry with
+			 * a new filename. */
+			if (GetLastError() == ERROR_FILE_EXISTS)
+				continue;
+			/* Otherwise, fail creation temporary file. */
+			la_dosmaperr(GetLastError());
+			goto exit_tmpfile;
+		}
+		fd = _open_osfhandle((intptr_t)h, _O_BINARY | _O_RDWR);
+		if (fd == -1) {
+			CloseHandle(h);
+			goto exit_tmpfile;
+		} else
+			break;/* success! */
+	}
+exit_tmpfile:
+	if (hProv != (HCRYPTPROV)NULL)
+		CryptReleaseContext(hProv, 0);
+	free(ws);
+	archive_wstring_free(&temp_name);
+	return (fd);
+}
+
+#else
+
+static int
+get_tempdir(struct archive_string *temppath)
+{
+	const char *tmp;
+
+	tmp = getenv("TMPDIR");
+	if (tmp == NULL)
+#ifdef _PATH_TMP
+		tmp = _PATH_TMP;
+#else
+                tmp = "/tmp";
+#endif
+	archive_strcpy(temppath, tmp);
+	if (temppath->s[temppath->length-1] != '/')
+		archive_strappend_char(temppath, '/');
+	return (ARCHIVE_OK);
+}
+
+#if defined(HAVE_MKSTEMP)
+
+/*
+ * We can use mkstemp().
+ */
+
+int
+__archive_mktemp(const char *tmpdir)
+{
+	struct archive_string temp_name;
+	int fd = -1;
+
+	archive_string_init(&temp_name);
+	if (tmpdir == NULL) {
+		if (get_tempdir(&temp_name) != ARCHIVE_OK)
+			goto exit_tmpfile;
+	} else {
+		archive_strcpy(&temp_name, tmpdir);
+		if (temp_name.s[temp_name.length-1] != '/')
+			archive_strappend_char(&temp_name, '/');
+	}
+	archive_strcat(&temp_name, "libarchive_XXXXXX");
+	fd = mkstemp(temp_name.s);
+	if (fd < 0)
+		goto exit_tmpfile;
+	__archive_ensure_cloexec_flag(fd);
+	unlink(temp_name.s);
+exit_tmpfile:
+	archive_string_free(&temp_name);
+	return (fd);
+}
+
+#else
+
+/*
+ * We use a private routine.
+ */
+
+int
+__archive_mktemp(const char *tmpdir)
+{
+        static const char num[] = {
+		'0', '1', '2', '3', '4', '5', '6', '7',
+		'8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
+		'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+		'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V',
+		'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+		'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
+		'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+		'u', 'v', 'w', 'x', 'y', 'z'
+        };
+	struct archive_string temp_name;
+	struct stat st;
+	int fd;
+	char *tp, *ep;
+
+	fd = -1;
+	archive_string_init(&temp_name);
+	if (tmpdir == NULL) {
+		if (get_tempdir(&temp_name) != ARCHIVE_OK)
+			goto exit_tmpfile;
+	} else
+		archive_strcpy(&temp_name, tmpdir);
+	if (temp_name.s[temp_name.length-1] == '/') {
+		temp_name.s[temp_name.length-1] = '\0';
+		temp_name.length --;
+	}
+	if (stat(temp_name.s, &st) < 0)
+		goto exit_tmpfile;
+	if (!S_ISDIR(st.st_mode)) {
+		errno = ENOTDIR;
+		goto exit_tmpfile;
+	}
+	archive_strcat(&temp_name, "/libarchive_");
+	tp = temp_name.s + archive_strlen(&temp_name);
+	archive_strcat(&temp_name, "XXXXXXXXXX");
+	ep = temp_name.s + archive_strlen(&temp_name);
+
+	do {
+		char *p;
+
+		p = tp;
+		archive_random(p, ep - p);
+		while (p < ep) {
+			int d = *((unsigned char *)p) % sizeof(num);
+			*p++ = num[d];
+		}
+		fd = open(temp_name.s, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC,
+			  0600);
+	} while (fd < 0 && errno == EEXIST);
+	if (fd < 0)
+		goto exit_tmpfile;
+	__archive_ensure_cloexec_flag(fd);
+	unlink(temp_name.s);
+exit_tmpfile:
+	archive_string_free(&temp_name);
+	return (fd);
+}
+
+#endif /* HAVE_MKSTEMP */
+#endif /* !_WIN32 || __CYGWIN__ */
+
+/*
+ * Set FD_CLOEXEC flag to a file descriptor if it is not set.
+ * We have to set the flag if the platform does not provide O_CLOEXEC
+ * or F_DUPFD_CLOEXEC flags.
+ *
+ * Note: This function is absolutely called after creating a new file
+ * descriptor even if the platform seemingly provides O_CLOEXEC or
+ * F_DUPFD_CLOEXEC macros because it is possible that the platform
+ * merely declares those macros, especially Linux 2.6.18 - 2.6.24 do it.
+ */
+void
+__archive_ensure_cloexec_flag(int fd)
+{
+#if defined(_WIN32) && !defined(__CYGWIN__)
+	(void)fd; /* UNUSED */
+#else
+	int flags;
+
+	if (fd >= 0) {
+		flags = fcntl(fd, F_GETFD);
+		if (flags != -1 && (flags & FD_CLOEXEC) == 0)
+			fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
+	}
+#endif
+}
+
+/*
+ * Utility function to sort a group of strings using quicksort.
+ */
+static int
+archive_utility_string_sort_helper(char **strings, unsigned int n)
+{
+	unsigned int i, lesser_count, greater_count;
+	char **lesser, **greater, **tmp, *pivot;
+	int retval1, retval2;
+
+	/* A list of 0 or 1 elements is already sorted */
+	if (n <= 1)
+		return (ARCHIVE_OK);
+
+	lesser_count = greater_count = 0;
+	lesser = greater = NULL;
+	pivot = strings[0];
+	for (i = 1; i < n; i++)
+	{
+		if (strcmp(strings[i], pivot) < 0)
+		{
+			lesser_count++;
+			tmp = (char **)realloc(lesser,
+				lesser_count * sizeof(char *));
+			if (!tmp) {
+				free(greater);
+				free(lesser);
+				return (ARCHIVE_FATAL);
+			}
+			lesser = tmp;
+			lesser[lesser_count - 1] = strings[i];
+		}
+		else
+		{
+			greater_count++;
+			tmp = (char **)realloc(greater,
+				greater_count * sizeof(char *));
+			if (!tmp) {
+				free(greater);
+				free(lesser);
+				return (ARCHIVE_FATAL);
+			}
+			greater = tmp;
+			greater[greater_count - 1] = strings[i];
+		}
+	}
+
+	/* quicksort(lesser) */
+	retval1 = archive_utility_string_sort_helper(lesser, lesser_count);
+	for (i = 0; i < lesser_count; i++)
+		strings[i] = lesser[i];
+	free(lesser);
+
+	/* pivot */
+	strings[lesser_count] = pivot;
+
+	/* quicksort(greater) */
+	retval2 = archive_utility_string_sort_helper(greater, greater_count);
+	for (i = 0; i < greater_count; i++)
+		strings[lesser_count + 1 + i] = greater[i];
+	free(greater);
+
+	return (retval1 < retval2) ? retval1 : retval2;
+}
+
+int
+archive_utility_string_sort(char **strings)
+{
+	  unsigned int size = 0;
+	  while (strings[size] != NULL)
+		size++;
+	  return archive_utility_string_sort_helper(strings, size);
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_version_details.c
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_version_details.c b/thirdparty/libarchive-3.3.2/libarchive/archive_version_details.c
new file mode 100644
index 0000000..813f0f3
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_version_details.c
@@ -0,0 +1,133 @@
+/*-
+ * Copyright (c) 2009-2012,2014 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:14Z kientzle $");
+
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+#ifdef HAVE_LZMA_H
+#include <lzma.h>
+#endif
+#ifdef HAVE_BZLIB_H
+#include <bzlib.h>
+#endif
+#ifdef HAVE_LZ4_H
+#include <lz4.h>
+#endif
+
+#include "archive.h"
+#include "archive_private.h"
+#include "archive_string.h"
+
+const char *
+archive_version_details(void)
+{
+	static struct archive_string str;
+	static int init = 0;
+	const char *zlib = archive_zlib_version();
+	const char *liblzma = archive_liblzma_version();
+	const char *bzlib = archive_bzlib_version();
+	const char *liblz4 = archive_liblz4_version();
+
+	if (!init) {
+		archive_string_init(&str);
+
+		archive_strcat(&str, ARCHIVE_VERSION_STRING);
+		if (zlib != NULL) {
+			archive_strcat(&str, " zlib/");
+			archive_strcat(&str, zlib);
+		}
+		if (liblzma) {
+			archive_strcat(&str, " liblzma/");
+			archive_strcat(&str, liblzma);
+		}
+		if (bzlib) {
+			const char *p = bzlib;
+			const char *sep = strchr(p, ',');
+			if (sep == NULL)
+				sep = p + strlen(p);
+			archive_strcat(&str, " bz2lib/");
+			archive_strncat(&str, p, sep - p);
+		}
+		if (liblz4) {
+			archive_strcat(&str, " liblz4/");
+			archive_strcat(&str, liblz4);
+		}
+	}
+	return str.s;
+}
+
+const char *
+archive_zlib_version(void)
+{
+#ifdef HAVE_ZLIB_H
+	return ZLIB_VERSION;
+#else
+	return NULL;
+#endif
+}
+
+const char *
+archive_liblzma_version(void)
+{
+#ifdef HAVE_LZMA_H
+	return LZMA_VERSION_STRING;
+#else
+	return NULL;
+#endif
+}
+
+const char *
+archive_bzlib_version(void)
+{
+#ifdef HAVE_BZLIB_H
+	return BZ2_bzlibVersion();
+#else
+	return NULL;
+#endif
+}
+
+const char *
+archive_liblz4_version(void)
+{
+#if defined(HAVE_LZ4_H) && defined(HAVE_LIBLZ4)
+#define str(s) #s
+#define NUMBER(x) str(x)
+	return NUMBER(LZ4_VERSION_MAJOR) "." NUMBER(LZ4_VERSION_MINOR) "." NUMBER(LZ4_VERSION_RELEASE);
+#undef NUMBER
+#undef str
+#else
+	return NULL;
+#endif
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_virtual.c
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_virtual.c b/thirdparty/libarchive-3.3.2/libarchive/archive_virtual.c
new file mode 100644
index 0000000..de2595a
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_virtual.c
@@ -0,0 +1,162 @@
+/*-
+ * Copyright (c) 2003-2007 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "archive_platform.h"
+__FBSDID("$FreeBSD: head/lib/libarchive/archive_virtual.c 201098 2009-12-28 02:58:14Z kientzle $");
+
+#include "archive.h"
+#include "archive_entry.h"
+#include "archive_private.h"
+
+int
+archive_filter_code(struct archive *a, int n)
+{
+	return ((a->vtable->archive_filter_code)(a, n));
+}
+
+int
+archive_filter_count(struct archive *a)
+{
+	return ((a->vtable->archive_filter_count)(a));
+}
+
+const char *
+archive_filter_name(struct archive *a, int n)
+{
+	return ((a->vtable->archive_filter_name)(a, n));
+}
+
+int64_t
+archive_filter_bytes(struct archive *a, int n)
+{
+	return ((a->vtable->archive_filter_bytes)(a, n));
+}
+
+int
+archive_free(struct archive *a)
+{
+	if (a == NULL)
+		return (ARCHIVE_OK);
+	return ((a->vtable->archive_free)(a));
+}
+
+int
+archive_write_close(struct archive *a)
+{
+	return ((a->vtable->archive_close)(a));
+}
+
+int
+archive_read_close(struct archive *a)
+{
+	return ((a->vtable->archive_close)(a));
+}
+
+int
+archive_write_fail(struct archive *a)
+{
+	a->state = ARCHIVE_STATE_FATAL;
+	return a->state;
+}
+
+int
+archive_write_free(struct archive *a)
+{
+	return archive_free(a);
+}
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* For backwards compatibility; will be removed with libarchive 4.0. */
+int
+archive_write_finish(struct archive *a)
+{
+	return archive_write_free(a);
+}
+#endif
+
+int
+archive_read_free(struct archive *a)
+{
+	return archive_free(a);
+}
+
+#if ARCHIVE_VERSION_NUMBER < 4000000
+/* For backwards compatibility; will be removed with libarchive 4.0. */
+int
+archive_read_finish(struct archive *a)
+{
+	return archive_read_free(a);
+}
+#endif
+
+int
+archive_write_header(struct archive *a, struct archive_entry *entry)
+{
+	++a->file_count;
+	return ((a->vtable->archive_write_header)(a, entry));
+}
+
+int
+archive_write_finish_entry(struct archive *a)
+{
+	return ((a->vtable->archive_write_finish_entry)(a));
+}
+
+ssize_t
+archive_write_data(struct archive *a, const void *buff, size_t s)
+{
+	return ((a->vtable->archive_write_data)(a, buff, s));
+}
+
+ssize_t
+archive_write_data_block(struct archive *a, const void *buff, size_t s, int64_t o)
+{
+	if (a->vtable->archive_write_data_block == NULL) {
+		archive_set_error(a, ARCHIVE_ERRNO_MISC,
+		    "archive_write_data_block not supported");
+		a->state = ARCHIVE_STATE_FATAL;
+		return (ARCHIVE_FATAL);
+	}
+	return ((a->vtable->archive_write_data_block)(a, buff, s, o));
+}
+
+int
+archive_read_next_header(struct archive *a, struct archive_entry **entry)
+{
+	return ((a->vtable->archive_read_next_header)(a, entry));
+}
+
+int
+archive_read_next_header2(struct archive *a, struct archive_entry *entry)
+{
+	return ((a->vtable->archive_read_next_header2)(a, entry));
+}
+
+int
+archive_read_data_block(struct archive *a,
+    const void **buff, size_t *s, int64_t *o)
+{
+	return ((a->vtable->archive_read_data_block)(a, buff, s, o));
+}

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_windows.c
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_windows.c b/thirdparty/libarchive-3.3.2/libarchive/archive_windows.c
new file mode 100644
index 0000000..6ff8749
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_windows.c
@@ -0,0 +1,908 @@
+/*-
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2007 Kees Zeelenberg
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * A set of compatibility glue for building libarchive on Windows platforms.
+ *
+ * Originally created as "libarchive-nonposix.c" by Kees Zeelenberg
+ * for the GnuWin32 project, trimmed significantly by Tim Kientzle.
+ *
+ * Much of the original file was unnecessary for libarchive, because
+ * many of the features it emulated were not strictly necessary for
+ * libarchive.  I hope for this to shrink further as libarchive
+ * internals are gradually reworked to sit more naturally on both
+ * POSIX and Windows.  Any ideas for this are greatly appreciated.
+ *
+ * The biggest remaining issue is the dev/ino emulation; libarchive
+ * has a couple of public APIs that rely on dev/ino uniquely
+ * identifying a file.  This doesn't match well with Windows.  I'm
+ * considering alternative APIs.
+ */
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+#include "archive_platform.h"
+#include "archive_private.h"
+#include "archive_entry.h"
+#include <ctype.h>
+#include <errno.h>
+#include <stddef.h>
+#ifdef HAVE_SYS_UTIME_H
+#include <sys/utime.h>
+#endif
+#include <sys/stat.h>
+#include <locale.h>
+#include <process.h>
+#include <stdlib.h>
+#include <wchar.h>
+#include <windows.h>
+#include <share.h>
+
+#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
+
+#if defined(__LA_LSEEK_NEEDED)
+static BOOL SetFilePointerEx_perso(HANDLE hFile,
+				   LARGE_INTEGER liDistanceToMove,
+				   PLARGE_INTEGER lpNewFilePointer,
+				   DWORD dwMoveMethod)
+{
+	LARGE_INTEGER li;
+	li.QuadPart = liDistanceToMove.QuadPart;
+	li.LowPart = SetFilePointer(
+		hFile, li.LowPart, &li.HighPart, dwMoveMethod);
+	if(lpNewFilePointer) {
+		lpNewFilePointer->QuadPart = li.QuadPart;
+	}
+	return li.LowPart != -1 || GetLastError() == NO_ERROR;
+}
+#endif
+
+struct ustat {
+	int64_t		st_atime;
+	uint32_t	st_atime_nsec;
+	int64_t		st_ctime;
+	uint32_t	st_ctime_nsec;
+	int64_t		st_mtime;
+	uint32_t	st_mtime_nsec;
+	gid_t		st_gid;
+	/* 64bits ino */
+	int64_t		st_ino;
+	mode_t		st_mode;
+	uint32_t	st_nlink;
+	uint64_t	st_size;
+	uid_t		st_uid;
+	dev_t		st_dev;
+	dev_t		st_rdev;
+};
+
+/* Transform 64-bits ino into 32-bits by hashing.
+ * You do not forget that really unique number size is 64-bits.
+ */
+#define INOSIZE (8*sizeof(ino_t)) /* 32 */
+static __inline ino_t
+getino(struct ustat *ub)
+{
+	ULARGE_INTEGER ino64;
+	ino64.QuadPart = ub->st_ino;
+	/* I don't know this hashing is correct way */
+	return ((ino_t)(ino64.LowPart ^ (ino64.LowPart >> INOSIZE)));
+}
+
+/*
+ * Prepend "\\?\" to the path name and convert it to unicode to permit
+ * an extended-length path for a maximum total path length of 32767
+ * characters.
+ * see also http://msdn.microsoft.com/en-us/library/aa365247.aspx
+ */
+wchar_t *
+__la_win_permissive_name(const char *name)
+{
+	wchar_t *wn;
+	wchar_t *ws;
+	size_t ll;
+
+	ll = strlen(name);
+	wn = malloc((ll + 1) * sizeof(wchar_t));
+	if (wn == NULL)
+		return (NULL);
+	ll = mbstowcs(wn, name, ll);
+	if (ll == (size_t)-1) {
+		free(wn);
+		return (NULL);
+	}
+	wn[ll] = L'\0';
+	ws = __la_win_permissive_name_w(wn);
+	free(wn);
+	return (ws);
+}
+
+wchar_t *
+__la_win_permissive_name_w(const wchar_t *wname)
+{
+	wchar_t *wn, *wnp;
+	wchar_t *ws, *wsp;
+	DWORD l, len, slen;
+	int unc;
+
+	/* Get a full-pathname. */
+	l = GetFullPathNameW(wname, 0, NULL, NULL);
+	if (l == 0)
+		return (NULL);
+	/* NOTE: GetFullPathNameW has a bug that if the length of the file
+	 * name is just 1 then it returns incomplete buffer size. Thus, we
+	 * have to add three to the size to allocate a sufficient buffer
+	 * size for the full-pathname of the file name. */
+	l += 3;
+	wnp = malloc(l * sizeof(wchar_t));
+	if (wnp == NULL)
+		return (NULL);
+	len = GetFullPathNameW(wname, l, wnp, NULL);
+	wn = wnp;
+
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+	    wnp[2] == L'?' && wnp[3] == L'\\')
+		/* We have already a permissive name. */
+		return (wn);
+
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
+		wnp[2] == L'.' && wnp[3] == L'\\') {
+		/* This is a device name */
+		if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
+		     (wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
+		    wnp[5] == L':' && wnp[6] == L'\\')
+			wnp[2] = L'?';/* Not device name. */
+		return (wn);
+	}
+
+	unc = 0;
+	if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
+		wchar_t *p = &wnp[2];
+
+		/* Skip server-name letters. */
+		while (*p != L'\\' && *p != L'\0')
+			++p;
+		if (*p == L'\\') {
+			wchar_t *rp = ++p;
+			/* Skip share-name letters. */
+			while (*p != L'\\' && *p != L'\0')
+				++p;
+			if (*p == L'\\' && p != rp) {
+				/* Now, match patterns such as
+				 * "\\server-name\share-name\" */
+				wnp += 2;
+				len -= 2;
+				unc = 1;
+			}
+		}
+	}
+
+	slen = 4 + (unc * 4) + len + 1;
+	ws = wsp = malloc(slen * sizeof(wchar_t));
+	if (ws == NULL) {
+		free(wn);
+		return (NULL);
+	}
+	/* prepend "\\?\" */
+	wcsncpy(wsp, L"\\\\?\\", 4);
+	wsp += 4;
+	slen -= 4;
+	if (unc) {
+		/* append "UNC\" ---> "\\?\UNC\" */
+		wcsncpy(wsp, L"UNC\\", 4);
+		wsp += 4;
+		slen -= 4;
+	}
+	wcsncpy(wsp, wnp, slen);
+	wsp[slen - 1] = L'\0'; /* Ensure null termination. */
+	free(wn);
+	return (ws);
+}
+
+/*
+ * Create a file handle.
+ * This can exceed MAX_PATH limitation.
+ */
+static HANDLE
+la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
+    LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
+    DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
+{
+	wchar_t *wpath;
+	HANDLE handle;
+
+	handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
+	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+	    hTemplateFile);
+	if (handle != INVALID_HANDLE_VALUE)
+		return (handle);
+	if (GetLastError() != ERROR_PATH_NOT_FOUND)
+		return (handle);
+	wpath = __la_win_permissive_name(path);
+	if (wpath == NULL)
+		return (handle);
+	handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
+	    lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
+	    hTemplateFile);
+	free(wpath);
+	return (handle);
+}
+
+#if defined(__LA_LSEEK_NEEDED)
+__int64
+__la_lseek(int fd, __int64 offset, int whence)
+{
+	LARGE_INTEGER distance;
+	LARGE_INTEGER newpointer;
+	HANDLE handle;
+
+	if (fd < 0) {
+		errno = EBADF;
+		return (-1);
+	}
+	handle = (HANDLE)_get_osfhandle(fd);
+	if (GetFileType(handle) != FILE_TYPE_DISK) {
+		errno = EBADF;
+		return (-1);
+	}
+	distance.QuadPart = offset;
+	if (!SetFilePointerEx_perso(handle, distance, &newpointer, whence)) {
+		DWORD lasterr;
+
+		lasterr = GetLastError();
+		if (lasterr == ERROR_BROKEN_PIPE)
+			return (0);
+		if (lasterr == ERROR_ACCESS_DENIED)
+			errno = EBADF;
+		else
+			la_dosmaperr(lasterr);
+		return (-1);
+	}
+	return (newpointer.QuadPart);
+}
+#endif
+
+/* This can exceed MAX_PATH limitation. */
+int
+__la_open(const char *path, int flags, ...)
+{
+	va_list ap;
+	wchar_t *ws;
+	int r, pmode;
+	DWORD attr;
+
+	va_start(ap, flags);
+	pmode = va_arg(ap, int);
+	va_end(ap);
+	ws = NULL;
+	if ((flags & ~O_BINARY) == O_RDONLY) {
+		/*
+		 * When we open a directory, _open function returns
+		 * "Permission denied" error.
+		 */
+		attr = GetFileAttributesA(path);
+		if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND) {
+			ws = __la_win_permissive_name(path);
+			if (ws == NULL) {
+				errno = EINVAL;
+				return (-1);
+			}
+			attr = GetFileAttributesW(ws);
+		}
+		if (attr == (DWORD)-1) {
+			la_dosmaperr(GetLastError());
+			free(ws);
+			return (-1);
+		}
+		if (attr & FILE_ATTRIBUTE_DIRECTORY) {
+			HANDLE handle;
+
+			if (ws != NULL)
+				handle = CreateFileW(ws, 0, 0, NULL,
+				    OPEN_EXISTING,
+				    FILE_FLAG_BACKUP_SEMANTICS |
+				    FILE_ATTRIBUTE_READONLY,
+					NULL);
+			else
+				handle = CreateFileA(path, 0, 0, NULL,
+				    OPEN_EXISTING,
+				    FILE_FLAG_BACKUP_SEMANTICS |
+				    FILE_ATTRIBUTE_READONLY,
+					NULL);
+			free(ws);
+			if (handle == INVALID_HANDLE_VALUE) {
+				la_dosmaperr(GetLastError());
+				return (-1);
+			}
+			r = _open_osfhandle((intptr_t)handle, _O_RDONLY);
+			return (r);
+		}
+	}
+	if (ws == NULL) {
+#if defined(__BORLANDC__)
+		/* Borland has no mode argument.
+		   TODO: Fix mode of new file.  */
+		r = _open(path, flags);
+#else
+		r = _open(path, flags, pmode);
+#endif
+		if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
+			/* Simulate other POSIX system action to pass our test suite. */
+			attr = GetFileAttributesA(path);
+			if (attr == (DWORD)-1)
+				la_dosmaperr(GetLastError());
+			else if (attr & FILE_ATTRIBUTE_DIRECTORY)
+				errno = EISDIR;
+			else
+				errno = EACCES;
+			return (-1);
+		}
+		if (r >= 0 || errno != ENOENT)
+			return (r);
+		ws = __la_win_permissive_name(path);
+		if (ws == NULL) {
+			errno = EINVAL;
+			return (-1);
+		}
+	}
+	r = _wopen(ws, flags, pmode);
+	if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
+		/* Simulate other POSIX system action to pass our test suite. */
+		attr = GetFileAttributesW(ws);
+		if (attr == (DWORD)-1)
+			la_dosmaperr(GetLastError());
+		else if (attr & FILE_ATTRIBUTE_DIRECTORY)
+			errno = EISDIR;
+		else
+			errno = EACCES;
+	}
+	free(ws);
+	return (r);
+}
+
+ssize_t
+__la_read(int fd, void *buf, size_t nbytes)
+{
+	HANDLE handle;
+	DWORD bytes_read, lasterr;
+	int r;
+
+#ifdef _WIN64
+	if (nbytes > UINT32_MAX)
+		nbytes = UINT32_MAX;
+#endif
+	if (fd < 0) {
+		errno = EBADF;
+		return (-1);
+	}
+	/* Do not pass 0 to third parameter of ReadFile(), read bytes.
+	 * This will not return to application side. */
+	if (nbytes == 0)
+		return (0);
+	handle = (HANDLE)_get_osfhandle(fd);
+	r = ReadFile(handle, buf, (uint32_t)nbytes,
+	    &bytes_read, NULL);
+	if (r == 0) {
+		lasterr = GetLastError();
+		if (lasterr == ERROR_NO_DATA) {
+			errno = EAGAIN;
+			return (-1);
+		}
+		if (lasterr == ERROR_BROKEN_PIPE)
+			return (0);
+		if (lasterr == ERROR_ACCESS_DENIED)
+			errno = EBADF;
+		else
+			la_dosmaperr(lasterr);
+		return (-1);
+	}
+	return ((ssize_t)bytes_read);
+}
+
+/* Convert Windows FILETIME to UTC */
+__inline static void
+fileTimeToUTC(const FILETIME *filetime, time_t *t, long *ns)
+{
+	ULARGE_INTEGER utc;
+
+	utc.HighPart = filetime->dwHighDateTime;
+	utc.LowPart  = filetime->dwLowDateTime;
+	if (utc.QuadPart >= EPOC_TIME) {
+		utc.QuadPart -= EPOC_TIME;
+		*t = (time_t)(utc.QuadPart / 10000000);	/* milli seconds base */
+		*ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */
+	} else {
+		*t = 0;
+		*ns = 0;
+	}
+}
+
+/* Stat by handle
+ * Windows' stat() does not accept the path added "\\?\" especially "?"
+ * character.
+ * It means we cannot access the long name path longer than MAX_PATH.
+ * So I've implemented simular Windows' stat() to access the long name path.
+ * And I've added some feature.
+ * 1. set st_ino by nFileIndexHigh and nFileIndexLow of
+ *    BY_HANDLE_FILE_INFORMATION.
+ * 2. set st_nlink by nNumberOfLinks of BY_HANDLE_FILE_INFORMATION.
+ * 3. set st_dev by dwVolumeSerialNumber by BY_HANDLE_FILE_INFORMATION.
+ */
+static int
+__hstat(HANDLE handle, struct ustat *st)
+{
+	BY_HANDLE_FILE_INFORMATION info;
+	ULARGE_INTEGER ino64;
+	DWORD ftype;
+	mode_t mode;
+	time_t t;
+	long ns;
+
+	switch (ftype = GetFileType(handle)) {
+	case FILE_TYPE_UNKNOWN:
+		errno = EBADF;
+		return (-1);
+	case FILE_TYPE_CHAR:
+	case FILE_TYPE_PIPE:
+		if (ftype == FILE_TYPE_CHAR) {
+			st->st_mode = S_IFCHR;
+			st->st_size = 0;
+		} else {
+			DWORD avail;
+
+			st->st_mode = S_IFIFO;
+			if (PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL))
+				st->st_size = avail;
+			else
+				st->st_size = 0;
+		}
+		st->st_atime = 0;
+		st->st_atime_nsec = 0;
+		st->st_mtime = 0;
+		st->st_mtime_nsec = 0;
+		st->st_ctime = 0;
+		st->st_ctime_nsec = 0;
+		st->st_ino = 0;
+		st->st_nlink = 1;
+		st->st_uid = 0;
+		st->st_gid = 0;
+		st->st_rdev = 0;
+		st->st_dev = 0;
+		return (0);
+	case FILE_TYPE_DISK:
+		break;
+	default:
+		/* This ftype is undocumented type. */
+		la_dosmaperr(GetLastError());
+		return (-1);
+	}
+
+	ZeroMemory(&info, sizeof(info));
+	if (!GetFileInformationByHandle (handle, &info)) {
+		la_dosmaperr(GetLastError());
+		return (-1);
+	}
+
+	mode = S_IRUSR | S_IRGRP | S_IROTH;
+	if ((info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
+		mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+	if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+		mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+	else
+		mode |= S_IFREG;
+	st->st_mode = mode;
+
+	fileTimeToUTC(&info.ftLastAccessTime, &t, &ns);
+	st->st_atime = t;
+	st->st_atime_nsec = ns;
+	fileTimeToUTC(&info.ftLastWriteTime, &t, &ns);
+	st->st_mtime = t;
+	st->st_mtime_nsec = ns;
+	fileTimeToUTC(&info.ftCreationTime, &t, &ns);
+	st->st_ctime = t;
+	st->st_ctime_nsec = ns;
+	st->st_size =
+	    ((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
+		+ (int64_t)(info.nFileSizeLow);
+#ifdef SIMULATE_WIN_STAT
+	st->st_ino = 0;
+	st->st_nlink = 1;
+	st->st_dev = 0;
+#else
+	/* Getting FileIndex as i-node. We should remove a sequence which
+	 * is high-16-bits of nFileIndexHigh. */
+	ino64.HighPart = info.nFileIndexHigh & 0x0000FFFFUL;
+	ino64.LowPart  = info.nFileIndexLow;
+	st->st_ino = ino64.QuadPart;
+	st->st_nlink = info.nNumberOfLinks;
+	if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
+		++st->st_nlink;/* Add parent directory. */
+	st->st_dev = info.dwVolumeSerialNumber;
+#endif
+	st->st_uid = 0;
+	st->st_gid = 0;
+	st->st_rdev = 0;
+	return (0);
+}
+
+static void
+copy_stat(struct stat *st, struct ustat *us)
+{
+	st->st_atime = us->st_atime;
+	st->st_ctime = us->st_ctime;
+	st->st_mtime = us->st_mtime;
+	st->st_gid = us->st_gid;
+	st->st_ino = getino(us);
+	st->st_mode = us->st_mode;
+	st->st_nlink = us->st_nlink;
+	st->st_size = (off_t)us->st_size;
+	st->st_uid = us->st_uid;
+	st->st_dev = us->st_dev;
+	st->st_rdev = us->st_rdev;
+}
+
+/*
+ * TODO: Remove a use of __la_fstat and __la_stat.
+ * We should use GetFileInformationByHandle in place
+ * where We still use the *stat functions.
+ */
+int
+__la_fstat(int fd, struct stat *st)
+{
+	struct ustat u;
+	int ret;
+
+	if (fd < 0) {
+		errno = EBADF;
+		return (-1);
+	}
+	ret = __hstat((HANDLE)_get_osfhandle(fd), &u);
+	if (ret >= 0) {
+		copy_stat(st, &u);
+		if (u.st_mode & (S_IFCHR | S_IFIFO)) {
+			st->st_dev = fd;
+			st->st_rdev = fd;
+		}
+	}
+	return (ret);
+}
+
+/* This can exceed MAX_PATH limitation. */
+int
+__la_stat(const char *path, struct stat *st)
+{
+	HANDLE handle;
+	struct ustat u;
+	int ret;
+
+	handle = la_CreateFile(path, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING,
+		FILE_FLAG_BACKUP_SEMANTICS,
+		NULL);
+	if (handle == INVALID_HANDLE_VALUE) {
+		la_dosmaperr(GetLastError());
+		return (-1);
+	}
+	ret = __hstat(handle, &u);
+	CloseHandle(handle);
+	if (ret >= 0) {
+		char *p;
+
+		copy_stat(st, &u);
+		p = strrchr(path, '.');
+		if (p != NULL && strlen(p) == 4) {
+			char exttype[4];
+
+			++ p;
+			exttype[0] = toupper(*p++);
+			exttype[1] = toupper(*p++);
+			exttype[2] = toupper(*p++);
+			exttype[3] = '\0';
+			if (!strcmp(exttype, "EXE") || !strcmp(exttype, "CMD") ||
+				!strcmp(exttype, "BAT") || !strcmp(exttype, "COM"))
+				st->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
+		}
+	}
+	return (ret);
+}
+
+/*
+ * This waitpid is limited implementation.
+ */
+pid_t
+__la_waitpid(HANDLE child, int *status, int option)
+{
+	DWORD cs;
+
+	(void)option;/* UNUSED */
+	do {
+		if (GetExitCodeProcess(child, &cs) == 0) {
+			CloseHandle(child);
+			la_dosmaperr(GetLastError());
+			*status = 0;
+			return (-1);
+		}
+	} while (cs == STILL_ACTIVE);
+
+	*status = (int)(cs & 0xff);
+	return (0);
+}
+
+ssize_t
+__la_write(int fd, const void *buf, size_t nbytes)
+{
+	DWORD bytes_written;
+
+#ifdef _WIN64
+	if (nbytes > UINT32_MAX)
+		nbytes = UINT32_MAX;
+#endif
+	if (fd < 0) {
+		errno = EBADF;
+		return (-1);
+	}
+	if (!WriteFile((HANDLE)_get_osfhandle(fd), buf, (uint32_t)nbytes,
+	    &bytes_written, NULL)) {
+		DWORD lasterr;
+
+		lasterr = GetLastError();
+		if (lasterr == ERROR_ACCESS_DENIED)
+			errno = EBADF;
+		else
+			la_dosmaperr(lasterr);
+		return (-1);
+	}
+	return (bytes_written);
+}
+
+/*
+ * Replace the Windows path separator '\' with '/'.
+ */
+static int
+replace_pathseparator(struct archive_wstring *ws, const wchar_t *wp)
+{
+	wchar_t *w;
+	size_t path_length;
+
+	if (wp == NULL)
+		return(0);
+	if (wcschr(wp, L'\\') == NULL)
+		return(0);
+	path_length = wcslen(wp);
+	if (archive_wstring_ensure(ws, path_length) == NULL)
+		return(-1);
+	archive_wstrncpy(ws, wp, path_length);
+	for (w = ws->s; *w; w++) {
+		if (*w == L'\\')
+			*w = L'/';
+	}
+	return(1);
+}
+
+static int
+fix_pathseparator(struct archive_entry *entry)
+{
+	struct archive_wstring ws;
+	const wchar_t *wp;
+	int ret = ARCHIVE_OK;
+
+	archive_string_init(&ws);
+	wp = archive_entry_pathname_w(entry);
+	switch (replace_pathseparator(&ws, wp)) {
+	case 0: /* Not replaced. */
+		break;
+	case 1: /* Replaced. */
+		archive_entry_copy_pathname_w(entry, ws.s);
+		break;
+	default:
+		ret = ARCHIVE_FAILED;
+	}
+	wp = archive_entry_hardlink_w(entry);
+	switch (replace_pathseparator(&ws, wp)) {
+	case 0: /* Not replaced. */
+		break;
+	case 1: /* Replaced. */
+		archive_entry_copy_hardlink_w(entry, ws.s);
+		break;
+	default:
+		ret = ARCHIVE_FAILED;
+	}
+	wp = archive_entry_symlink_w(entry);
+	switch (replace_pathseparator(&ws, wp)) {
+	case 0: /* Not replaced. */
+		break;
+	case 1: /* Replaced. */
+		archive_entry_copy_symlink_w(entry, ws.s);
+		break;
+	default:
+		ret = ARCHIVE_FAILED;
+	}
+	archive_wstring_free(&ws);
+	return(ret);
+}
+
+struct archive_entry *
+__la_win_entry_in_posix_pathseparator(struct archive_entry *entry)
+{
+	struct archive_entry *entry_main;
+	const wchar_t *wp;
+	int has_backslash = 0;
+	int ret;
+
+	wp = archive_entry_pathname_w(entry);
+	if (wp != NULL && wcschr(wp, L'\\') != NULL)
+		has_backslash = 1;
+	if (!has_backslash) {
+		wp = archive_entry_hardlink_w(entry);
+		if (wp != NULL && wcschr(wp, L'\\') != NULL)
+			has_backslash = 1;
+	}
+	if (!has_backslash) {
+		wp = archive_entry_symlink_w(entry);
+		if (wp != NULL && wcschr(wp, L'\\') != NULL)
+			has_backslash = 1;
+	}
+	/*
+	 * If there is no backslash chars, return the original.
+	 */
+	if (!has_backslash)
+		return (entry);
+
+	/* Copy entry so we can modify it as needed. */
+	entry_main = archive_entry_clone(entry);
+	if (entry_main == NULL)
+		return (NULL);
+	/* Replace the Windows path-separator '\' with '/'. */
+	ret = fix_pathseparator(entry_main);
+	if (ret < ARCHIVE_WARN) {
+		archive_entry_free(entry_main);
+		return (NULL);
+	}
+	return (entry_main);
+}
+
+
+/*
+ * The following function was modified from PostgreSQL sources and is
+ * subject to the copyright below.
+ */
+/*-------------------------------------------------------------------------
+ *
+ * win32error.c
+ *	  Map win32 error codes to errno values
+ *
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ *
+ * IDENTIFICATION
+ *	  $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+/*
+PostgreSQL Database Management System
+(formerly known as Postgres, then as Postgres95)
+
+Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+
+Portions Copyright (c) 1994, The Regents of the University of California
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose, without fee, and without a written agreement
+is hereby granted, provided that the above copyright notice and this
+paragraph and the following two paragraphs appear in all copies.
+
+IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
+LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
+DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
+PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+*/
+
+static const struct {
+	DWORD		winerr;
+	int		doserr;
+} doserrors[] =
+{
+	{	ERROR_INVALID_FUNCTION, EINVAL	},
+	{	ERROR_FILE_NOT_FOUND, ENOENT	},
+	{	ERROR_PATH_NOT_FOUND, ENOENT	},
+	{	ERROR_TOO_MANY_OPEN_FILES, EMFILE	},
+	{	ERROR_ACCESS_DENIED, EACCES	},
+	{	ERROR_INVALID_HANDLE, EBADF	},
+	{	ERROR_ARENA_TRASHED, ENOMEM	},
+	{	ERROR_NOT_ENOUGH_MEMORY, ENOMEM	},
+	{	ERROR_INVALID_BLOCK, ENOMEM	},
+	{	ERROR_BAD_ENVIRONMENT, E2BIG	},
+	{	ERROR_BAD_FORMAT, ENOEXEC	},
+	{	ERROR_INVALID_ACCESS, EINVAL	},
+	{	ERROR_INVALID_DATA, EINVAL	},
+	{	ERROR_INVALID_DRIVE, ENOENT	},
+	{	ERROR_CURRENT_DIRECTORY, EACCES	},
+	{	ERROR_NOT_SAME_DEVICE, EXDEV	},
+	{	ERROR_NO_MORE_FILES, ENOENT	},
+	{	ERROR_LOCK_VIOLATION, EACCES	},
+	{	ERROR_SHARING_VIOLATION, EACCES	},
+	{	ERROR_BAD_NETPATH, ENOENT	},
+	{	ERROR_NETWORK_ACCESS_DENIED, EACCES	},
+	{	ERROR_BAD_NET_NAME, ENOENT	},
+	{	ERROR_FILE_EXISTS, EEXIST	},
+	{	ERROR_CANNOT_MAKE, EACCES	},
+	{	ERROR_FAIL_I24, EACCES	},
+	{	ERROR_INVALID_PARAMETER, EINVAL	},
+	{	ERROR_NO_PROC_SLOTS, EAGAIN	},
+	{	ERROR_DRIVE_LOCKED, EACCES	},
+	{	ERROR_BROKEN_PIPE, EPIPE	},
+	{	ERROR_DISK_FULL, ENOSPC	},
+	{	ERROR_INVALID_TARGET_HANDLE, EBADF	},
+	{	ERROR_INVALID_HANDLE, EINVAL	},
+	{	ERROR_WAIT_NO_CHILDREN, ECHILD	},
+	{	ERROR_CHILD_NOT_COMPLETE, ECHILD	},
+	{	ERROR_DIRECT_ACCESS_HANDLE, EBADF	},
+	{	ERROR_NEGATIVE_SEEK, EINVAL	},
+	{	ERROR_SEEK_ON_DEVICE, EACCES	},
+	{	ERROR_DIR_NOT_EMPTY, ENOTEMPTY	},
+	{	ERROR_NOT_LOCKED, EACCES	},
+	{	ERROR_BAD_PATHNAME, ENOENT	},
+	{	ERROR_MAX_THRDS_REACHED, EAGAIN	},
+	{	ERROR_LOCK_FAILED, EACCES	},
+	{	ERROR_ALREADY_EXISTS, EEXIST	},
+	{	ERROR_FILENAME_EXCED_RANGE, ENOENT	},
+	{	ERROR_NESTING_NOT_ALLOWED, EAGAIN	},
+	{	ERROR_NOT_ENOUGH_QUOTA, ENOMEM	}
+};
+
+void
+__la_dosmaperr(unsigned long e)
+{
+	int			i;
+
+	if (e == 0)
+	{
+		errno = 0;
+		return;
+	}
+
+	for (i = 0; i < (int)(sizeof(doserrors)/sizeof(doserrors[0])); i++)
+	{
+		if (doserrors[i].winerr == e)
+		{
+			errno = doserrors[i].doserr;
+			return;
+		}
+	}
+
+	/* fprintf(stderr, "unrecognized win32 error code: %lu", e); */
+	errno = EINVAL;
+	return;
+}
+
+#endif /* _WIN32 && !__CYGWIN__ */

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_windows.h
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_windows.h b/thirdparty/libarchive-3.3.2/libarchive/archive_windows.h
new file mode 100644
index 0000000..e77cd08
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_windows.h
@@ -0,0 +1,318 @@
+/*-
+ * Copyright (c) 2009-2011 Michihiro NAKAJIMA
+ * Copyright (c) 2003-2006 Tim Kientzle
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef __LIBARCHIVE_BUILD
+#error This header is only to be used internally to libarchive.
+#endif
+
+/*
+ * TODO: A lot of stuff in here isn't actually used by libarchive and
+ * can be trimmed out.  Note that this file is used by libarchive and
+ * libarchive_test but nowhere else.  (But note that it gets compiled
+ * with many different Windows environments, including MinGW, Visual
+ * Studio, and Cygwin.  Significant changes should be tested in all three.)
+ */
+
+/*
+ * TODO: Don't use off_t in here.  Use __int64 instead.  Note that
+ * Visual Studio and the Windows SDK define off_t as 32 bits; Win32's
+ * more modern file handling APIs all use __int64 instead of off_t.
+ */
+
+#ifndef LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED
+#define	LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED
+
+/* Start of configuration for native Win32  */
+#ifndef MINGW_HAS_SECURE_API
+#define MINGW_HAS_SECURE_API 1
+#endif
+
+#include <errno.h>
+#define	set_errno(val)	((errno)=val)
+#include <io.h>
+#include <stdlib.h>   //brings in NULL
+#if defined(HAVE_STDINT_H)
+#include <stdint.h>
+#endif
+#include <stdio.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <process.h>
+#include <direct.h>
+#if defined(__MINGW32__) && defined(HAVE_UNISTD_H)
+/* Prevent build error from a type mismatch of ftruncate().
+ * This unistd.h defines it as ftruncate(int, off_t). */
+#include <unistd.h>
+#endif
+#define NOCRYPT
+#include <windows.h>
+//#define	EFTYPE 7
+
+#if defined(__BORLANDC__)
+#pragma warn -8068	/* Constant out of range in comparison. */
+#pragma warn -8072	/* Suspicious pointer arithmetic. */
+#endif
+
+#ifndef NULL
+#ifdef  __cplusplus
+#define	NULL    0
+#else
+#define	NULL    ((void *)0)
+#endif
+#endif
+
+/* Alias the Windows _function to the POSIX equivalent. */
+#define	close		_close
+#define	fcntl(fd, cmd, flg)	/* No operation. */
+#ifndef fileno
+#define	fileno		_fileno
+#endif
+#ifdef fstat
+#undef fstat
+#endif
+#define	fstat		__la_fstat
+#if !defined(__BORLANDC__)
+#ifdef lseek
+#undef lseek
+#endif
+#define	lseek		_lseeki64
+#else
+#define	lseek		__la_lseek
+#define __LA_LSEEK_NEEDED
+#endif
+#define	lstat		__la_stat
+#define	open		__la_open
+#define	read		__la_read
+#if !defined(__BORLANDC__) && !defined(__WATCOMC__)
+#define setmode		_setmode
+#endif
+#ifdef stat
+#undef stat
+#endif
+#define	stat(path,stref)		__la_stat(path,stref)
+#if !defined(__WATCOMC__)
+#if !defined(__BORLANDC__)
+#define	strdup		_strdup
+#endif
+#define	tzset		_tzset
+#if !defined(__BORLANDC__)
+#define	umask		_umask
+#endif
+#endif
+#define	waitpid		__la_waitpid
+#define	write		__la_write
+
+#if !defined(__WATCOMC__)
+
+#ifndef O_RDONLY
+#define	O_RDONLY	_O_RDONLY
+#define	O_WRONLY	_O_WRONLY
+#define	O_TRUNC		_O_TRUNC
+#define	O_CREAT		_O_CREAT
+#define	O_EXCL		_O_EXCL
+#define	O_BINARY	_O_BINARY
+#endif
+
+#ifndef _S_IFIFO
+  #define	_S_IFIFO        0010000   /* pipe */
+#endif
+#ifndef _S_IFCHR
+  #define	_S_IFCHR        0020000   /* character special */
+#endif
+#ifndef _S_IFDIR
+  #define	_S_IFDIR        0040000   /* directory */
+#endif
+#ifndef _S_IFBLK
+  #define	_S_IFBLK        0060000   /* block special */
+#endif
+#ifndef _S_IFLNK
+  #define	_S_IFLNK        0120000   /* symbolic link */
+#endif
+#ifndef _S_IFSOCK
+  #define	_S_IFSOCK       0140000   /* socket */
+#endif
+#ifndef	_S_IFREG
+  #define	_S_IFREG        0100000   /* regular */
+#endif
+#ifndef	_S_IFMT
+  #define	_S_IFMT         0170000   /* file type mask */
+#endif
+
+#ifndef S_IFIFO
+#define	S_IFIFO     _S_IFIFO
+#endif
+//#define	S_IFCHR  _S_IFCHR
+//#define	S_IFDIR  _S_IFDIR
+#ifndef S_IFBLK
+#define	S_IFBLK     _S_IFBLK
+#endif
+#ifndef S_IFLNK
+#define	S_IFLNK     _S_IFLNK
+#endif
+#ifndef S_IFSOCK
+#define	S_IFSOCK    _S_IFSOCK
+#endif
+//#define	S_IFREG  _S_IFREG
+//#define	S_IFMT   _S_IFMT
+
+#ifndef S_ISBLK
+#define	S_ISBLK(m)	(((m) & S_IFMT) == S_IFBLK)	/* block special */
+#define	S_ISFIFO(m)	(((m) & S_IFMT) == S_IFIFO)	/* fifo or socket */
+#define	S_ISCHR(m)	(((m) & S_IFMT) == S_IFCHR)	/* char special */
+#define	S_ISDIR(m)	(((m) & S_IFMT) == S_IFDIR)	/* directory */
+#define	S_ISREG(m)	(((m) & S_IFMT) == S_IFREG)	/* regular file */
+#endif
+#define	S_ISLNK(m)  (((m) & S_IFMT) == S_IFLNK) /* Symbolic link */
+#define	S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK) /* Socket */
+
+#define	_S_ISUID        0004000   /* set user id on execution */
+#define	_S_ISGID        0002000   /* set group id on execution */
+#define	_S_ISVTX        0001000   /* save swapped text even after use */
+
+#define	S_ISUID        _S_ISUID
+#define	S_ISGID        _S_ISGID
+#define	S_ISVTX        _S_ISVTX
+
+#define	_S_IRWXU	     (_S_IREAD | _S_IWRITE | _S_IEXEC)
+#define	_S_IXUSR	     _S_IEXEC  /* read permission, user */
+#define	_S_IWUSR	     _S_IWRITE /* write permission, user */
+#define	_S_IRUSR	     _S_IREAD  /* execute/search permission, user */
+#define	_S_IRWXG        (_S_IRWXU >> 3)
+#define	_S_IXGRP        (_S_IXUSR >> 3) /* read permission, group */
+#define	_S_IWGRP        (_S_IWUSR >> 3) /* write permission, group */
+#define	_S_IRGRP        (_S_IRUSR >> 3) /* execute/search permission, group */
+#define	_S_IRWXO        (_S_IRWXG >> 3)
+#define	_S_IXOTH        (_S_IXGRP >> 3) /* read permission, other */
+#define	_S_IWOTH        (_S_IWGRP >> 3) /* write permission, other */
+#define	_S_IROTH        (_S_IRGRP  >> 3) /* execute/search permission, other */
+
+#ifndef S_IRWXU
+#define	S_IRWXU	     _S_IRWXU
+#define	S_IXUSR	     _S_IXUSR
+#define	S_IWUSR	     _S_IWUSR
+#define	S_IRUSR	     _S_IRUSR
+#endif
+#ifndef S_IRWXG
+#define	S_IRWXG        _S_IRWXG
+#define	S_IXGRP        _S_IXGRP
+#define	S_IWGRP        _S_IWGRP
+#endif
+#ifndef S_IRGRP
+#define	S_IRGRP        _S_IRGRP
+#endif
+#ifndef S_IRWXO
+#define	S_IRWXO        _S_IRWXO
+#define	S_IXOTH        _S_IXOTH
+#define	S_IWOTH        _S_IWOTH
+#define	S_IROTH        _S_IROTH
+#endif
+
+#endif
+
+#define	F_DUPFD	  	0	/* Duplicate file descriptor.  */
+#define	F_GETFD		1	/* Get file descriptor flags.  */
+#define	F_SETFD		2	/* Set file descriptor flags.  */
+#define	F_GETFL		3	/* Get file status flags.  */
+#define	F_SETFL		4	/* Set file status flags.  */
+#define	F_GETOWN		5	/* Get owner (receiver of SIGIO).  */
+#define	F_SETOWN		6	/* Set owner (receiver of SIGIO).  */
+#define	F_GETLK		7	/* Get record locking info.  */
+#define	F_SETLK		8	/* Set record locking info (non-blocking).  */
+#define	F_SETLKW		9	/* Set record locking info (blocking).  */
+
+/* XXX missing */
+#define	F_GETLK64	7	/* Get record locking info.  */
+#define	F_SETLK64	8	/* Set record locking info (non-blocking).  */
+#define	F_SETLKW64	9	/* Set record locking info (blocking).  */
+
+/* File descriptor flags used with F_GETFD and F_SETFD.  */
+#define	FD_CLOEXEC	1	/* Close on exec.  */
+
+//NOT SURE IF O_NONBLOCK is OK here but at least the 0x0004 flag is not used by anything else...
+#define	O_NONBLOCK 0x0004 /* Non-blocking I/O.  */
+//#define	O_NDELAY   O_NONBLOCK
+
+/* Symbolic constants for the access() function */
+#if !defined(F_OK)
+    #define	R_OK    4       /*  Test for read permission    */
+    #define	W_OK    2       /*  Test for write permission   */
+    #define	X_OK    1       /*  Test for execute permission */
+    #define	F_OK    0       /*  Test for existence of file  */
+#endif
+
+
+/* Replacement POSIX function */
+extern int	 __la_fstat(int fd, struct stat *st);
+extern int	 __la_lstat(const char *path, struct stat *st);
+#if defined(__LA_LSEEK_NEEDED)
+extern __int64	 __la_lseek(int fd, __int64 offset, int whence);
+#endif
+extern int	 __la_open(const char *path, int flags, ...);
+extern ssize_t	 __la_read(int fd, void *buf, size_t nbytes);
+extern int	 __la_stat(const char *path, struct stat *st);
+extern pid_t	 __la_waitpid(HANDLE child, int *status, int option);
+extern ssize_t	 __la_write(int fd, const void *buf, size_t nbytes);
+
+#define _stat64i32(path, st)	__la_stat(path, st)
+#define _stat64(path, st)	__la_stat(path, st)
+/* for status returned by la_waitpid */
+#define WIFEXITED(sts)		((sts & 0x100) == 0)
+#define WEXITSTATUS(sts)	(sts & 0x0FF)
+
+extern wchar_t *__la_win_permissive_name(const char *name);
+extern wchar_t *__la_win_permissive_name_w(const wchar_t *wname);
+extern void __la_dosmaperr(unsigned long e);
+#define la_dosmaperr(e) __la_dosmaperr(e)
+extern struct archive_entry *__la_win_entry_in_posix_pathseparator(
+    struct archive_entry *);
+
+#if defined(HAVE_WCRTOMB) && defined(__BORLANDC__)
+typedef int mbstate_t;
+size_t wcrtomb(char *, wchar_t, mbstate_t *);
+#endif
+
+#if defined(_MSC_VER) && _MSC_VER < 1300
+WINBASEAPI BOOL WINAPI GetVolumePathNameW(
+       LPCWSTR lpszFileName,
+       LPWSTR lpszVolumePathName,
+       DWORD cchBufferLength
+       );
+# if _WIN32_WINNT < 0x0500 /* windows.h not providing 0x500 API */
+typedef struct _FILE_ALLOCATED_RANGE_BUFFER {
+       LARGE_INTEGER FileOffset;
+       LARGE_INTEGER Length;
+} FILE_ALLOCATED_RANGE_BUFFER, *PFILE_ALLOCATED_RANGE_BUFFER;
+#  define FSCTL_SET_SPARSE \
+     CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 49, METHOD_BUFFERED, FILE_WRITE_DATA)
+#  define FSCTL_QUERY_ALLOCATED_RANGES \
+     CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 51,  METHOD_NEITHER, FILE_READ_DATA)
+# endif
+#endif
+
+#endif /* LIBARCHIVE_ARCHIVE_WINDOWS_H_INCLUDED */

http://git-wip-us.apache.org/repos/asf/nifi-minifi-cpp/blob/3781b52f/thirdparty/libarchive-3.3.2/libarchive/archive_write.3
----------------------------------------------------------------------
diff --git a/thirdparty/libarchive-3.3.2/libarchive/archive_write.3 b/thirdparty/libarchive-3.3.2/libarchive/archive_write.3
new file mode 100644
index 0000000..376d71d
--- /dev/null
+++ b/thirdparty/libarchive-3.3.2/libarchive/archive_write.3
@@ -0,0 +1,268 @@
+.\" Copyright (c) 2003-2011 Tim Kientzle
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 2, 2012
+.Dt ARCHIVE_WRITE 3
+.Os
+.Sh NAME
+.Nm archive_write
+.Nd functions for creating archives
+.Sh LIBRARY
+Streaming Archive Library (libarchive, -larchive)
+.Sh SYNOPSIS
+.In archive.h
+.Sh DESCRIPTION
+These functions provide a complete API for creating streaming
+archive files.
+The general process is to first create the
+.Tn struct archive
+object, set any desired options, initialize the archive, append entries, then
+close the archive and release all resources.
+.\"
+.Ss Create archive object
+See
+.Xr archive_write_new 3 .
+.Pp
+To write an archive, you must first obtain an initialized
+.Tn struct archive
+object from
+.Fn archive_write_new .
+.\"
+.Ss Enable filters and formats, configure block size and padding
+See
+.Xr archive_write_filter 3 ,
+.Xr archive_write_format 3
+and
+.Xr archive_write_blocksize 3 .
+.Pp
+You can then modify this object for the desired operations with the
+various
+.Fn archive_write_set_XXX
+functions.
+In particular, you will need to invoke appropriate
+.Fn archive_write_add_XXX
+and
+.Fn archive_write_set_XXX
+functions to enable the corresponding compression and format
+support.
+.\"
+.Ss Set options
+See
+.Xr archive_read_set_options 3 .
+.\"
+.Ss Open archive
+See
+.Xr archive_write_open 3 .
+.Pp
+Once you have prepared the
+.Tn struct archive
+object, you call
+.Fn archive_write_open
+to actually open the archive and prepare it for writing.
+There are several variants of this function;
+the most basic expects you to provide pointers to several
+functions that can provide blocks of bytes from the archive.
+There are convenience forms that allow you to
+specify a filename, file descriptor,
+.Ft "FILE *"
+object, or a block of memory from which to write the archive data.
+.\"
+.Ss Produce archive
+See
+.Xr archive_write_header 3
+and
+.Xr archive_write_data 3 .
+.Pp
+Individual archive entries are written in a three-step
+process:
+You first initialize a
+.Tn struct archive_entry
+structure with information about the new entry.
+At a minimum, you should set the pathname of the
+entry and provide a
+.Va struct stat
+with a valid
+.Va st_mode
+field, which specifies the type of object and
+.Va st_size
+field, which specifies the size of the data portion of the object.
+.\"
+.Ss Release resources
+See
+.Xr archive_write_free 3 .
+.Pp
+After all entries have been written, use the
+.Fn archive_write_free
+function to release all resources.
+.\"
+.Sh EXAMPLE
+The following sketch illustrates basic usage of the library.
+In this example,
+the callback functions are simply wrappers around the standard
+.Xr open 2 ,
+.Xr write 2 ,
+and
+.Xr close 2
+system calls.
+.Bd -literal -offset indent
+#ifdef __linux__
+#define	_FILE_OFFSET_BITS 64
+#endif
+#include <sys/stat.h>
+#include <archive.h>
+#include <archive_entry.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+struct mydata {
+  const char *name;
+  int fd;
+};
+
+int
+myopen(struct archive *a, void *client_data)
+{
+  struct mydata *mydata = client_data;
+
+  mydata->fd = open(mydata->name, O_WRONLY | O_CREAT, 0644);
+  if (mydata->fd >= 0)
+    return (ARCHIVE_OK);
+  else
+    return (ARCHIVE_FATAL);
+}
+
+la_ssize_t
+mywrite(struct archive *a, void *client_data, const void *buff, size_t n)
+{
+  struct mydata *mydata = client_data;
+
+  return (write(mydata->fd, buff, n));
+}
+
+int
+myclose(struct archive *a, void *client_data)
+{
+  struct mydata *mydata = client_data;
+
+  if (mydata->fd > 0)
+    close(mydata->fd);
+  return (0);
+}
+
+void
+write_archive(const char *outname, const char **filename)
+{
+  struct mydata *mydata = malloc(sizeof(struct mydata));
+  struct archive *a;
+  struct archive_entry *entry;
+  struct stat st;
+  char buff[8192];
+  int len;
+  int fd;
+
+  a = archive_write_new();
+  mydata->name = outname;
+  /* Set archive format and filter according to output file extension.
+   * If it fails, set default format. Platform depended function.
+   * See supported formats in archive_write_set_format_filter_by_ext.c */
+  if (archive_write_set_format_filter_by_ext(a, outname) != ARCHIVE_OK)  {
+    archive_write_add_filter_gzip(a);
+    archive_write_set_format_ustar(a);
+  }  
+  archive_write_open(a, mydata, myopen, mywrite, myclose);
+  while (*filename) {
+    stat(*filename, &st);
+    entry = archive_entry_new();
+    archive_entry_copy_stat(entry, &st);
+    archive_entry_set_pathname(entry, *filename);
+    archive_write_header(a, entry);
+    if ((fd = open(*filename, O_RDONLY)) != -1) {
+      len = read(fd, buff, sizeof(buff));
+      while (len > 0) {
+        archive_write_data(a, buff, len);
+        len = read(fd, buff, sizeof(buff));
+      }
+      close(fd);
+    }
+    archive_entry_free(entry);
+    filename++;
+  }
+  archive_write_free(a);
+}
+
+int main(int argc, const char **argv)
+{
+  const char *outname;
+  argv++;
+  outname = *argv++;
+  write_archive(outname, argv);
+  return 0;
+}
+.Ed
+.Sh SEE ALSO
+.Xr tar 1 ,
+.Xr libarchive 3 ,
+.Xr archive_write_set_options 3 ,
+.Xr cpio 5 ,
+.Xr mtree 5 ,
+.Xr tar 5
+.Sh HISTORY
+The
+.Nm libarchive
+library first appeared in
+.Fx 5.3 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm libarchive
+library was written by
+.An Tim Kientzle Aq kientzle@acm.org .
+.Sh BUGS
+There are many peculiar bugs in historic tar implementations that may cause
+certain programs to reject archives written by this library.
+For example, several historic implementations calculated header checksums
+incorrectly and will thus reject valid archives; GNU tar does not fully support
+pax interchange format; some old tar implementations required specific
+field terminations.
+.Pp
+The default pax interchange format eliminates most of the historic
+tar limitations and provides a generic key/value attribute facility
+for vendor-defined extensions.
+One oversight in POSIX is the failure to provide a standard attribute
+for large device numbers.
+This library uses
+.Dq SCHILY.devminor
+and
+.Dq SCHILY.devmajor
+for device numbers that exceed the range supported by the backwards-compatible
+ustar header.
+These keys are compatible with Joerg Schilling's
+.Nm star
+archiver.
+Other implementations may not recognize these keys and will thus be unable
+to correctly restore device nodes with large device numbers from archives
+created by this library.


Mime
View raw message