libarchive-static 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (157) hide show
  1. data/ext/Makefile +6 -0
  2. data/ext/extconf.rb +61 -0
  3. data/ext/libarchive-0.1.1/COPYING.libarchive +60 -0
  4. data/ext/libarchive-0.1.1/LICENSE.libbzip2 +42 -0
  5. data/ext/libarchive-0.1.1/README.txt +143 -0
  6. data/ext/libarchive-0.1.1/ext/Makefile.in +0 -0
  7. data/ext/libarchive-0.1.1/ext/archive_read_support_compression.c +31 -0
  8. data/ext/libarchive-0.1.1/ext/archive_read_support_compression.h +6 -0
  9. data/ext/libarchive-0.1.1/ext/archive_read_support_format.c +32 -0
  10. data/ext/libarchive-0.1.1/ext/archive_read_support_format.h +6 -0
  11. data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.c +29 -0
  12. data/ext/libarchive-0.1.1/ext/archive_write_open_rb_str.h +6 -0
  13. data/ext/libarchive-0.1.1/ext/archive_write_set_compression.c +32 -0
  14. data/ext/libarchive-0.1.1/ext/archive_write_set_compression.h +6 -0
  15. data/ext/libarchive-0.1.1/ext/config.h.in +22 -0
  16. data/ext/libarchive-0.1.1/ext/configure +3904 -0
  17. data/ext/libarchive-0.1.1/ext/configure.in +11 -0
  18. data/ext/libarchive-0.1.1/ext/depend +19 -0
  19. data/ext/libarchive-0.1.1/ext/extconf.rb +6 -0
  20. data/ext/libarchive-0.1.1/ext/install-sh +250 -0
  21. data/ext/libarchive-0.1.1/ext/libarchive.c +89 -0
  22. data/ext/libarchive-0.1.1/ext/libarchive_archive.c +84 -0
  23. data/ext/libarchive-0.1.1/ext/libarchive_entry.c +1015 -0
  24. data/ext/libarchive-0.1.1/ext/libarchive_internal.h +155 -0
  25. data/ext/libarchive-0.1.1/ext/libarchive_reader.c +328 -0
  26. data/ext/libarchive-0.1.1/ext/libarchive_win32.h +52 -0
  27. data/ext/libarchive-0.1.1/ext/libarchive_writer.c +246 -0
  28. data/ext/libarchive-0.1.1/libarchive.c +1762 -0
  29. data/ext/libarchive-2.8.4/Makefile.in +7076 -0
  30. data/ext/libarchive-2.8.4/build/autoconf/check_stdcall_func.m4 +51 -0
  31. data/ext/libarchive-2.8.4/build/autoconf/compile +143 -0
  32. data/ext/libarchive-2.8.4/build/autoconf/config.guess +1502 -0
  33. data/ext/libarchive-2.8.4/build/autoconf/config.sub +1708 -0
  34. data/ext/libarchive-2.8.4/build/autoconf/depcomp +630 -0
  35. data/ext/libarchive-2.8.4/build/autoconf/install-sh +291 -0
  36. data/ext/libarchive-2.8.4/build/autoconf/la_uid_t.m4 +20 -0
  37. data/ext/libarchive-2.8.4/build/autoconf/ltmain.sh +8406 -0
  38. data/ext/libarchive-2.8.4/build/autoconf/missing +376 -0
  39. data/ext/libarchive-2.8.4/build/pkgconfig/libarchive.pc.in +10 -0
  40. data/ext/libarchive-2.8.4/config.h.in +772 -0
  41. data/ext/libarchive-2.8.4/configure +17916 -0
  42. data/ext/libarchive-2.8.4/libarchive/archive.h +741 -0
  43. data/ext/libarchive-2.8.4/libarchive/archive_check_magic.c +134 -0
  44. data/ext/libarchive-2.8.4/libarchive/archive_crc32.h +66 -0
  45. data/ext/libarchive-2.8.4/libarchive/archive_endian.h +162 -0
  46. data/ext/libarchive-2.8.4/libarchive/archive_entry.c +2202 -0
  47. data/ext/libarchive-2.8.4/libarchive/archive_entry.h +524 -0
  48. data/ext/libarchive-2.8.4/libarchive/archive_entry_copy_bhfi.c +74 -0
  49. data/ext/libarchive-2.8.4/libarchive/archive_entry_copy_stat.c +77 -0
  50. data/ext/libarchive-2.8.4/libarchive/archive_entry_link_resolver.c +405 -0
  51. data/ext/libarchive-2.8.4/libarchive/archive_entry_private.h +184 -0
  52. data/ext/libarchive-2.8.4/libarchive/archive_entry_stat.c +118 -0
  53. data/ext/libarchive-2.8.4/libarchive/archive_entry_strmode.c +87 -0
  54. data/ext/libarchive-2.8.4/libarchive/archive_entry_xattr.c +158 -0
  55. data/ext/libarchive-2.8.4/libarchive/archive_hash.h +281 -0
  56. data/ext/libarchive-2.8.4/libarchive/archive_platform.h +165 -0
  57. data/ext/libarchive-2.8.4/libarchive/archive_private.h +124 -0
  58. data/ext/libarchive-2.8.4/libarchive/archive_read.c +1249 -0
  59. data/ext/libarchive-2.8.4/libarchive/archive_read_data_into_fd.c +93 -0
  60. data/ext/libarchive-2.8.4/libarchive/archive_read_disk.c +198 -0
  61. data/ext/libarchive-2.8.4/libarchive/archive_read_disk_entry_from_file.c +570 -0
  62. data/ext/libarchive-2.8.4/libarchive/archive_read_disk_private.h +62 -0
  63. data/ext/libarchive-2.8.4/libarchive/archive_read_disk_set_standard_lookup.c +303 -0
  64. data/ext/libarchive-2.8.4/libarchive/archive_read_extract.c +182 -0
  65. data/ext/libarchive-2.8.4/libarchive/archive_read_open_fd.c +190 -0
  66. data/ext/libarchive-2.8.4/libarchive/archive_read_open_file.c +165 -0
  67. data/ext/libarchive-2.8.4/libarchive/archive_read_open_filename.c +272 -0
  68. data/ext/libarchive-2.8.4/libarchive/archive_read_open_memory.c +156 -0
  69. data/ext/libarchive-2.8.4/libarchive/archive_read_private.h +199 -0
  70. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_all.c +60 -0
  71. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_bzip2.c +353 -0
  72. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_compress.c +444 -0
  73. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_gzip.c +465 -0
  74. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_none.c +40 -0
  75. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_program.c +459 -0
  76. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_rpm.c +287 -0
  77. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_uu.c +627 -0
  78. data/ext/libarchive-2.8.4/libarchive/archive_read_support_compression_xz.c +708 -0
  79. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_all.c +43 -0
  80. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_ar.c +584 -0
  81. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_cpio.c +777 -0
  82. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_empty.c +93 -0
  83. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_iso9660.c +2830 -0
  84. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_mtree.c +1304 -0
  85. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_raw.c +185 -0
  86. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_tar.c +2418 -0
  87. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_xar.c +3151 -0
  88. data/ext/libarchive-2.8.4/libarchive/archive_read_support_format_zip.c +903 -0
  89. data/ext/libarchive-2.8.4/libarchive/archive_string.c +453 -0
  90. data/ext/libarchive-2.8.4/libarchive/archive_string.h +148 -0
  91. data/ext/libarchive-2.8.4/libarchive/archive_string_sprintf.c +164 -0
  92. data/ext/libarchive-2.8.4/libarchive/archive_util.c +391 -0
  93. data/ext/libarchive-2.8.4/libarchive/archive_virtual.c +94 -0
  94. data/ext/libarchive-2.8.4/libarchive/archive_windows.c +1236 -0
  95. data/ext/libarchive-2.8.4/libarchive/archive_windows.h +347 -0
  96. data/ext/libarchive-2.8.4/libarchive/archive_write.c +466 -0
  97. data/ext/libarchive-2.8.4/libarchive/archive_write_disk.c +2628 -0
  98. data/ext/libarchive-2.8.4/libarchive/archive_write_disk_private.h +38 -0
  99. data/ext/libarchive-2.8.4/libarchive/archive_write_disk_set_standard_lookup.c +262 -0
  100. data/ext/libarchive-2.8.4/libarchive/archive_write_open_fd.c +141 -0
  101. data/ext/libarchive-2.8.4/libarchive/archive_write_open_file.c +105 -0
  102. data/ext/libarchive-2.8.4/libarchive/archive_write_open_filename.c +162 -0
  103. data/ext/libarchive-2.8.4/libarchive/archive_write_open_memory.c +126 -0
  104. data/ext/libarchive-2.8.4/libarchive/archive_write_private.h +122 -0
  105. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_bzip2.c +408 -0
  106. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_compress.c +492 -0
  107. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_gzip.c +477 -0
  108. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_none.c +257 -0
  109. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_program.c +347 -0
  110. data/ext/libarchive-2.8.4/libarchive/archive_write_set_compression_xz.c +438 -0
  111. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format.c +72 -0
  112. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_ar.c +550 -0
  113. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_by_name.c +76 -0
  114. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio.c +344 -0
  115. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_cpio_newc.c +295 -0
  116. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_mtree.c +1050 -0
  117. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_pax.c +1386 -0
  118. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_shar.c +626 -0
  119. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_ustar.c +587 -0
  120. data/ext/libarchive-2.8.4/libarchive/archive_write_set_format_zip.c +667 -0
  121. data/ext/libarchive-2.8.4/libarchive/config_freebsd.h +154 -0
  122. data/ext/libarchive-2.8.4/libarchive/filter_fork.c +161 -0
  123. data/ext/libarchive-2.8.4/libarchive/filter_fork.h +41 -0
  124. data/ext/libarchive-2.8.4/libarchive/filter_fork_windows.c +113 -0
  125. data/ext/libarchive-static-makefile +80 -0
  126. data/ext/libarchive-static-wrapper-makefile +22 -0
  127. data/ext/zlib-1.2.5/Makefile.in +257 -0
  128. data/ext/zlib-1.2.5/adler32.c +169 -0
  129. data/ext/zlib-1.2.5/compress.c +80 -0
  130. data/ext/zlib-1.2.5/configure +596 -0
  131. data/ext/zlib-1.2.5/crc32.c +442 -0
  132. data/ext/zlib-1.2.5/crc32.h +441 -0
  133. data/ext/zlib-1.2.5/deflate.c +1834 -0
  134. data/ext/zlib-1.2.5/deflate.h +342 -0
  135. data/ext/zlib-1.2.5/example.c +565 -0
  136. data/ext/zlib-1.2.5/gzclose.c +25 -0
  137. data/ext/zlib-1.2.5/gzguts.h +132 -0
  138. data/ext/zlib-1.2.5/gzlib.c +537 -0
  139. data/ext/zlib-1.2.5/gzread.c +653 -0
  140. data/ext/zlib-1.2.5/gzwrite.c +531 -0
  141. data/ext/zlib-1.2.5/infback.c +632 -0
  142. data/ext/zlib-1.2.5/inffast.c +340 -0
  143. data/ext/zlib-1.2.5/inffast.h +11 -0
  144. data/ext/zlib-1.2.5/inffixed.h +94 -0
  145. data/ext/zlib-1.2.5/inflate.c +1480 -0
  146. data/ext/zlib-1.2.5/inflate.h +122 -0
  147. data/ext/zlib-1.2.5/inftrees.c +330 -0
  148. data/ext/zlib-1.2.5/inftrees.h +62 -0
  149. data/ext/zlib-1.2.5/minigzip.c +440 -0
  150. data/ext/zlib-1.2.5/trees.c +1244 -0
  151. data/ext/zlib-1.2.5/trees.h +128 -0
  152. data/ext/zlib-1.2.5/uncompr.c +59 -0
  153. data/ext/zlib-1.2.5/zconf.h +428 -0
  154. data/ext/zlib-1.2.5/zlib.h +1613 -0
  155. data/ext/zlib-1.2.5/zutil.c +318 -0
  156. data/ext/zlib-1.2.5/zutil.h +274 -0
  157. metadata +211 -0
@@ -0,0 +1,1236 @@
1
+ /*-
2
+ * Copyright (c) 2009 Michihiro NAKAJIMA
3
+ * Copyright (c) 2003-2007 Kees Zeelenberg
4
+ * All rights reserved.
5
+ *
6
+ * Redistribution and use in source and binary forms, with or without
7
+ * modification, are permitted provided that the following conditions
8
+ * are met:
9
+ * 1. Redistributions of source code must retain the above copyright
10
+ * notice, this list of conditions and the following disclaimer.
11
+ * 2. Redistributions in binary form must reproduce the above copyright
12
+ * notice, this list of conditions and the following disclaimer in the
13
+ * documentation and/or other materials provided with the distribution.
14
+ *
15
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18
+ * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
+ *
26
+ * $FreeBSD$
27
+ */
28
+
29
+ /*
30
+ * A set of compatibility glue for building libarchive on Windows platforms.
31
+ *
32
+ * Originally created as "libarchive-nonposix.c" by Kees Zeelenberg
33
+ * for the GnuWin32 project, trimmed significantly by Tim Kientzle.
34
+ *
35
+ * Much of the original file was unnecessary for libarchive, because
36
+ * many of the features it emulated were not strictly necessary for
37
+ * libarchive. I hope for this to shrink further as libarchive
38
+ * internals are gradually reworked to sit more naturally on both
39
+ * POSIX and Windows. Any ideas for this are greatly appreciated.
40
+ *
41
+ * The biggest remaining issue is the dev/ino emulation; libarchive
42
+ * has a couple of public APIs that rely on dev/ino uniquely
43
+ * identifying a file. This doesn't match well with Windows. I'm
44
+ * considering alternative APIs.
45
+ */
46
+
47
+ #if defined(_WIN32) && !defined(__CYGWIN__)
48
+
49
+ #include "archive_platform.h"
50
+ #include "archive_private.h"
51
+ #include "archive_hash.h"
52
+ #include <ctype.h>
53
+ #include <errno.h>
54
+ #include <stddef.h>
55
+ #ifdef HAVE_SYS_UTIME_H
56
+ #include <sys/utime.h>
57
+ #endif
58
+ #include <sys/stat.h>
59
+ #include <process.h>
60
+ #include <stdlib.h>
61
+ #include <wchar.h>
62
+ #include <windows.h>
63
+
64
+ #define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
65
+
66
+ #if defined(_MSC_VER) && _MSC_VER < 1300
67
+ /* VS 6 does not provide SetFilePointerEx, so define it here. */
68
+ static BOOL SetFilePointerEx(HANDLE hFile,
69
+ LARGE_INTEGER liDistanceToMove,
70
+ PLARGE_INTEGER lpNewFilePointer,
71
+ DWORD dwMoveMethod)
72
+ {
73
+ LARGE_INTEGER li;
74
+ li.QuadPart = liDistanceToMove.QuadPart;
75
+ li.LowPart = SetFilePointer(
76
+ hFile, li.LowPart, &li.HighPart, dwMoveMethod);
77
+ if(lpNewFilePointer) {
78
+ lpNewFilePointer->QuadPart = li.QuadPart;
79
+ }
80
+ return li.LowPart != -1 || GetLastError() == NO_ERROR;
81
+ }
82
+ #endif
83
+
84
+ struct ustat {
85
+ int64_t st_atime;
86
+ uint32_t st_atime_nsec;
87
+ int64_t st_ctime;
88
+ uint32_t st_ctime_nsec;
89
+ int64_t st_mtime;
90
+ uint32_t st_mtime_nsec;
91
+ gid_t st_gid;
92
+ /* 64bits ino */
93
+ int64_t st_ino;
94
+ mode_t st_mode;
95
+ uint32_t st_nlink;
96
+ uint64_t st_size;
97
+ uid_t st_uid;
98
+ dev_t st_dev;
99
+ dev_t st_rdev;
100
+ };
101
+
102
+ /* Local replacement for undocumented Windows CRT function. */
103
+ static void la_dosmaperr(unsigned long e);
104
+
105
+ /* Transform 64-bits ino into 32-bits by hashing.
106
+ * You do not forget that really unique number size is 64-bits.
107
+ */
108
+ #define INOSIZE (8*sizeof(ino_t)) /* 32 */
109
+ static __inline ino_t
110
+ getino(struct ustat *ub)
111
+ {
112
+ ULARGE_INTEGER ino64;
113
+ ino64.QuadPart = ub->st_ino;
114
+ /* I don't know this hashing is correct way */
115
+ return (ino64.LowPart ^ (ino64.LowPart >> INOSIZE));
116
+ }
117
+
118
+ /*
119
+ * Prepend "\\?\" to the path name and convert it to unicode to permit
120
+ * an extended-length path for a maximum total path length of 32767
121
+ * characters.
122
+ * see also http://msdn.microsoft.com/en-us/library/aa365247.aspx
123
+ */
124
+ static wchar_t *
125
+ permissive_name(const char *name)
126
+ {
127
+ wchar_t *wn, *wnp;
128
+ wchar_t *ws, *wsp;
129
+ DWORD l, len, slen;
130
+ int unc;
131
+
132
+ len = (DWORD)strlen(name);
133
+ wn = malloc((len + 1) * sizeof(wchar_t));
134
+ if (wn == NULL)
135
+ return (NULL);
136
+ l = MultiByteToWideChar(CP_ACP, 0, name, (int)len, wn, (int)len);
137
+ if (l == 0) {
138
+ free(wn);
139
+ return (NULL);
140
+ }
141
+ wn[l] = L'\0';
142
+
143
+ /* Get a full path names */
144
+ l = GetFullPathNameW(wn, 0, NULL, NULL);
145
+ if (l == 0) {
146
+ free(wn);
147
+ return (NULL);
148
+ }
149
+ wnp = malloc(l * sizeof(wchar_t));
150
+ if (wnp == NULL) {
151
+ free(wn);
152
+ return (NULL);
153
+ }
154
+ len = GetFullPathNameW(wn, l, wnp, NULL);
155
+ free(wn);
156
+ wn = wnp;
157
+
158
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
159
+ wnp[2] == L'?' && wnp[3] == L'\\')
160
+ /* We have already permissive names. */
161
+ return (wn);
162
+
163
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
164
+ wnp[2] == L'.' && wnp[3] == L'\\') {
165
+ /* Device names */
166
+ if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
167
+ (wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
168
+ wnp[5] == L':' && wnp[6] == L'\\')
169
+ wnp[2] = L'?';/* Not device names. */
170
+ return (wn);
171
+ }
172
+
173
+ unc = 0;
174
+ if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
175
+ wchar_t *p = &wnp[2];
176
+
177
+ /* Skip server-name letters. */
178
+ while (*p != L'\\' && *p != L'\0')
179
+ ++p;
180
+ if (*p == L'\\') {
181
+ wchar_t *rp = ++p;
182
+ /* Skip share-name letters. */
183
+ while (*p != L'\\' && *p != L'\0')
184
+ ++p;
185
+ if (*p == L'\\' && p != rp) {
186
+ /* Now, match patterns such as
187
+ * "\\server-name\share-name\" */
188
+ wnp += 2;
189
+ len -= 2;
190
+ unc = 1;
191
+ }
192
+ }
193
+ }
194
+
195
+ slen = 4 + (unc * 4) + len + 1;
196
+ ws = wsp = malloc(slen * sizeof(wchar_t));
197
+ if (ws == NULL) {
198
+ free(wn);
199
+ return (NULL);
200
+ }
201
+ /* prepend "\\?\" */
202
+ wcsncpy(wsp, L"\\\\?\\", 4);
203
+ wsp += 4;
204
+ slen -= 4;
205
+ if (unc) {
206
+ /* append "UNC\" ---> "\\?\UNC\" */
207
+ wcsncpy(wsp, L"UNC\\", 4);
208
+ wsp += 4;
209
+ slen -= 4;
210
+ }
211
+ wcsncpy(wsp, wnp, slen);
212
+ wsp[slen - 1] = L'\0'; /* Ensure null termination. */
213
+ free(wn);
214
+ return (ws);
215
+ }
216
+
217
+ static HANDLE
218
+ la_CreateFile(const char *path, DWORD dwDesiredAccess, DWORD dwShareMode,
219
+ LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
220
+ DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
221
+ {
222
+ wchar_t *wpath;
223
+ HANDLE handle;
224
+
225
+ handle = CreateFileA(path, dwDesiredAccess, dwShareMode,
226
+ lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
227
+ hTemplateFile);
228
+ if (handle != INVALID_HANDLE_VALUE)
229
+ return (handle);
230
+ if (GetLastError() != ERROR_PATH_NOT_FOUND)
231
+ return (handle);
232
+ wpath = permissive_name(path);
233
+ if (wpath == NULL)
234
+ return (handle);
235
+ handle = CreateFileW(wpath, dwDesiredAccess, dwShareMode,
236
+ lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes,
237
+ hTemplateFile);
238
+ free(wpath);
239
+ return (handle);
240
+ }
241
+
242
+ static void *
243
+ la_GetFunctionKernel32(const char *name)
244
+ {
245
+ static HINSTANCE lib;
246
+ static int set;
247
+ if (!set) {
248
+ set = 1;
249
+ lib = LoadLibrary("kernel32.dll");
250
+ }
251
+ if (lib == NULL) {
252
+ fprintf(stderr, "Can't load kernel32.dll?!\n");
253
+ exit(1);
254
+ }
255
+ return (void *)GetProcAddress(lib, name);
256
+ }
257
+
258
+ static int
259
+ la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
260
+ {
261
+ static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
262
+ static int set;
263
+ if (!set) {
264
+ set = 1;
265
+ f = la_GetFunctionKernel32("CreateHardLinkW");
266
+ }
267
+ return f == NULL ? 0 : (*f)(linkname, target, NULL);
268
+ }
269
+
270
+
271
+ /* Make a link to src called dst. */
272
+ static int
273
+ __link(const char *src, const char *dst)
274
+ {
275
+ wchar_t *wsrc, *wdst;
276
+ int res, retval;
277
+ DWORD attr;
278
+
279
+ if (src == NULL || dst == NULL) {
280
+ set_errno (EINVAL);
281
+ return -1;
282
+ }
283
+
284
+ wsrc = permissive_name(src);
285
+ wdst = permissive_name(dst);
286
+ if (wsrc == NULL || wdst == NULL) {
287
+ free(wsrc);
288
+ free(wdst);
289
+ set_errno (EINVAL);
290
+ return -1;
291
+ }
292
+
293
+ if ((attr = GetFileAttributesW(wsrc)) != (DWORD)-1) {
294
+ res = la_CreateHardLinkW(wdst, wsrc);
295
+ } else {
296
+ /* wsrc does not exist; try src prepend it with the dirname of wdst */
297
+ wchar_t *wnewsrc, *slash;
298
+ int i, n, slen, wlen;
299
+
300
+ if (strlen(src) >= 3 && isalpha((unsigned char)src[0]) &&
301
+ src[1] == ':' && src[2] == '\\') {
302
+ /* Original src name is already full-path */
303
+ retval = -1;
304
+ goto exit;
305
+ }
306
+ if (src[0] == '\\') {
307
+ /* Original src name is almost full-path
308
+ * (maybe src name is without drive) */
309
+ retval = -1;
310
+ goto exit;
311
+ }
312
+
313
+ wnewsrc = malloc ((wcslen(wsrc) + wcslen(wdst) + 1) * sizeof(wchar_t));
314
+ if (wnewsrc == NULL) {
315
+ errno = ENOMEM;
316
+ retval = -1;
317
+ goto exit;
318
+ }
319
+ /* Copying a dirname of wdst */
320
+ wcscpy(wnewsrc, wdst);
321
+ slash = wcsrchr(wnewsrc, L'\\');
322
+ if (slash != NULL)
323
+ *++slash = L'\0';
324
+ else
325
+ wcscat(wnewsrc, L"\\");
326
+ /* Converting multi-byte src to wide-char src */
327
+ wlen = (int)wcslen(wsrc);
328
+ slen = (int)strlen(src);
329
+ n = MultiByteToWideChar(CP_ACP, 0, src, slen, wsrc, wlen);
330
+ if (n == 0) {
331
+ free (wnewsrc);
332
+ retval = -1;
333
+ goto exit;
334
+ }
335
+ for (i = 0; i < n; i++)
336
+ if (wsrc[i] == L'/')
337
+ wsrc[i] = L'\\';
338
+ wcsncat(wnewsrc, wsrc, n);
339
+ /* Check again */
340
+ attr = GetFileAttributesW(wnewsrc);
341
+ if (attr == (DWORD)-1 || (attr & FILE_ATTRIBUTE_DIRECTORY) != 0) {
342
+ if (attr == (DWORD)-1)
343
+ la_dosmaperr(GetLastError());
344
+ else
345
+ errno = EPERM;
346
+ free (wnewsrc);
347
+ retval = -1;
348
+ goto exit;
349
+ }
350
+ res = la_CreateHardLinkW(wdst, wnewsrc);
351
+ free (wnewsrc);
352
+ }
353
+ if (res == 0) {
354
+ la_dosmaperr(GetLastError());
355
+ retval = -1;
356
+ } else
357
+ retval = 0;
358
+ exit:
359
+ free(wsrc);
360
+ free(wdst);
361
+ return (retval);
362
+ }
363
+
364
+ /* Make a hard link to src called dst. */
365
+ int
366
+ __la_link(const char *src, const char *dst)
367
+ {
368
+ return __link(src, dst);
369
+ }
370
+
371
+ int
372
+ __la_ftruncate(int fd, off_t length)
373
+ {
374
+ LARGE_INTEGER distance;
375
+ HANDLE handle;
376
+
377
+ if (fd < 0) {
378
+ errno = EBADF;
379
+ return (-1);
380
+ }
381
+ handle = (HANDLE)_get_osfhandle(fd);
382
+ if (GetFileType(handle) != FILE_TYPE_DISK) {
383
+ errno = EBADF;
384
+ return (-1);
385
+ }
386
+ distance.QuadPart = length;
387
+ if (!SetFilePointerEx(handle, distance, NULL, FILE_BEGIN)) {
388
+ la_dosmaperr(GetLastError());
389
+ return (-1);
390
+ }
391
+ if (!SetEndOfFile(handle)) {
392
+ la_dosmaperr(GetLastError());
393
+ return (-1);
394
+ }
395
+ return (0);
396
+ }
397
+
398
+ #define WINTIME(sec, usec) ((Int32x32To64(sec, 10000000) + EPOC_TIME) + (usec * 10))
399
+ static int
400
+ __hutimes(HANDLE handle, const struct __timeval *times)
401
+ {
402
+ ULARGE_INTEGER wintm;
403
+ FILETIME fatime, fmtime;
404
+
405
+ wintm.QuadPart = WINTIME(times[0].tv_sec, times[0].tv_usec);
406
+ fatime.dwLowDateTime = wintm.LowPart;
407
+ fatime.dwHighDateTime = wintm.HighPart;
408
+ wintm.QuadPart = WINTIME(times[1].tv_sec, times[1].tv_usec);
409
+ fmtime.dwLowDateTime = wintm.LowPart;
410
+ fmtime.dwHighDateTime = wintm.HighPart;
411
+ if (SetFileTime(handle, NULL, &fatime, &fmtime) == 0) {
412
+ errno = EINVAL;
413
+ return (-1);
414
+ }
415
+ return (0);
416
+ }
417
+
418
+ int
419
+ __la_futimes(int fd, const struct __timeval *times)
420
+ {
421
+
422
+ return (__hutimes((HANDLE)_get_osfhandle(fd), times));
423
+ }
424
+
425
+ int
426
+ __la_utimes(const char *name, const struct __timeval *times)
427
+ {
428
+ int ret;
429
+ HANDLE handle;
430
+
431
+ handle = la_CreateFile(name, GENERIC_READ | GENERIC_WRITE,
432
+ FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
433
+ FILE_FLAG_BACKUP_SEMANTICS, NULL);
434
+ if (handle == INVALID_HANDLE_VALUE) {
435
+ la_dosmaperr(GetLastError());
436
+ return (-1);
437
+ }
438
+ ret = __hutimes(handle, times);
439
+ CloseHandle(handle);
440
+ return (ret);
441
+ }
442
+
443
+ int
444
+ __la_chdir(const char *path)
445
+ {
446
+ wchar_t *ws;
447
+ int r;
448
+
449
+ r = SetCurrentDirectoryA(path);
450
+ if (r == 0) {
451
+ if (GetLastError() != ERROR_FILE_NOT_FOUND) {
452
+ la_dosmaperr(GetLastError());
453
+ return (-1);
454
+ }
455
+ } else
456
+ return (0);
457
+ ws = permissive_name(path);
458
+ if (ws == NULL) {
459
+ errno = EINVAL;
460
+ return (-1);
461
+ }
462
+ r = SetCurrentDirectoryW(ws);
463
+ free(ws);
464
+ if (r == 0) {
465
+ la_dosmaperr(GetLastError());
466
+ return (-1);
467
+ }
468
+ return (0);
469
+ }
470
+
471
+ int
472
+ __la_chmod(const char *path, mode_t mode)
473
+ {
474
+ wchar_t *ws;
475
+ DWORD attr;
476
+ BOOL r;
477
+
478
+ ws = NULL;
479
+ attr = GetFileAttributesA(path);
480
+ if (attr == (DWORD)-1) {
481
+ if (GetLastError() != ERROR_FILE_NOT_FOUND) {
482
+ la_dosmaperr(GetLastError());
483
+ return (-1);
484
+ }
485
+ ws = permissive_name(path);
486
+ if (ws == NULL) {
487
+ errno = EINVAL;
488
+ return (-1);
489
+ }
490
+ attr = GetFileAttributesW(ws);
491
+ if (attr == (DWORD)-1) {
492
+ free(ws);
493
+ la_dosmaperr(GetLastError());
494
+ return (-1);
495
+ }
496
+ }
497
+ if (mode & _S_IWRITE)
498
+ attr &= ~FILE_ATTRIBUTE_READONLY;
499
+ else
500
+ attr |= FILE_ATTRIBUTE_READONLY;
501
+ if (ws == NULL)
502
+ r = SetFileAttributesA(path, attr);
503
+ else {
504
+ r = SetFileAttributesW(ws, attr);
505
+ free(ws);
506
+ }
507
+ if (r == 0) {
508
+ la_dosmaperr(GetLastError());
509
+ return (-1);
510
+ }
511
+ return (0);
512
+ }
513
+
514
+ /*
515
+ * This fcntl is limited implemention.
516
+ */
517
+ int
518
+ __la_fcntl(int fd, int cmd, int val)
519
+ {
520
+ HANDLE handle;
521
+
522
+ handle = (HANDLE)_get_osfhandle(fd);
523
+ if (GetFileType(handle) == FILE_TYPE_PIPE) {
524
+ if (cmd == F_SETFL && val == 0) {
525
+ DWORD mode = PIPE_WAIT;
526
+ if (SetNamedPipeHandleState(
527
+ handle, &mode, NULL, NULL) != 0)
528
+ return (0);
529
+ }
530
+ }
531
+ errno = EINVAL;
532
+ return (-1);
533
+ }
534
+
535
+ __int64
536
+ __la_lseek(int fd, __int64 offset, int whence)
537
+ {
538
+ LARGE_INTEGER distance;
539
+ LARGE_INTEGER newpointer;
540
+ HANDLE handle;
541
+
542
+ if (fd < 0) {
543
+ errno = EBADF;
544
+ return (-1);
545
+ }
546
+ handle = (HANDLE)_get_osfhandle(fd);
547
+ if (GetFileType(handle) != FILE_TYPE_DISK) {
548
+ errno = EBADF;
549
+ return (-1);
550
+ }
551
+ distance.QuadPart = offset;
552
+ if (!SetFilePointerEx(handle, distance, &newpointer, whence)) {
553
+ DWORD lasterr;
554
+
555
+ lasterr = GetLastError();
556
+ if (lasterr == ERROR_BROKEN_PIPE)
557
+ return (0);
558
+ if (lasterr == ERROR_ACCESS_DENIED)
559
+ errno = EBADF;
560
+ else
561
+ la_dosmaperr(lasterr);
562
+ return (-1);
563
+ }
564
+ return (newpointer.QuadPart);
565
+ }
566
+
567
+ int
568
+ __la_mkdir(const char *path, mode_t mode)
569
+ {
570
+ wchar_t *ws;
571
+ int r;
572
+
573
+ (void)mode;/* UNUSED */
574
+ r = CreateDirectoryA(path, NULL);
575
+ if (r == 0) {
576
+ DWORD lasterr = GetLastError();
577
+ if (lasterr != ERROR_FILENAME_EXCED_RANGE &&
578
+ lasterr != ERROR_PATH_NOT_FOUND) {
579
+ la_dosmaperr(GetLastError());
580
+ return (-1);
581
+ }
582
+ } else
583
+ return (0);
584
+ ws = permissive_name(path);
585
+ if (ws == NULL) {
586
+ errno = EINVAL;
587
+ return (-1);
588
+ }
589
+ r = CreateDirectoryW(ws, NULL);
590
+ free(ws);
591
+ if (r == 0) {
592
+ la_dosmaperr(GetLastError());
593
+ return (-1);
594
+ }
595
+ return (0);
596
+ }
597
+
598
+ /* Windows' mbstowcs is differrent error handling from other unix mbstowcs.
599
+ * That one is using MultiByteToWideChar function with MB_PRECOMPOSED and
600
+ * MB_ERR_INVALID_CHARS flags.
601
+ * This implements for only to pass libarchive_test.
602
+ */
603
+ size_t
604
+ __la_mbstowcs(wchar_t *wcstr, const char *mbstr, size_t nwchars)
605
+ {
606
+
607
+ return (MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
608
+ mbstr, (int)strlen(mbstr), wcstr,
609
+ (int)nwchars));
610
+ }
611
+
612
+ int
613
+ __la_open(const char *path, int flags, ...)
614
+ {
615
+ va_list ap;
616
+ wchar_t *ws;
617
+ int r, pmode;
618
+ DWORD attr;
619
+
620
+ va_start(ap, flags);
621
+ pmode = va_arg(ap, int);
622
+ va_end(ap);
623
+ ws = NULL;
624
+ if ((flags & ~O_BINARY) == O_RDONLY) {
625
+ /*
626
+ * When we open a directory, _open function returns
627
+ * "Permission denied" error.
628
+ */
629
+ attr = GetFileAttributesA(path);
630
+ if (attr == (DWORD)-1 && GetLastError() == ERROR_PATH_NOT_FOUND) {
631
+ ws = permissive_name(path);
632
+ if (ws == NULL) {
633
+ errno = EINVAL;
634
+ return (-1);
635
+ }
636
+ attr = GetFileAttributesW(ws);
637
+ }
638
+ if (attr == (DWORD)-1) {
639
+ la_dosmaperr(GetLastError());
640
+ free(ws);
641
+ return (-1);
642
+ }
643
+ if (attr & FILE_ATTRIBUTE_DIRECTORY) {
644
+ HANDLE handle;
645
+
646
+ if (ws != NULL)
647
+ handle = CreateFileW(ws, 0, 0, NULL,
648
+ OPEN_EXISTING,
649
+ FILE_FLAG_BACKUP_SEMANTICS |
650
+ FILE_ATTRIBUTE_READONLY,
651
+ NULL);
652
+ else
653
+ handle = CreateFileA(path, 0, 0, NULL,
654
+ OPEN_EXISTING,
655
+ FILE_FLAG_BACKUP_SEMANTICS |
656
+ FILE_ATTRIBUTE_READONLY,
657
+ NULL);
658
+ free(ws);
659
+ if (handle == INVALID_HANDLE_VALUE) {
660
+ la_dosmaperr(GetLastError());
661
+ return (-1);
662
+ }
663
+ r = _open_osfhandle((intptr_t)handle, _O_RDONLY);
664
+ return (r);
665
+ }
666
+ }
667
+ if (ws == NULL) {
668
+ #if defined(__BORLANDC__)
669
+ /* Borland has no mode argument.
670
+ TODO: Fix mode of new file. */
671
+ r = _open(path, flags);
672
+ #else
673
+ r = _open(path, flags, pmode);
674
+ #endif
675
+ if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
676
+ /* simular other POSIX system action to pass a test */
677
+ attr = GetFileAttributesA(path);
678
+ if (attr == (DWORD)-1)
679
+ la_dosmaperr(GetLastError());
680
+ else if (attr & FILE_ATTRIBUTE_DIRECTORY)
681
+ errno = EISDIR;
682
+ else
683
+ errno = EACCES;
684
+ return (-1);
685
+ }
686
+ if (r >= 0 || errno != ENOENT)
687
+ return (r);
688
+ ws = permissive_name(path);
689
+ if (ws == NULL) {
690
+ errno = EINVAL;
691
+ return (-1);
692
+ }
693
+ }
694
+ r = _wopen(ws, flags, pmode);
695
+ if (r < 0 && errno == EACCES && (flags & O_CREAT) != 0) {
696
+ /* simular other POSIX system action to pass a test */
697
+ attr = GetFileAttributesW(ws);
698
+ if (attr == (DWORD)-1)
699
+ la_dosmaperr(GetLastError());
700
+ else if (attr & FILE_ATTRIBUTE_DIRECTORY)
701
+ errno = EISDIR;
702
+ else
703
+ errno = EACCES;
704
+ }
705
+ free(ws);
706
+ return (r);
707
+ }
708
+
709
+ ssize_t
710
+ __la_read(int fd, void *buf, size_t nbytes)
711
+ {
712
+ HANDLE handle;
713
+ DWORD bytes_read, lasterr;
714
+ int r;
715
+
716
+ #ifdef _WIN64
717
+ if (nbytes > UINT32_MAX)
718
+ nbytes = UINT32_MAX;
719
+ #endif
720
+ if (fd < 0) {
721
+ errno = EBADF;
722
+ return (-1);
723
+ }
724
+ handle = (HANDLE)_get_osfhandle(fd);
725
+ if (GetFileType(handle) == FILE_TYPE_PIPE) {
726
+ DWORD sta;
727
+ if (GetNamedPipeHandleState(
728
+ handle, &sta, NULL, NULL, NULL, NULL, 0) != 0 &&
729
+ (sta & PIPE_NOWAIT) == 0) {
730
+ DWORD avail = -1;
731
+ int cnt = 3;
732
+
733
+ while (PeekNamedPipe(
734
+ handle, NULL, 0, NULL, &avail, NULL) != 0 &&
735
+ avail == 0 && --cnt)
736
+ Sleep(100);
737
+ if (avail == 0)
738
+ return (0);
739
+ }
740
+ }
741
+ r = ReadFile(handle, buf, (uint32_t)nbytes,
742
+ &bytes_read, NULL);
743
+ if (r == 0) {
744
+ lasterr = GetLastError();
745
+ if (lasterr == ERROR_NO_DATA) {
746
+ errno = EAGAIN;
747
+ return (-1);
748
+ }
749
+ if (lasterr == ERROR_BROKEN_PIPE)
750
+ return (0);
751
+ if (lasterr == ERROR_ACCESS_DENIED)
752
+ errno = EBADF;
753
+ else
754
+ la_dosmaperr(lasterr);
755
+ return (-1);
756
+ }
757
+ return ((ssize_t)bytes_read);
758
+ }
759
+
760
+ /* Remove directory */
761
+ int
762
+ __la_rmdir(const char *path)
763
+ {
764
+ wchar_t *ws;
765
+ int r;
766
+
767
+ r = _rmdir(path);
768
+ if (r >= 0 || errno != ENOENT)
769
+ return (r);
770
+ ws = permissive_name(path);
771
+ if (ws == NULL) {
772
+ errno = EINVAL;
773
+ return (-1);
774
+ }
775
+ r = _wrmdir(ws);
776
+ free(ws);
777
+ return (r);
778
+ }
779
+
780
+ /* Convert Windows FILETIME to UTC */
781
+ __inline static void
782
+ fileTimeToUTC(const FILETIME *filetime, time_t *time, long *ns)
783
+ {
784
+ ULARGE_INTEGER utc;
785
+
786
+ utc.HighPart = filetime->dwHighDateTime;
787
+ utc.LowPart = filetime->dwLowDateTime;
788
+ if (utc.QuadPart >= EPOC_TIME) {
789
+ utc.QuadPart -= EPOC_TIME;
790
+ *time = (time_t)(utc.QuadPart / 10000000); /* milli seconds base */
791
+ *ns = (long)(utc.QuadPart % 10000000) * 100;/* nano seconds base */
792
+ } else {
793
+ *time = 0;
794
+ *ns = 0;
795
+ }
796
+ }
797
+
798
+ /* Stat by handle
799
+ * Windows' stat() does not accept path which is added "\\?\" especially "?"
800
+ * character.
801
+ * It means we cannot access a long name path(which is longer than MAX_PATH).
802
+ * So I've implemented simular Windows' stat() to access the long name path.
803
+ * And I've added some feature.
804
+ * 1. set st_ino by nFileIndexHigh and nFileIndexLow of
805
+ * BY_HANDLE_FILE_INFORMATION.
806
+ * 2. set st_nlink by nNumberOfLinks of BY_HANDLE_FILE_INFORMATION.
807
+ * 3. set st_dev by dwVolumeSerialNumber by BY_HANDLE_FILE_INFORMATION.
808
+ */
809
+ static int
810
+ __hstat(HANDLE handle, struct ustat *st)
811
+ {
812
+ BY_HANDLE_FILE_INFORMATION info;
813
+ ULARGE_INTEGER ino64;
814
+ DWORD ftype;
815
+ mode_t mode;
816
+ time_t time;
817
+ long ns;
818
+
819
+ switch (ftype = GetFileType(handle)) {
820
+ case FILE_TYPE_UNKNOWN:
821
+ errno = EBADF;
822
+ return (-1);
823
+ case FILE_TYPE_CHAR:
824
+ case FILE_TYPE_PIPE:
825
+ if (ftype == FILE_TYPE_CHAR) {
826
+ st->st_mode = S_IFCHR;
827
+ st->st_size = 0;
828
+ } else {
829
+ DWORD avail;
830
+
831
+ st->st_mode = S_IFIFO;
832
+ if (PeekNamedPipe(handle, NULL, 0, NULL, &avail, NULL))
833
+ st->st_size = avail;
834
+ else
835
+ st->st_size = 0;
836
+ }
837
+ st->st_atime = 0;
838
+ st->st_atime_nsec = 0;
839
+ st->st_mtime = 0;
840
+ st->st_mtime_nsec = 0;
841
+ st->st_ctime = 0;
842
+ st->st_ctime_nsec = 0;
843
+ st->st_ino = 0;
844
+ st->st_nlink = 1;
845
+ st->st_uid = 0;
846
+ st->st_gid = 0;
847
+ st->st_rdev = 0;
848
+ st->st_dev = 0;
849
+ return (0);
850
+ case FILE_TYPE_DISK:
851
+ break;
852
+ default:
853
+ /* This ftype is undocumented type. */
854
+ la_dosmaperr(GetLastError());
855
+ return (-1);
856
+ }
857
+
858
+ ZeroMemory(&info, sizeof(info));
859
+ if (!GetFileInformationByHandle (handle, &info)) {
860
+ la_dosmaperr(GetLastError());
861
+ return (-1);
862
+ }
863
+
864
+ mode = S_IRUSR | S_IRGRP | S_IROTH;
865
+ if ((info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
866
+ mode |= S_IWUSR | S_IWGRP | S_IWOTH;
867
+ if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
868
+ mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
869
+ else
870
+ mode |= S_IFREG;
871
+ st->st_mode = mode;
872
+
873
+ fileTimeToUTC(&info.ftLastAccessTime, &time, &ns);
874
+ st->st_atime = time;
875
+ st->st_atime_nsec = ns;
876
+ fileTimeToUTC(&info.ftLastWriteTime, &time, &ns);
877
+ st->st_mtime = time;
878
+ st->st_mtime_nsec = ns;
879
+ fileTimeToUTC(&info.ftCreationTime, &time, &ns);
880
+ st->st_ctime = time;
881
+ st->st_ctime_nsec = ns;
882
+ st->st_size =
883
+ ((int64_t)(info.nFileSizeHigh) * ((int64_t)MAXDWORD + 1))
884
+ + (int64_t)(info.nFileSizeLow);
885
+ #ifdef SIMULATE_WIN_STAT
886
+ st->st_ino = 0;
887
+ st->st_nlink = 1;
888
+ st->st_dev = 0;
889
+ #else
890
+ /* Getting FileIndex as i-node. We have to remove a sequence which
891
+ * is high-16-bits of nFileIndexHigh. */
892
+ ino64.HighPart = info.nFileIndexHigh & 0x0000FFFFUL;
893
+ ino64.LowPart = info.nFileIndexLow;
894
+ st->st_ino = ino64.QuadPart;
895
+ st->st_nlink = info.nNumberOfLinks;
896
+ if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
897
+ ++st->st_nlink;/* Add parent directory. */
898
+ st->st_dev = info.dwVolumeSerialNumber;
899
+ #endif
900
+ st->st_uid = 0;
901
+ st->st_gid = 0;
902
+ st->st_rdev = 0;
903
+ return (0);
904
+ }
905
+
906
+ static void
907
+ copy_stat(struct stat *st, struct ustat *us)
908
+ {
909
+ st->st_atime = us->st_atime;
910
+ st->st_ctime = us->st_ctime;
911
+ st->st_mtime = us->st_mtime;
912
+ st->st_gid = us->st_gid;
913
+ st->st_ino = getino(us);
914
+ st->st_mode = us->st_mode;
915
+ st->st_nlink = us->st_nlink;
916
+ st->st_size = us->st_size;
917
+ st->st_uid = us->st_uid;
918
+ st->st_dev = us->st_dev;
919
+ st->st_rdev = us->st_rdev;
920
+ }
921
+
922
+ int
923
+ __la_fstat(int fd, struct stat *st)
924
+ {
925
+ struct ustat u;
926
+ int ret;
927
+
928
+ if (fd < 0) {
929
+ errno = EBADF;
930
+ return (-1);
931
+ }
932
+ ret = __hstat((HANDLE)_get_osfhandle(fd), &u);
933
+ if (ret >= 0) {
934
+ copy_stat(st, &u);
935
+ if (u.st_mode & (S_IFCHR | S_IFIFO)) {
936
+ st->st_dev = fd;
937
+ st->st_rdev = fd;
938
+ }
939
+ }
940
+ return (ret);
941
+ }
942
+
943
+ int
944
+ __la_stat(const char *path, struct stat *st)
945
+ {
946
+ HANDLE handle;
947
+ struct ustat u;
948
+ int ret;
949
+
950
+ handle = la_CreateFile(path, 0, 0, NULL, OPEN_EXISTING,
951
+ FILE_FLAG_BACKUP_SEMANTICS | FILE_ATTRIBUTE_READONLY,
952
+ NULL);
953
+ if (handle == INVALID_HANDLE_VALUE) {
954
+ la_dosmaperr(GetLastError());
955
+ return (-1);
956
+ }
957
+ ret = __hstat(handle, &u);
958
+ CloseHandle(handle);
959
+ if (ret >= 0) {
960
+ char *p;
961
+
962
+ copy_stat(st, &u);
963
+ p = strrchr(path, '.');
964
+ if (p != NULL && strlen(p) == 4) {
965
+ char exttype[4];
966
+
967
+ ++ p;
968
+ exttype[0] = toupper(*p++);
969
+ exttype[1] = toupper(*p++);
970
+ exttype[2] = toupper(*p++);
971
+ exttype[3] = '\0';
972
+ if (!strcmp(exttype, "EXE") || !strcmp(exttype, "CMD") ||
973
+ !strcmp(exttype, "BAT") || !strcmp(exttype, "COM"))
974
+ st->st_mode |= S_IXUSR | S_IXGRP | S_IXOTH;
975
+ }
976
+ }
977
+ return (ret);
978
+ }
979
+
980
+ int
981
+ __la_unlink(const char *path)
982
+ {
983
+ wchar_t *ws;
984
+ int r;
985
+
986
+ r = _unlink(path);
987
+ if (r >= 0 || errno != ENOENT)
988
+ return (r);
989
+ ws = permissive_name(path);
990
+ if (ws == NULL) {
991
+ errno = EINVAL;
992
+ return (-1);
993
+ }
994
+ r = _wunlink(ws);
995
+ free(ws);
996
+ return (r);
997
+ }
998
+
999
+ /*
1000
+ * This waitpid is limited implemention.
1001
+ */
1002
+ pid_t
1003
+ __la_waitpid(pid_t wpid, int *status, int option)
1004
+ {
1005
+ HANDLE child;
1006
+ DWORD cs, ret;
1007
+
1008
+ (void)option;/* UNUSED */
1009
+ child = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, wpid);
1010
+ if (child == NULL) {
1011
+ la_dosmaperr(GetLastError());
1012
+ return (-1);
1013
+ }
1014
+ ret = WaitForSingleObject(child, INFINITE);
1015
+ if (ret == WAIT_FAILED) {
1016
+ CloseHandle(child);
1017
+ la_dosmaperr(GetLastError());
1018
+ return (-1);
1019
+ }
1020
+ if (GetExitCodeProcess(child, &cs) == 0) {
1021
+ CloseHandle(child);
1022
+ la_dosmaperr(GetLastError());
1023
+ return (-1);
1024
+ }
1025
+ if (cs == STILL_ACTIVE)
1026
+ *status = 0x100;
1027
+ else
1028
+ *status = (int)(cs & 0xff);
1029
+ CloseHandle(child);
1030
+ return (wpid);
1031
+ }
1032
+
1033
+ ssize_t
1034
+ __la_write(int fd, const void *buf, size_t nbytes)
1035
+ {
1036
+ DWORD bytes_written;
1037
+
1038
+ #ifdef _WIN64
1039
+ if (nbytes > UINT32_MAX)
1040
+ nbytes = UINT32_MAX;
1041
+ #endif
1042
+ if (fd < 0) {
1043
+ errno = EBADF;
1044
+ return (-1);
1045
+ }
1046
+ if (!WriteFile((HANDLE)_get_osfhandle(fd), buf, (uint32_t)nbytes,
1047
+ &bytes_written, NULL)) {
1048
+ DWORD lasterr;
1049
+
1050
+ lasterr = GetLastError();
1051
+ if (lasterr == ERROR_ACCESS_DENIED)
1052
+ errno = EBADF;
1053
+ else
1054
+ la_dosmaperr(lasterr);
1055
+ return (-1);
1056
+ }
1057
+ return (bytes_written);
1058
+ }
1059
+
1060
+ /*
1061
+ * The following function was modified from PostgreSQL sources and is
1062
+ * subject to the copyright below.
1063
+ */
1064
+ /*-------------------------------------------------------------------------
1065
+ *
1066
+ * win32error.c
1067
+ * Map win32 error codes to errno values
1068
+ *
1069
+ * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
1070
+ *
1071
+ * IDENTIFICATION
1072
+ * $PostgreSQL: pgsql/src/port/win32error.c,v 1.4 2008/01/01 19:46:00 momjian Exp $
1073
+ *
1074
+ *-------------------------------------------------------------------------
1075
+ */
1076
+ /*
1077
+ PostgreSQL Database Management System
1078
+ (formerly known as Postgres, then as Postgres95)
1079
+
1080
+ Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
1081
+
1082
+ Portions Copyright (c) 1994, The Regents of the University of California
1083
+
1084
+ Permission to use, copy, modify, and distribute this software and its
1085
+ documentation for any purpose, without fee, and without a written agreement
1086
+ is hereby granted, provided that the above copyright notice and this
1087
+ paragraph and the following two paragraphs appear in all copies.
1088
+
1089
+ IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
1090
+ DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
1091
+ LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
1092
+ DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE
1093
+ POSSIBILITY OF SUCH DAMAGE.
1094
+
1095
+ THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
1096
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
1097
+ AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
1098
+ ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO
1099
+ PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1100
+ */
1101
+
1102
+ static const struct {
1103
+ DWORD winerr;
1104
+ int doserr;
1105
+ } doserrors[] =
1106
+ {
1107
+ { ERROR_INVALID_FUNCTION, EINVAL },
1108
+ { ERROR_FILE_NOT_FOUND, ENOENT },
1109
+ { ERROR_PATH_NOT_FOUND, ENOENT },
1110
+ { ERROR_TOO_MANY_OPEN_FILES, EMFILE },
1111
+ { ERROR_ACCESS_DENIED, EACCES },
1112
+ { ERROR_INVALID_HANDLE, EBADF },
1113
+ { ERROR_ARENA_TRASHED, ENOMEM },
1114
+ { ERROR_NOT_ENOUGH_MEMORY, ENOMEM },
1115
+ { ERROR_INVALID_BLOCK, ENOMEM },
1116
+ { ERROR_BAD_ENVIRONMENT, E2BIG },
1117
+ { ERROR_BAD_FORMAT, ENOEXEC },
1118
+ { ERROR_INVALID_ACCESS, EINVAL },
1119
+ { ERROR_INVALID_DATA, EINVAL },
1120
+ { ERROR_INVALID_DRIVE, ENOENT },
1121
+ { ERROR_CURRENT_DIRECTORY, EACCES },
1122
+ { ERROR_NOT_SAME_DEVICE, EXDEV },
1123
+ { ERROR_NO_MORE_FILES, ENOENT },
1124
+ { ERROR_LOCK_VIOLATION, EACCES },
1125
+ { ERROR_SHARING_VIOLATION, EACCES },
1126
+ { ERROR_BAD_NETPATH, ENOENT },
1127
+ { ERROR_NETWORK_ACCESS_DENIED, EACCES },
1128
+ { ERROR_BAD_NET_NAME, ENOENT },
1129
+ { ERROR_FILE_EXISTS, EEXIST },
1130
+ { ERROR_CANNOT_MAKE, EACCES },
1131
+ { ERROR_FAIL_I24, EACCES },
1132
+ { ERROR_INVALID_PARAMETER, EINVAL },
1133
+ { ERROR_NO_PROC_SLOTS, EAGAIN },
1134
+ { ERROR_DRIVE_LOCKED, EACCES },
1135
+ { ERROR_BROKEN_PIPE, EPIPE },
1136
+ { ERROR_DISK_FULL, ENOSPC },
1137
+ { ERROR_INVALID_TARGET_HANDLE, EBADF },
1138
+ { ERROR_INVALID_HANDLE, EINVAL },
1139
+ { ERROR_WAIT_NO_CHILDREN, ECHILD },
1140
+ { ERROR_CHILD_NOT_COMPLETE, ECHILD },
1141
+ { ERROR_DIRECT_ACCESS_HANDLE, EBADF },
1142
+ { ERROR_NEGATIVE_SEEK, EINVAL },
1143
+ { ERROR_SEEK_ON_DEVICE, EACCES },
1144
+ { ERROR_DIR_NOT_EMPTY, ENOTEMPTY },
1145
+ { ERROR_NOT_LOCKED, EACCES },
1146
+ { ERROR_BAD_PATHNAME, ENOENT },
1147
+ { ERROR_MAX_THRDS_REACHED, EAGAIN },
1148
+ { ERROR_LOCK_FAILED, EACCES },
1149
+ { ERROR_ALREADY_EXISTS, EEXIST },
1150
+ { ERROR_FILENAME_EXCED_RANGE, ENOENT },
1151
+ { ERROR_NESTING_NOT_ALLOWED, EAGAIN },
1152
+ { ERROR_NOT_ENOUGH_QUOTA, ENOMEM }
1153
+ };
1154
+
1155
+ static void
1156
+ la_dosmaperr(unsigned long e)
1157
+ {
1158
+ int i;
1159
+
1160
+ if (e == 0)
1161
+ {
1162
+ errno = 0;
1163
+ return;
1164
+ }
1165
+
1166
+ for (i = 0; i < sizeof(doserrors); i++)
1167
+ {
1168
+ if (doserrors[i].winerr == e)
1169
+ {
1170
+ errno = doserrors[i].doserr;
1171
+ return;
1172
+ }
1173
+ }
1174
+
1175
+ /* fprintf(stderr, "unrecognized win32 error code: %lu", e); */
1176
+ errno = EINVAL;
1177
+ return;
1178
+ }
1179
+
1180
+ #if defined(ARCHIVE_HASH_MD5_WIN) ||\
1181
+ defined(ARCHIVE_HASH_SHA1_WIN) || defined(ARCHIVE_HASH_SHA256_WIN) ||\
1182
+ defined(ARCHIVE_HASH_SHA384_WIN) || defined(ARCHIVE_HASH_SHA512_WIN)
1183
+ /*
1184
+ * Message digest functions.
1185
+ */
1186
+ void
1187
+ __la_hash_Init(Digest_CTX *ctx, ALG_ID algId)
1188
+ {
1189
+
1190
+ ctx->valid = 0;
1191
+ if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
1192
+ PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) {
1193
+ if (GetLastError() != (DWORD)NTE_BAD_KEYSET)
1194
+ return;
1195
+ if (!CryptAcquireContext(&ctx->cryptProv, NULL, NULL,
1196
+ PROV_RSA_FULL, CRYPT_NEWKEYSET))
1197
+ return;
1198
+ }
1199
+
1200
+ if (!CryptCreateHash(ctx->cryptProv, algId, 0, 0, &ctx->hash)) {
1201
+ CryptReleaseContext(ctx->cryptProv, 0);
1202
+ return;
1203
+ }
1204
+
1205
+ ctx->valid = 1;
1206
+ }
1207
+
1208
+ void
1209
+ __la_hash_Update(Digest_CTX *ctx, const unsigned char *buf, size_t len)
1210
+ {
1211
+
1212
+ if (!ctx->valid)
1213
+ return;
1214
+
1215
+ CryptHashData(ctx->hash,
1216
+ (unsigned char *)(uintptr_t)buf,
1217
+ (DWORD)len, 0);
1218
+ }
1219
+
1220
+ void
1221
+ __la_hash_Final(unsigned char *buf, size_t bufsize, Digest_CTX *ctx)
1222
+ {
1223
+ DWORD siglen = bufsize;
1224
+
1225
+ if (!ctx->valid)
1226
+ return;
1227
+
1228
+ CryptGetHashParam(ctx->hash, HP_HASHVAL, buf, &siglen, 0);
1229
+ CryptDestroyHash(ctx->hash);
1230
+ CryptReleaseContext(ctx->cryptProv, 0);
1231
+ ctx->valid = 0;
1232
+ }
1233
+
1234
+ #endif /* defined(ARCHIVE_HASH_*_WIN) */
1235
+
1236
+ #endif /* _WIN32 && !__CYGWIN__ */