summaryrefslogtreecommitdiff
path: root/archivers/libarchive/files/libarchive/archive_windows.c
diff options
context:
space:
mode:
Diffstat (limited to 'archivers/libarchive/files/libarchive/archive_windows.c')
-rw-r--r--archivers/libarchive/files/libarchive/archive_windows.c188
1 files changed, 188 insertions, 0 deletions
diff --git a/archivers/libarchive/files/libarchive/archive_windows.c b/archivers/libarchive/files/libarchive/archive_windows.c
new file mode 100644
index 00000000000..1f4d273dabb
--- /dev/null
+++ b/archivers/libarchive/files/libarchive/archive_windows.c
@@ -0,0 +1,188 @@
+/*-
+ * 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.
+ */
+
+#ifdef _WIN32
+
+#include <errno.h>
+#include <stddef.h>
+#include <sys/utime.h>
+#include <sys/stat.h>
+#include <process.h>
+#include <stdlib.h>
+#include <windows.h>
+#include "archive_platform.h"
+
+/* Make a link to FROM called TO. */
+int link (from, to)
+ const char *from;
+ const char *to;
+{
+ int res;
+
+ if (from == NULL || to == NULL) {
+ set_errno (EINVAL);
+ return -1;
+ }
+
+ if (!_access (from, F_OK))
+ res = CopyFile (from, to, FALSE);
+ else {
+ /* from doesn not exist; try to prepend it with the dirname of to */
+ char *fullfrompath, *slash, *todir;
+ todir = strdup (to);
+ if (!todir)
+ return -1;
+ slash = strrchr(todir, '/');
+ if (slash)
+ *slash = '\0';
+ fullfrompath = malloc (strlen (from) + strlen (todir) + 2);
+ if (!fullfrompath)
+ return -1;
+ strcpy (fullfrompath, todir);
+ strcat (fullfrompath, "/");
+ strcat (fullfrompath, from);
+ if (todir)
+ free (todir);
+ if (_access (fullfrompath, R_OK))
+ return -1;
+ res = CopyFile (fullfrompath, to, FALSE);
+ if (fullfrompath)
+ free (fullfrompath);
+ }
+
+ if (res == 0) {
+ set_errno (EINVAL);
+ return -1;
+ }
+ return 0;
+}
+
+/* Make a symbolic link to FROM called TO. */
+int symlink (from, to)
+ const char *from;
+ const char *to;
+{
+ return link (from, to);
+}
+
+static int get_dev_ino (HANDLE hFile, dev_t *dev, ino_t *ino)
+{
+/* dev_t: short (2 bytes); ino_t: unsigned int (4 bytes) */
+#define LODWORD(l) ((DWORD)((DWORDLONG)(l)))
+#define HIDWORD(l) ((DWORD)(((DWORDLONG)(l)>>32)&0xFFFFFFFF))
+#define MAKEDWORDLONG(a,b) ((DWORDLONG)(((DWORD)(a))|(((DWORDLONG)((DWORD)(b)))<<32)))
+
+#define INOSIZE (8*sizeof(ino_t)) /* 32 */
+//#define DEVSIZE (8*sizeof(dev_t)) /* 16 */
+#define SEQNUMSIZE (16)
+
+ BY_HANDLE_FILE_INFORMATION FileInformation;
+ uint64_t ino64, FileReferenceNumber ;
+ ino_t resino;
+ dev_t resdev;
+ DWORD VolumeSerialNumber;
+
+ *ino = 0;
+ *dev = 0;
+ if (hFile == INVALID_HANDLE_VALUE) /* file cannot be opened */
+ return 0;
+ ZeroMemory (&FileInformation, sizeof(FileInformation));
+ if (!GetFileInformationByHandle (hFile, &FileInformation)) /* cannot obtain FileInformation */
+ return 0;
+ ino64 = (uint64_t) MAKEDWORDLONG (
+ FileInformation.nFileIndexLow, FileInformation.nFileIndexHigh);
+ FileReferenceNumber = ino64 & ((~(0ULL)) >> SEQNUMSIZE); /* remove sequence number */
+ /* transform 64-bits ino into 32-bits by hashing */
+ resino = (ino_t) (
+ ( (LODWORD(FileReferenceNumber)) ^ ((LODWORD(FileReferenceNumber)) >> INOSIZE) )
+// ^
+// ( (HIDWORD(FileReferenceNumber)) ^ ((HIDWORD(FileReferenceNumber)) >> INOSIZE) )
+ );
+ *ino = resino;
+ VolumeSerialNumber = FileInformation.dwVolumeSerialNumber;
+ //resdev = (unsigned short) ( (LOWORD(VolumeSerialNumber)) ^ ((HIWORD(VolumeSerialNumber)) >> DEVSIZE) );
+ resdev = (dev_t) VolumeSerialNumber;
+ *dev = resdev;
+//printf ("get_dev_ino: dev = %d; ino = %u\n", resdev, resino);
+ return 0;
+}
+
+int get_dev_ino_fd (int fd, dev_t *dev, ino_t *ino)
+{
+ HANDLE hFile;
+ hFile = (HANDLE) _get_osfhandle (fd);
+ return get_dev_ino (hFile, dev, ino);
+}
+
+int get_dev_ino_filename (char *path, dev_t *dev, ino_t *ino)
+{
+ HANDLE hFile;
+ int res;
+ if (!path || !*path) /* path = NULL */
+ return 0;
+ if (_access (path, F_OK)) /* path does not exist */
+ return -1;
+/* obtain handle to file "name"; FILE_FLAG_BACKUP_SEMANTICS is used to open directories */
+ hFile = CreateFile (path, 0, 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_READONLY,
+ NULL);
+ res = get_dev_ino (hFile, dev, ino);
+ CloseHandle (hFile);
+ return res;
+}
+
+int fstati64 (int fd, struct _stati64 *st)
+{
+ int res;
+ res = _fstati64 (fd, st);
+ if (res < 0)
+ return -1;
+ if (st->st_ino == 0)
+ res = get_dev_ino_fd (fd, &st->st_dev, &st->st_ino);
+// printf ("fstat: dev = %u; ino = %u\n", st->st_dev, st->st_ino);
+ return res;
+}
+
+#endif /* _WIN32 */