summaryrefslogtreecommitdiff
path: root/cpio/cpio_windows.c
diff options
context:
space:
mode:
authorTim Kientzle <kientzle@gmail.com>2009-08-02 23:06:15 -0400
committerTim Kientzle <kientzle@gmail.com>2009-08-02 23:06:15 -0400
commit2171f3b62264f5bed6a5dd9849c772fb729361b1 (patch)
tree4d2691cd780d042f86c45a9d9b3d905d1e2adbf6 /cpio/cpio_windows.c
parent3a5f8a96b6a37dc48392b5aeb3810bd9d8d73c54 (diff)
downloadlibarchive-2171f3b62264f5bed6a5dd9849c772fb729361b1.tar.gz
Try to fix cpio_windows.c
SVN-Revision: 1330
Diffstat (limited to 'cpio/cpio_windows.c')
-rw-r--r--cpio/cpio_windows.c203
1 files changed, 147 insertions, 56 deletions
diff --git a/cpio/cpio_windows.c b/cpio/cpio_windows.c
index 508af9fe..65c8bfda 100644
--- a/cpio/cpio_windows.c
+++ b/cpio/cpio_windows.c
@@ -30,7 +30,10 @@
#define WINVER 0x0500
#include "cpio_platform.h"
+#include <ctype.h>
#include <errno.h>
+#include <fcntl.h>
+#include <io.h>
#include <stddef.h>
#include <sys/utime.h>
#include <sys/stat.h>
@@ -63,6 +66,8 @@ struct ustat {
dev_t st_rdev;
};
+static void cpio_dosmaperr(unsigned long);
+
/* Transform 64-bits ino into 32-bits by hashing.
* You do not forget that really unique number size is 64-bits.
*/
@@ -74,7 +79,7 @@ getino(struct ustat *ub)
ino64.QuadPart = ub->st_ino;
/* I don't know this hashing is correct way */
- return (ino64.LowPart ^ (ino64.LowPart >> INOSIZE));
+ return (ino_t)(ino64.LowPart ^ (ino64.LowPart >> INOSIZE));
}
/*
@@ -88,7 +93,7 @@ permissive_name(const char *name)
{
wchar_t *wn, *wnp;
wchar_t *ws, *wsp;
- size_t l, len, slen;
+ size_t l, len, slen, alloclen;
int unc;
len = strlen(name);
@@ -154,7 +159,7 @@ permissive_name(const char *name)
}
}
- slen = 4 + (unc * 4) + len + 1;
+ alloclen = slen = 4 + (unc * 4) + len + 1;
ws = wsp = malloc(slen * sizeof(wchar_t));
if (ws == NULL) {
free(wn);
@@ -170,8 +175,9 @@ permissive_name(const char *name)
wsp += 4;
slen -= 4;
}
- wcsncpy_s(wsp, slen, wnp, _TRUNCATE);
+ wcsncpy(wsp, wnp, slen);
free(wn);
+ ws[alloclen - 1] = L'\0';
return (ws);
}
@@ -289,7 +295,7 @@ __link(const char *src, const char *dst, int sym)
DWORD attr;
if (src == NULL || dst == NULL) {
- set_errno (EINVAL);
+ errno = EINVAL;
return -1;
}
@@ -300,7 +306,7 @@ __link(const char *src, const char *dst, int sym)
free(wsrc);
if (wdst != NULL)
free(wdst);
- set_errno (EINVAL);
+ errno = EINVAL;
return -1;
}
@@ -319,7 +325,7 @@ __link(const char *src, const char *dst, int sym)
wchar_t *wnewsrc, *slash;
int i, n, slen, wlen;
- if (strlen(src) >= 3 && isalpha((unsigned char )src[0]) &&
+ if (strlen(src) >= 3 && isalpha((unsigned char)src[0]) &&
src[1] == ':' && src[2] == '\\') {
/* Original src name is already full-path */
retval = -1;
@@ -362,7 +368,7 @@ __link(const char *src, const char *dst, int sym)
attr = GetFileAttributesW(wnewsrc);
if (attr == -1 || (attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
if (attr == -1)
- _dosmaperr(GetLastError());
+ cpio_dosmaperr(GetLastError());
else
errno = EPERM;
free (wnewsrc);
@@ -376,7 +382,7 @@ __link(const char *src, const char *dst, int sym)
free (wnewsrc);
}
if (res == 0) {
- _dosmaperr(GetLastError());
+ cpio_dosmaperr(GetLastError());
retval = -1;
} else
retval = 0;
@@ -445,7 +451,7 @@ utimes(const char *name, const struct __timeval *times)
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (handle == INVALID_HANDLE_VALUE) {
- _dosmaperr(GetLastError());
+ cpio_dosmaperr(GetLastError());
return (-1);
}
ret = __hutimes(handle, times);
@@ -462,7 +468,7 @@ la_chdir(const char *path)
r = SetCurrentDirectoryA(path);
if (r == 0) {
if (GetLastError() != ERROR_FILE_NOT_FOUND) {
- _dosmaperr(GetLastError());
+ cpio_dosmaperr(GetLastError());
return (-1);
}
} else
@@ -475,38 +481,7 @@ la_chdir(const char *path)
r = SetCurrentDirectoryW(ws);
free(ws);
if (r == 0) {
- _dosmaperr(GetLastError());
- return (-1);
- }
- return (0);
-}
-
-int
-la_mkdir(const char *path, mode_t mode)
-{
- wchar_t *ws;
- int r;
-
- (void)mode;/* UNUSED */
- r = CreateDirectoryA(path, NULL);
- if (r == 0) {
- DWORD lasterr = GetLastError();
- if (lasterr != ERROR_FILENAME_EXCED_RANGE &&
- lasterr != ERROR_PATH_NOT_FOUND) {
- _dosmaperr(GetLastError());
- return (-1);
- }
- } else
- return (0);
- ws = permissive_name(path);
- if (ws == NULL) {
- errno = EINVAL;
- return (-1);
- }
- r = CreateDirectoryW(ws, NULL);
- free(ws);
- if (r == 0) {
- _dosmaperr(GetLastError());
+ cpio_dosmaperr(GetLastError());
return (-1);
}
return (0);
@@ -539,7 +514,7 @@ la_open(const char *path, int flags, ...)
attr = GetFileAttributesW(ws);
}
if (attr == -1) {
- _dosmaperr(GetLastError());
+ cpio_dosmaperr(GetLastError());
free(ws);
return (-1);
}
@@ -560,7 +535,7 @@ la_open(const char *path, int flags, ...)
NULL);
free(ws);
if (handle == INVALID_HANDLE_VALUE) {
- _dosmaperr(GetLastError());
+ cpio_dosmaperr(GetLastError());
return (-1);
}
r = _open_osfhandle((intptr_t)handle, _O_RDONLY);
@@ -573,7 +548,7 @@ la_open(const char *path, int flags, ...)
/* simular other POSIX system action to pass a test */
attr = GetFileAttributesA(path);
if (attr == -1)
- _dosmaperr(GetLastError());
+ cpio_dosmaperr(GetLastError());
else if (attr & FILE_ATTRIBUTE_DIRECTORY)
errno = EISDIR;
else
@@ -593,7 +568,7 @@ la_open(const char *path, int flags, ...)
/* simular other POSIX system action to pass a test */
attr = GetFileAttributesW(ws);
if (attr == -1)
- _dosmaperr(GetLastError());
+ cpio_dosmaperr(GetLastError());
else if (attr & FILE_ATTRIBUTE_DIRECTORY)
errno = EISDIR;
else
@@ -648,7 +623,7 @@ la_read(int fd, void *buf, size_t nbytes)
if (lasterr == ERROR_ACCESS_DENIED)
errno = EBADF;
else
- _dosmaperr(lasterr);
+ cpio_dosmaperr(lasterr);
return (-1);
}
return ((ssize_t)bytes_read);
@@ -748,21 +723,21 @@ __hstat(HANDLE handle, struct ustat *st)
break;
default:
/* This ftype is undocumented type. */
- _dosmaperr(GetLastError());
+ cpio_dosmaperr(GetLastError());
return (-1);
}
ZeroMemory(&info, sizeof(info));
if (!GetFileInformationByHandle (handle, &info)) {
- _dosmaperr(GetLastError());
+ cpio_dosmaperr(GetLastError());
return (-1);
}
- mode = S_IRUSR | S_IRGRP | S_IROTH;
+ mode = 0444;
if ((info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
- mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+ mode |= 0222;
if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
- mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
+ mode |= S_IFDIR | 0111;
else
mode |= S_IFREG;
st->st_mode = mode;
@@ -848,7 +823,7 @@ la_stat(const char *path, struct stat *st)
FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_READONLY,
NULL);
if (handle == INVALID_HANDLE_VALUE) {
- _dosmaperr(GetLastError());
+ cpio_dosmaperr(GetLastError());
return (-1);
}
ret = __hstat(handle, &u);
@@ -868,7 +843,7 @@ la_stat(const char *path, struct stat *st)
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;
+ st->st_mode |= 0111;
}
}
return (ret);
@@ -895,10 +870,126 @@ la_write(int fd, const void *buf, size_t nbytes)
if (lasterr == ERROR_ACCESS_DENIED)
errno = EBADF;
else
- _dosmaperr(lasterr);
+ cpio_dosmaperr(lasterr);
return (-1);
}
return (bytes_written);
}
#endif
+/*
+ * 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 }
+};
+
+static void
+cpio_dosmaperr(unsigned long e)
+{
+ int i;
+
+ if (e == 0) {
+ errno = 0;
+ return;
+ }
+
+ for (i = 0; i < sizeof(doserrors); i++) {
+ if (doserrors[i].winerr == e) {
+ errno = doserrors[i].doserr;
+ return;
+ }
+ }
+
+ /* fprintf(stderr, "unrecognized win32 error code: %lu", e); */
+ errno = EINVAL;
+ return;
+}