| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658 | 
							- /*-
 
-  * 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"
 
- #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(_WIN32) && !defined(__CYGWIN__)
 
- #if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
 
- /* don't use bcrypt when XP needs to be supported */
 
- #include <bcrypt.h>
 
- /* Common in other bcrypt implementations, but missing from VS2008. */
 
- #ifndef BCRYPT_SUCCESS
 
- #define BCRYPT_SUCCESS(r) ((NTSTATUS)(r) == STATUS_SUCCESS)
 
- #endif
 
- #elif defined(HAVE_WINCRYPT_H)
 
- #include <wincrypt.h>
 
- #endif
 
- #endif
 
- #ifdef HAVE_ZLIB_H
 
- #include <cm3p/zlib.h>
 
- #endif
 
- #ifdef HAVE_LZMA_H
 
- #include <cm3p/lzma.h>
 
- #endif
 
- #ifdef HAVE_BZLIB_H
 
- #include <cm3p/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
 
- #if ARCHIVE_VERSION_NUMBER < 4000000
 
- static int __LA_LIBC_CC archive_utility_string_sort_helper(const void *, const void *);
 
- #endif
 
- /* 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.
 
-  */
 
- la_int64_t
 
- archive_position_compressed(struct archive *a)
 
- {
 
- 	return archive_filter_bytes(a, -1);
 
- }
 
- /*
 
-  * Return a count of the number of uncompressed bytes processed.
 
-  */
 
- la_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.
 
-  */
 
- static int
 
- __archive_mktempx(const char *tmpdir, wchar_t *template)
 
- {
 
- 	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'
 
- 	};
 
- 	struct archive_wstring temp_name;
 
- 	wchar_t *ws;
 
- 	DWORD attr;
 
- 	wchar_t *xp, *ep;
 
- 	int fd;
 
- #if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
 
- 	BCRYPT_ALG_HANDLE hAlg = NULL;
 
- #else
 
- 	HCRYPTPROV hProv = (HCRYPTPROV)NULL;
 
- #endif
 
- 	fd = -1;
 
- 	ws = NULL;
 
- 	archive_string_init(&temp_name);
 
- 	if (template == NULL) {
 
- 		/* 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.length == 0 ||
 
- 			    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);
 
- 		template = temp_name.s;
 
- 	} else {
 
- 		xp = wcschr(template, L'X');
 
- 		if (xp == NULL)	/* No X, programming error */
 
- 			abort();
 
- 		for (ep = xp; *ep == L'X'; ep++)
 
- 			continue;
 
- 		if (*ep)	/* X followed by non X, programming error */
 
- 			abort();
 
- 	}
 
- #if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
 
- 	if (!BCRYPT_SUCCESS(BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_RNG_ALGORITHM,
 
- 		NULL, 0))) {
 
- 		la_dosmaperr(GetLastError());
 
- 		goto exit_tmpfile;
 
- 	}
 
- #else
 
- 	if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
 
- 		CRYPT_VERIFYCONTEXT)) {
 
- 		la_dosmaperr(GetLastError());
 
- 		goto exit_tmpfile;
 
- 	}
 
- #endif
 
- 	for (;;) {
 
- 		wchar_t *p;
 
- 		HANDLE h;
 
- # if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
 
- 		CREATEFILE2_EXTENDED_PARAMETERS createExParams;
 
- #endif
 
- 		/* Generate a random file name through CryptGenRandom(). */
 
- 		p = xp;
 
- #if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
 
- 		if (!BCRYPT_SUCCESS(BCryptGenRandom(hAlg, (PUCHAR)p,
 
- 		    (DWORD)(ep - p)*sizeof(wchar_t), 0))) {
 
- 			la_dosmaperr(GetLastError());
 
- 			goto exit_tmpfile;
 
- 		}
 
- #else
 
- 		if (!CryptGenRandom(hProv, (DWORD)(ep - p)*sizeof(wchar_t),
 
- 		    (BYTE*)p)) {
 
- 			la_dosmaperr(GetLastError());
 
- 			goto exit_tmpfile;
 
- 		}
 
- #endif
 
- 		for (; p < ep; p++)
 
- 			*p = num[((DWORD)*p) % (sizeof(num)/sizeof(num[0]))];
 
- 		free(ws);
 
- 		ws = __la_win_permissive_name_w(template);
 
- 		if (ws == NULL) {
 
- 			errno = EINVAL;
 
- 			goto exit_tmpfile;
 
- 		}
 
- 		if (template == temp_name.s) {
 
- 			attr = FILE_ATTRIBUTE_TEMPORARY |
 
- 			       FILE_FLAG_DELETE_ON_CLOSE;
 
- 		} else {
 
- 			/* mkstemp */
 
- 			attr = FILE_ATTRIBUTE_NORMAL;
 
- 		}
 
- # if _WIN32_WINNT >= 0x0602 /* _WIN32_WINNT_WIN8 */
 
- 		ZeroMemory(&createExParams, sizeof(createExParams));
 
- 		createExParams.dwSize = sizeof(createExParams);
 
- 		createExParams.dwFileAttributes = attr & 0xFFFF;
 
- 		createExParams.dwFileFlags = attr & 0xFFF00000;
 
- 		h = CreateFile2(ws,
 
- 		    GENERIC_READ | GENERIC_WRITE | DELETE,
 
- 		    0,/* Not share */
 
- 			CREATE_NEW,
 
- 			&createExParams);
 
- #else
 
- 		h = CreateFileW(ws,
 
- 		    GENERIC_READ | GENERIC_WRITE | DELETE,
 
- 		    0,/* Not share */
 
- 		    NULL,
 
- 		    CREATE_NEW,/* Create a new file only */
 
- 		    attr,
 
- 		    NULL);
 
- #endif
 
- 		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) {
 
- 			la_dosmaperr(GetLastError());
 
- 			CloseHandle(h);
 
- 			goto exit_tmpfile;
 
- 		} else
 
- 			break;/* success! */
 
- 	}
 
- exit_tmpfile:
 
- #if defined(HAVE_BCRYPT_H) && _WIN32_WINNT >= _WIN32_WINNT_VISTA
 
- 	if (hAlg != NULL)
 
- 		BCryptCloseAlgorithmProvider(hAlg, 0);
 
- #else
 
- 	if (hProv != (HCRYPTPROV)NULL)
 
- 		CryptReleaseContext(hProv, 0);
 
- #endif
 
- 	free(ws);
 
- 	if (template == temp_name.s)
 
- 		archive_wstring_free(&temp_name);
 
- 	return (fd);
 
- }
 
- int
 
- __archive_mktemp(const char *tmpdir)
 
- {
 
- 	return __archive_mktempx(tmpdir, NULL);
 
- }
 
- int
 
- __archive_mkstemp(wchar_t *template)
 
- {
 
- 	return __archive_mktempx(NULL, template);
 
- }
 
- #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->length == 0 || 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.length == 0 ||
 
- 		    temp_name.s[temp_name.length-1] != '/')
 
- 			archive_strappend_char(&temp_name, '/');
 
- 	}
 
- #ifdef O_TMPFILE
 
- 	fd = open(temp_name.s, O_RDWR|O_CLOEXEC|O_TMPFILE|O_EXCL, 0600); 
 
- 	if(fd >= 0)
 
- 		goto exit_tmpfile;
 
- #endif
 
- 	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);
 
- }
 
- int
 
- __archive_mkstemp(char *template)
 
- {
 
- 	int fd = -1;
 
- 	fd = mkstemp(template);
 
- 	if (fd >= 0)
 
- 		__archive_ensure_cloexec_flag(fd);
 
- 	return (fd);
 
- }
 
- #else /* !HAVE_MKSTEMP */
 
- /*
 
-  * We use a private routine.
 
-  */
 
- static int
 
- __archive_mktempx(const char *tmpdir, char *template)
 
- {
 
-         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;
 
- 	if (template == NULL) {
 
- 		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.length > 0 && temp_name.s[temp_name.length-1] == '/') {
 
- 			temp_name.s[temp_name.length-1] = '\0';
 
- 			temp_name.length --;
 
- 		}
 
- 		if (la_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);
 
- 		template = temp_name.s;
 
- 	} else {
 
- 		tp = strchr(template, 'X');
 
- 		if (tp == NULL)	/* No X, programming error */
 
- 			abort();
 
- 		for (ep = tp; *ep == 'X'; ep++)
 
- 			continue;
 
- 		if (*ep)	/* X followed by non X, programming error */
 
- 			abort();
 
- 	}
 
- 	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(template, 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);
 
- 	if (template == temp_name.s)
 
- 		unlink(temp_name.s);
 
- exit_tmpfile:
 
- 	if (template == temp_name.s)
 
- 		archive_string_free(&temp_name);
 
- 	return (fd);
 
- }
 
- int
 
- __archive_mktemp(const char *tmpdir)
 
- {
 
- 	return __archive_mktempx(tmpdir, NULL);
 
- }
 
- int
 
- __archive_mkstemp(char *template)
 
- {
 
- 	return __archive_mktempx(NULL, template);
 
- }
 
- #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
 
- }
 
- #if ARCHIVE_VERSION_NUMBER < 4000000
 
- /*
 
-  * Utility functions to sort a group of strings using quicksort.
 
-  */
 
- static int
 
- __LA_LIBC_CC
 
- archive_utility_string_sort_helper(const void *p1, const void *p2)
 
- {
 
- 	const char * const * const s1 = p1;
 
- 	const char * const * const s2 = p2;
 
- 	return strcmp(*s1, *s2);
 
- }
 
- int
 
- archive_utility_string_sort(char **strings)
 
- {
 
- 	size_t size = 0;
 
- 	while (strings[size] != NULL)
 
- 		size++;
 
- 	qsort(strings, size, sizeof(char *),
 
- 	      archive_utility_string_sort_helper);
 
- 	return (ARCHIVE_OK);
 
- }
 
- #endif
 
 
  |