]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Try to fix cpio_windows.c
authorTim Kientzle <kientzle@gmail.com>
Mon, 3 Aug 2009 03:06:15 +0000 (23:06 -0400)
committerTim Kientzle <kientzle@gmail.com>
Mon, 3 Aug 2009 03:06:15 +0000 (23:06 -0400)
SVN-Revision: 1330

cpio/cpio_windows.c

index 508af9feeb6a3ed96ab7570e612576632fe32002..65c8bfda3e40d2f47ceab19e58c136b6e4bba9a0 100644 (file)
 #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;
+}