diff options
author | Tim Kientzle <kientzle@gmail.com> | 2009-08-02 23:06:15 -0400 |
---|---|---|
committer | Tim Kientzle <kientzle@gmail.com> | 2009-08-02 23:06:15 -0400 |
commit | 2171f3b62264f5bed6a5dd9849c772fb729361b1 (patch) | |
tree | 4d2691cd780d042f86c45a9d9b3d905d1e2adbf6 /cpio/cpio_windows.c | |
parent | 3a5f8a96b6a37dc48392b5aeb3810bd9d8d73c54 (diff) | |
download | libarchive-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.c | 203 |
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; +} |