which will be used by ISO writer and xar writer.
SVN-Revision: 1895
CHECK_FUNCTION_EXISTS_GLIBC(mkdir HAVE_MKDIR)
CHECK_FUNCTION_EXISTS_GLIBC(mkfifo HAVE_MKFIFO)
CHECK_FUNCTION_EXISTS_GLIBC(mknod HAVE_MKNOD)
+CHECK_FUNCTION_EXISTS_GLIBC(mkstemp HAVE_MKSTEMP)
CHECK_FUNCTION_EXISTS_GLIBC(nl_langinfo HAVE_NL_LANGINFO)
CHECK_FUNCTION_EXISTS_GLIBC(pipe HAVE_PIPE)
CHECK_FUNCTION_EXISTS_GLIBC(poll HAVE_POLL)
/* Define to 1 if you have the `mknod' function. */
#cmakedefine HAVE_MKNOD 1
+/* Define to 1 if you have the `mkstemp' function. */
+#cmakedefine HAVE_MKSTEMP 1
+
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#cmakedefine HAVE_NDIR_H 1
AC_CHECK_FUNCS([fchdir fchflags fchmod fchown fcntl fork])
AC_CHECK_FUNCS([fstat ftruncate futimens futimes geteuid getpid])
AC_CHECK_FUNCS([lchflags lchmod lchown link lstat])
-AC_CHECK_FUNCS([lutimes memmove memset mkdir mkfifo mknod])
+AC_CHECK_FUNCS([lutimes memmove memset mkdir mkfifo mknod mkstemp])
AC_CHECK_FUNCS([nl_langinfo pipe poll readlink])
AC_CHECK_FUNCS([select setenv setlocale sigaction])
AC_CHECK_FUNCS([strchr strdup strerror strncpy_s strrchr symlink timegm])
int __archive_parse_options(const char *p, const char *fn,
int keysize, char *key, int valsize, char *val);
+int __archive_mktemp(const char *tmpdir);
+
+
#define err_combine(a,b) ((a) < (b) ? (a) : (b))
#if defined(__BORLANDC__) || (defined(_MSC_VER) && _MSC_VER <= 1300)
/*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
+ * Copyright (c) 2009,2010 Michihiro NAKAJIMA
* Copyright (c) 2003-2007 Tim Kientzle
* All rights reserved.
*
#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
/* Return a size which we've consumed for detecting option */
return ((int)(p - p_org));
}
+
+/*
+ * Create a temporary file
+ */
+
+#if defined(HAVE_MKSTEMP) || !defined(HAVE_TMPFILE)
+
+#if defined(_WIN32) && !defined(__CYGWIN__)
+
+static int
+get_tempdir(struct archive_string *temppath)
+{
+ size_t l;
+ char *tmp;
+
+ l = GetTempPathA(0, NULL);
+ if (l == 0)
+ return (ARCHIVE_FATAL);
+ tmp = malloc(l);
+ if (tmp == NULL)
+ return (ARCHIVE_FATAL);
+ GetTempPathA(l, tmp);
+ archive_strcpy(temppath, tmp);
+ free(tmp);
+ return (ARCHIVE_OK);
+}
+
+#else /* _WIN32 && !__CYGWIN__ */
+
+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);
+}
+
+#endif /* _WIN32 && !__CYGWIN__ */
+#endif /* HAVE_MKSTEMP || !HAVE_TMPFILE */
+
+#if defined(HAVE_MKSTEMP)
+
+/*
+ * We can use mkstemp().
+ */
+
+int
+__archive_mktemp(const char *tmpdir)
+{
+ struct archive_string temp_name;
+ int fd;
+
+ 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;
+#if !defined(_WIN32) || defined(__CYGWIN__)
+ /* On Windows, the temporary file will be automatically removed
+ * when the file is closed */
+ unlink(temp_name.s);
+#endif
+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;
+ unsigned seed;
+
+ 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);
+
+ fd = open("/dev/random", O_RDONLY);
+ if (fd < 0)
+ seed = time(NULL);
+ else {
+ if (read(fd, &seed, sizeof(seed)) < 0)
+ seed = time(NULL);
+ close(fd);
+ }
+ do {
+ char *p;
+
+ p = tp;
+ while (p < ep)
+ *p++ = num[((unsigned)rand_r(&seed)) % sizeof(num)];
+ fd = open(temp_name.s, O_CREAT | O_EXCL | O_RDWR, 0600);
+ } while (fd < 0 && errno == EEXIST);
+ if (fd < 0)
+ goto exit_tmpfile;
+ unlink(temp_name.s);
+exit_tmpfile:
+ archive_string_free(&temp_name);
+ return (fd);
+}
+
+#endif
/*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
+ * Copyright (c) 2009,2010 Michihiro NAKAJIMA
* Copyright (c) 2003-2007 Kees Zeelenberg
* All rights reserved.
*
#include <stdlib.h>
#include <wchar.h>
#include <windows.h>
+#include <share.h>
#define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
return (0);
}
+/*
+ * 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.
+ */
+int
+__la_mkstemp(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'
+ };
+ HCRYPTPROV hProv;
+ wchar_t *ws;
+ int fd;
+ size_t l, tmpsize;
+ errno_t err;
+ int i, xcnt;
+
+ fd = -1;
+ hProv = (HCRYPTPROV)NULL;
+ tmpsize = l = strlen(template);
+ xcnt = 0;
+ while (l > 0 && template[--l] == 'X')
+ xcnt++;
+ if (xcnt < 6) {
+ errno = EINVAL;
+ goto exit_tmpfile;
+ }
+
+ if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL,
+ CRYPT_VERIFYCONTEXT)) {
+ la_dosmaperr(GetLastError());
+ goto exit_tmpfile;
+ }
+
+ ws = NULL;
+ do {
+ BYTE *p;
+
+ /* Make a random file name. */
+ p = (BYTE *)template + tmpsize - xcnt;
+ if (!CryptGenRandom(hProv, xcnt, p)) {
+ la_dosmaperr(GetLastError());
+ goto exit_tmpfile;
+ }
+ for (i = 0; i < xcnt; i++, p++)
+ *p = num[*p % sizeof(num)];
+
+ free(ws);
+ ws = permissive_name(template);
+ if (ws == NULL) {
+ errno = EINVAL;
+ goto exit_tmpfile;
+ }
+ err = _wsopen_s(&fd, ws,
+ _O_CREAT | _O_EXCL | _O_BINARY | _O_RDWR | _O_TEMPORARY,
+ _SH_DENYRW,
+ _S_IREAD | _S_IWRITE);
+ } while (err == EEXIST);
+
+ if (err != 0)
+ fd = -1;
+exit_tmpfile:
+ free(ws);
+ if (hProv != (HCRYPTPROV)NULL)
+ CryptReleaseContext(hProv, 0);
+ return (fd);
+}
+
/* Windows' mbstowcs is differrent error handling from other unix mbstowcs.
* That one is using MultiByteToWideChar function with MB_PRECOMPOSED and
* MB_ERR_INVALID_CHARS flags.
/*-
- * Copyright (c) 2009 Michihiro NAKAJIMA
+ * Copyright (c) 2009,2010 Michihiro NAKAJIMA
* Copyright (c) 2003-2006 Tim Kientzle
* All rights reserved.
*
#define lstat __la_stat
#define mbstowcs __la_mbstowcs
#define mkdir(d,m) __la_mkdir(d, m)
+#define mkstemp __la_mkstemp
#define mktemp _mktemp
#define open __la_open
#define read __la_read
#ifndef HAVE_LINK
#define HAVE_LINK 1
#endif
+#ifndef HAVE_MKSTEMP
+#define HAVE_MKSTEMP 1
+#endif
/* Replacement POSIX function */
extern int __la_chdir(const char *path);
extern __int64 __la_lseek(int fd, __int64 offset, int whence);
extern size_t __la_mbstowcs(wchar_t *wcstr, const char *mbstr, size_t nwchars);
extern int __la_mkdir(const char *path, mode_t mode);
+extern int __la_mkstemp(char *template);
extern int __la_open(const char *path, int flags, ...);
extern ssize_t __la_read(int fd, void *buf, size_t nbytes);
extern int __la_rmdir(const char *path);