]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - libarchive/archive_write_disk_windows.c
Update libarchive's vendor dist to latest changes in release branch.
[FreeBSD/FreeBSD.git] / libarchive / archive_write_disk_windows.c
1 /*-
2  * Copyright (c) 2003-2010 Tim Kientzle
3  * Copyright (c) 2011 Michihiro NAKAJIMA
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  *    in this position and unchanged.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include "archive_platform.h"
29 __FBSDID("$FreeBSD$");
30
31 #if defined(_WIN32) && !defined(__CYGWIN__)
32
33 #ifdef HAVE_SYS_TYPES_H
34 #include <sys/types.h>
35 #endif
36 #ifdef HAVE_SYS_STAT_H
37 #include <sys/stat.h>
38 #endif
39 #ifdef HAVE_SYS_UTIME_H
40 #include <sys/utime.h>
41 #endif
42 #ifdef HAVE_ERRNO_H
43 #include <errno.h>
44 #endif
45 #ifdef HAVE_FCNTL_H
46 #include <fcntl.h>
47 #endif
48 #ifdef HAVE_LIMITS_H
49 #include <limits.h>
50 #endif
51 #include <stdio.h>
52 #ifdef HAVE_STDLIB_H
53 #include <stdlib.h>
54 #endif
55 #ifdef HAVE_STRING_H
56 #include <string.h>
57 #endif
58 #include <winioctl.h>
59
60 /* TODO: Support Mac OS 'quarantine' feature.  This is really just a
61  * standard tag to mark files that have been downloaded as "tainted".
62  * On Mac OS, we should mark the extracted files as tainted if the
63  * archive being read was tainted.  Windows has a similar feature; we
64  * should investigate ways to support this generically. */
65
66 #include "archive.h"
67 #include "archive_acl_private.h"
68 #include "archive_string.h"
69 #include "archive_entry.h"
70 #include "archive_private.h"
71
72 #ifndef O_BINARY
73 #define O_BINARY 0
74 #endif
75 #ifndef IO_REPARSE_TAG_SYMLINK
76 /* Old SDKs do not provide IO_REPARSE_TAG_SYMLINK */
77 #define IO_REPARSE_TAG_SYMLINK 0xA000000CL
78 #endif
79
80 static BOOL SetFilePointerEx_perso(HANDLE hFile,
81                              LARGE_INTEGER liDistanceToMove,
82                              PLARGE_INTEGER lpNewFilePointer,
83                              DWORD dwMoveMethod)
84 {
85         LARGE_INTEGER li;
86         li.QuadPart = liDistanceToMove.QuadPart;
87         li.LowPart = SetFilePointer(
88             hFile, li.LowPart, &li.HighPart, dwMoveMethod);
89         if(lpNewFilePointer) {
90                 lpNewFilePointer->QuadPart = li.QuadPart;
91         }
92         return li.LowPart != -1 || GetLastError() == NO_ERROR;
93 }
94
95 struct fixup_entry {
96         struct fixup_entry      *next;
97         struct archive_acl       acl;
98         mode_t                   mode;
99         int64_t                  atime;
100         int64_t                  birthtime;
101         int64_t                  mtime;
102         int64_t                  ctime;
103         unsigned long            atime_nanos;
104         unsigned long            birthtime_nanos;
105         unsigned long            mtime_nanos;
106         unsigned long            ctime_nanos;
107         unsigned long            fflags_set;
108         int                      fixup; /* bitmask of what needs fixing */
109         wchar_t                 *name;
110 };
111
112 /*
113  * We use a bitmask to track which operations remain to be done for
114  * this file.  In particular, this helps us avoid unnecessary
115  * operations when it's possible to take care of one step as a
116  * side-effect of another.  For example, mkdir() can specify the mode
117  * for the newly-created object but symlink() cannot.  This means we
118  * can skip chmod() if mkdir() succeeded, but we must explicitly
119  * chmod() if we're trying to create a directory that already exists
120  * (mkdir() failed) or if we're restoring a symlink.  Similarly, we
121  * need to verify UID/GID before trying to restore SUID/SGID bits;
122  * that verification can occur explicitly through a stat() call or
123  * implicitly because of a successful chown() call.
124  */
125 #define TODO_MODE_FORCE         0x40000000
126 #define TODO_MODE_BASE          0x20000000
127 #define TODO_SUID               0x10000000
128 #define TODO_SUID_CHECK         0x08000000
129 #define TODO_SGID               0x04000000
130 #define TODO_SGID_CHECK         0x02000000
131 #define TODO_MODE               (TODO_MODE_BASE|TODO_SUID|TODO_SGID)
132 #define TODO_TIMES              ARCHIVE_EXTRACT_TIME
133 #define TODO_OWNER              ARCHIVE_EXTRACT_OWNER
134 #define TODO_FFLAGS             ARCHIVE_EXTRACT_FFLAGS
135 #define TODO_ACLS               ARCHIVE_EXTRACT_ACL
136 #define TODO_XATTR              ARCHIVE_EXTRACT_XATTR
137 #define TODO_MAC_METADATA       ARCHIVE_EXTRACT_MAC_METADATA
138
139 struct archive_write_disk {
140         struct archive  archive;
141
142         mode_t                   user_umask;
143         struct fixup_entry      *fixup_list;
144         struct fixup_entry      *current_fixup;
145         int64_t                  user_uid;
146         int                      skip_file_set;
147         dev_t                    skip_file_dev;
148         ino_t                    skip_file_ino;
149         time_t                   start_time;
150
151         int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid);
152         void  (*cleanup_gid)(void *private);
153         void                    *lookup_gid_data;
154         int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid);
155         void  (*cleanup_uid)(void *private);
156         void                    *lookup_uid_data;
157
158         /*
159          * Full path of last file to satisfy symlink checks.
160          */
161         struct archive_wstring  path_safe;
162
163         /*
164          * Cached stat data from disk for the current entry.
165          * If this is valid, pst points to st.  Otherwise,
166          * pst is null.
167          */
168         BY_HANDLE_FILE_INFORMATION               st;
169         BY_HANDLE_FILE_INFORMATION              *pst;
170
171         /* Information about the object being restored right now. */
172         struct archive_entry    *entry; /* Entry being extracted. */
173         wchar_t                 *name; /* Name of entry, possibly edited. */
174         struct archive_wstring   _name_data; /* backing store for 'name' */
175         /* Tasks remaining for this object. */
176         int                      todo;
177         /* Tasks deferred until end-of-archive. */
178         int                      deferred;
179         /* Options requested by the client. */
180         int                      flags;
181         /* Handle for the file we're restoring. */
182         HANDLE           fh;
183         /* Current offset for writing data to the file. */
184         int64_t                  offset;
185         /* Last offset actually written to disk. */
186         int64_t                  fd_offset;
187         /* Total bytes actually written to files. */
188         int64_t                  total_bytes_written;
189         /* Maximum size of file, -1 if unknown. */
190         int64_t                  filesize;
191         /* Dir we were in before this restore; only for deep paths. */
192         int                      restore_pwd;
193         /* Mode we should use for this entry; affected by _PERM and umask. */
194         mode_t                   mode;
195         /* UID/GID to use in restoring this entry. */
196         int64_t                  uid;
197         int64_t                  gid;
198 };
199
200 /*
201  * Default mode for dirs created automatically (will be modified by umask).
202  * Note that POSIX specifies 0777 for implicity-created dirs, "modified
203  * by the process' file creation mask."
204  */
205 #define DEFAULT_DIR_MODE 0777
206 /*
207  * Dir modes are restored in two steps:  During the extraction, the permissions
208  * in the archive are modified to match the following limits.  During
209  * the post-extract fixup pass, the permissions from the archive are
210  * applied.
211  */
212 #define MINIMUM_DIR_MODE 0700
213 #define MAXIMUM_DIR_MODE 0775
214
215 static int      check_symlinks(struct archive_write_disk *);
216 static int      create_filesystem_object(struct archive_write_disk *);
217 static struct fixup_entry *current_fixup(struct archive_write_disk *, const wchar_t *pathname);
218 #if defined(HAVE_FCHDIR) && defined(PATH_MAX)
219 static void     edit_deep_directories(struct archive_write_disk *ad);
220 #endif
221 static int      cleanup_pathname(struct archive_write_disk *);
222 static int      create_dir(struct archive_write_disk *, wchar_t *);
223 static int      create_parent_dir(struct archive_write_disk *, wchar_t *);
224 static int      older(BY_HANDLE_FILE_INFORMATION *, struct archive_entry *);
225 static int      restore_entry(struct archive_write_disk *);
226 #ifdef HAVE_POSIX_ACL
227 static int      set_acl(struct archive_write_disk *, int fd, const char *, struct archive_acl *,
228                     acl_type_t, int archive_entry_acl_type, const char *tn);
229 #endif
230 static int      set_acls(struct archive_write_disk *, HANDLE h, const wchar_t *, struct archive_acl *);
231 static int      set_xattrs(struct archive_write_disk *);
232 static int      set_fflags(struct archive_write_disk *);
233 static int      set_ownership(struct archive_write_disk *);
234 static int      set_mode(struct archive_write_disk *, int mode);
235 static int      set_times(struct archive_write_disk *, HANDLE, int, const wchar_t *,
236                     time_t, long, time_t, long, time_t, long, time_t, long);
237 static int      set_times_from_entry(struct archive_write_disk *);
238 static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
239 static ssize_t  write_data_block(struct archive_write_disk *,
240                     const char *, size_t);
241
242 static struct archive_vtable *archive_write_disk_vtable(void);
243
244 static int      _archive_write_disk_close(struct archive *);
245 static int      _archive_write_disk_free(struct archive *);
246 static int      _archive_write_disk_header(struct archive *, struct archive_entry *);
247 static int64_t  _archive_write_disk_filter_bytes(struct archive *, int);
248 static int      _archive_write_disk_finish_entry(struct archive *);
249 static ssize_t  _archive_write_disk_data(struct archive *, const void *, size_t);
250 static ssize_t  _archive_write_disk_data_block(struct archive *, const void *, size_t, int64_t);
251
252 #define bhfi_dev(bhfi)  ((bhfi)->dwVolumeSerialNumber)
253 /* Treat FileIndex as i-node. We should remove a sequence number
254  * which is high-16-bits of nFileIndexHigh. */
255 #define bhfi_ino(bhfi)  \
256         ((((int64_t)((bhfi)->nFileIndexHigh & 0x0000FFFFUL)) << 32) \
257     + (bhfi)->nFileIndexLow)
258 #define bhfi_size(bhfi) \
259     ((((int64_t)(bhfi)->nFileSizeHigh) << 32) + (bhfi)->nFileSizeLow)
260
261 static int
262 file_information(struct archive_write_disk *a, wchar_t *path,
263     BY_HANDLE_FILE_INFORMATION *st, mode_t *mode, int sim_lstat)
264 {
265         HANDLE h;
266         int r;
267         DWORD flag = FILE_FLAG_BACKUP_SEMANTICS;
268         WIN32_FIND_DATAW        findData;
269
270         if (sim_lstat || mode != NULL) {
271                 h = FindFirstFileW(path, &findData);
272                 if (h == INVALID_HANDLE_VALUE &&
273                     GetLastError() == ERROR_INVALID_NAME) {
274                         wchar_t *full;
275                         full = __la_win_permissive_name_w(path);
276                         h = FindFirstFileW(full, &findData);
277                         free(full);
278                 }
279                 if (h == INVALID_HANDLE_VALUE) {
280                         la_dosmaperr(GetLastError());
281                         return (-1);
282                 }
283                 FindClose(h);
284         }
285
286         /* Is symlink file ? */
287         if (sim_lstat && 
288             ((findData.dwFileAttributes
289                         & FILE_ATTRIBUTE_REPARSE_POINT) &&
290                 (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)))
291                 flag |= FILE_FLAG_OPEN_REPARSE_POINT;
292
293         h = CreateFileW(a->name, 0, 0, NULL,
294             OPEN_EXISTING, flag, NULL);
295         if (h == INVALID_HANDLE_VALUE &&
296             GetLastError() == ERROR_INVALID_NAME) {
297                 wchar_t *full;
298                 full = __la_win_permissive_name_w(path);
299                 h = CreateFileW(full, 0, 0, NULL,
300                     OPEN_EXISTING, flag, NULL);
301                 free(full);
302         }
303         if (h == INVALID_HANDLE_VALUE) {
304                 la_dosmaperr(GetLastError());
305                 return (-1);
306         }
307         r = GetFileInformationByHandle(h, st);
308         CloseHandle(h);
309         if (r == 0) {
310                 la_dosmaperr(GetLastError());
311                 return (-1);
312         }
313
314         if (mode == NULL)
315                 return (0);
316
317         *mode = S_IRUSR | S_IRGRP | S_IROTH;
318         if ((st->dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0)
319                 *mode |= S_IWUSR | S_IWGRP | S_IWOTH;
320         if ((st->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
321             findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)
322                 *mode |= S_IFLNK;
323         else if (st->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
324                 *mode |= S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH;
325         else {
326                 const wchar_t *p;
327
328                 *mode |= S_IFREG;
329                 p = wcsrchr(path, L'.');
330                 if (p != NULL && wcslen(p) == 4) {
331                         switch (p[1]) {
332                         case L'B': case L'b':
333                                 if ((p[2] == L'A' || p[2] == L'a' ) &&
334                                     (p[3] == L'T' || p[3] == L't' ))
335                                         *mode |= S_IXUSR | S_IXGRP | S_IXOTH;
336                                 break;
337                         case L'C': case L'c':
338                                 if (((p[2] == L'M' || p[2] == L'm' ) &&
339                                     (p[3] == L'D' || p[3] == L'd' )) ||
340                                     ((p[2] == L'M' || p[2] == L'm' ) &&
341                                     (p[3] == L'D' || p[3] == L'd' )))
342                                         *mode |= S_IXUSR | S_IXGRP | S_IXOTH;
343                                 break;
344                         case L'E': case L'e':
345                                 if ((p[2] == L'X' || p[2] == L'x' ) &&
346                                     (p[3] == L'E' || p[3] == L'e' ))
347                                         *mode |= S_IXUSR | S_IXGRP | S_IXOTH;
348                                 break;
349                         default:
350                                 break;
351                         }
352                 }
353         }
354         return (0);
355 }
356
357 /* 
358  * Note: The path, for example, "aa/a/../b../c" will be converted to "aa/c"
359  * by GetFullPathNameW() W32 API, which __la_win_permissive_name_w uses.
360  * It means we cannot handle multiple dirs in one archive_entry.
361  * So we have to make the full-pathname in another way, which does not
362  * break "../" path string.
363  */
364 int
365 permissive_name_w(struct archive_write_disk *a)
366 {
367         wchar_t *wn, *wnp;
368         wchar_t *ws, *wsp;
369         DWORD l;
370
371         wnp = a->name;
372         if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
373             wnp[2] == L'?' && wnp[3] == L'\\')
374                 /* We have already a permissive name. */
375                 return (0);
376
377         if (wnp[0] == L'\\' && wnp[1] == L'\\' &&
378                 wnp[2] == L'.' && wnp[3] == L'\\') {
379                 /* This is a device name */
380                 if (((wnp[4] >= L'a' && wnp[4] <= L'z') ||
381                      (wnp[4] >= L'A' && wnp[4] <= L'Z')) &&
382                          wnp[5] == L':' && wnp[6] == L'\\') {
383                         wnp[2] = L'?';/* Not device name. */
384                         return (0);
385                 }
386         }
387
388         /*
389          * A full-pathname starting with a drive name like "C:\abc".
390          */
391         if (((wnp[0] >= L'a' && wnp[0] <= L'z') ||
392              (wnp[0] >= L'A' && wnp[0] <= L'Z')) &&
393                  wnp[1] == L':' && wnp[2] == L'\\') {
394                 wn = _wcsdup(wnp);
395                 if (wn == NULL)
396                         return (-1);
397                 archive_wstring_ensure(&(a->_name_data), 4 + wcslen(wn) + 1);
398                 a->name = a->_name_data.s;
399                 /* Prepend "\\?\" */
400                 archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
401                 archive_wstrcat(&(a->_name_data), wn);
402                 free(wn);
403                 return (0);
404         }
405
406         /*
407          * A full-pathname pointig a network drive
408          * like "\\<server-name>\<share-name>\file". 
409          */
410         if (wnp[0] == L'\\' && wnp[1] == L'\\' && wnp[2] != L'\\') {
411                 const wchar_t *p = &wnp[2];
412
413                 /* Skip server-name letters. */
414                 while (*p != L'\\' && *p != L'\0')
415                         ++p;
416                 if (*p == L'\\') {
417                         const wchar_t *rp = ++p;
418                         /* Skip share-name letters. */
419                         while (*p != L'\\' && *p != L'\0')
420                                 ++p;
421                         if (*p == L'\\' && p != rp) {
422                                 /* Now, match patterns such as
423                                  * "\\server-name\share-name\" */
424                                 wn = _wcsdup(wnp);
425                                 if (wn == NULL)
426                                         return (-1);
427                                 archive_wstring_ensure(&(a->_name_data), 8 + wcslen(wn) + 1);
428                                 a->name = a->_name_data.s;
429                                 /* Prepend "\\?\UNC\" */
430                                 archive_wstrncpy(&(a->_name_data), L"\\\\?\\UNC\\", 8);
431                                 archive_wstrcat(&(a->_name_data), wn+2);
432                                 free(wn);
433                                 return (0);
434                         }
435                 }
436                 return (0);
437         }
438
439         /*
440          * Get current working directory.
441          */
442         l = GetCurrentDirectoryW(0, NULL);
443         if (l == 0)
444                 return (-1);
445         ws = malloc(l * sizeof(wchar_t));
446         l = GetCurrentDirectoryW(l, ws);
447         if (l == 0) {
448                 free(ws);
449                 return (-1);
450         }
451         wsp = ws;
452
453         /*
454          * A full-pathname starting without a drive name like "\abc".
455          */
456         if (wnp[0] == L'\\') {
457                 wn = _wcsdup(wnp);
458                 if (wn == NULL)
459                         return (-1);
460                 archive_wstring_ensure(&(a->_name_data), 4 + 2 + wcslen(wn) + 1);
461                 a->name = a->_name_data.s;
462                 /* Prepend "\\?\" and drive name. */
463                 archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
464                 archive_wstrncat(&(a->_name_data), wsp, 2);
465                 archive_wstrcat(&(a->_name_data), wn);
466                 free(wsp);
467                 free(wn);
468                 return (0);
469         }
470
471         wn = _wcsdup(wnp);
472         if (wn == NULL)
473                 return (-1);
474         archive_wstring_ensure(&(a->_name_data), 4 + l + 1 + wcslen(wn) + 1);
475         a->name = a->_name_data.s;
476         /* Prepend "\\?\" and drive name. */
477         archive_wstrncpy(&(a->_name_data), L"\\\\?\\", 4);
478         archive_wstrncat(&(a->_name_data), wsp, l);
479         archive_wstrncat(&(a->_name_data), L"\\", 1);
480         archive_wstrcat(&(a->_name_data), wn);
481         a->name = a->_name_data.s;
482         free(wsp);
483         free(wn);
484         return (0);
485 }
486
487 int
488 la_chmod(const wchar_t *path, mode_t mode)
489 {
490         DWORD attr;
491         BOOL r;
492         wchar_t *fullname;
493         int ret = 0;
494
495         fullname = NULL;
496         attr = GetFileAttributesW(path);
497         if (attr == (DWORD)-1 &&
498             GetLastError() == ERROR_INVALID_NAME) {
499                 fullname = __la_win_permissive_name_w(path);
500                 attr = GetFileAttributesW(fullname);
501         }
502         if (attr == (DWORD)-1) {
503                 la_dosmaperr(GetLastError());
504                 ret = -1;
505                 goto exit_chmode;
506         }
507         if (mode & _S_IWRITE)
508                 attr &= ~FILE_ATTRIBUTE_READONLY;
509         else
510                 attr |= FILE_ATTRIBUTE_READONLY;
511         if (fullname != NULL)
512                 r = SetFileAttributesW(fullname, attr);
513         else
514                 r = SetFileAttributesW(path, attr);
515         if (r == 0) {
516                 la_dosmaperr(GetLastError());
517                 ret = -1;
518         }
519 exit_chmode:
520         free(fullname);
521         return (ret);
522 }
523
524 static void *
525 la_GetFunctionKernel32(const char *name)
526 {
527         static HINSTANCE lib;
528         static int set;
529         if (!set) {
530                 set = 1;
531                 lib = LoadLibrary("kernel32.dll");
532         }
533         if (lib == NULL) {
534                 fprintf(stderr, "Can't load kernel32.dll?!\n");
535                 exit(1);
536         }
537         return (void *)GetProcAddress(lib, name);
538 }
539
540 static int
541 la_CreateHardLinkW(wchar_t *linkname, wchar_t *target)
542 {
543         static BOOLEAN (WINAPI *f)(LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES);
544         static int set;
545         BOOL ret;
546
547         if (!set) {
548                 set = 1;
549                 f = la_GetFunctionKernel32("CreateHardLinkW");
550         }
551         if (!f)
552                 return (0);
553         ret = (*f)(linkname, target, NULL);
554         if (!ret) {
555                 /* Under windows 2000, it is necessary to remove
556                  * the "\\?\" prefix. */
557 #define IS_UNC(name)    ((name[0] == L'U' || name[0] == L'u') &&        \
558                          (name[1] == L'N' || name[1] == L'n') &&        \
559                          (name[2] == L'C' || name[2] == L'c') &&        \
560                          name[3] == L'\\')
561                 if (!wcsncmp(linkname,L"\\\\?\\", 4)) {
562                         linkname += 4;
563                         if (IS_UNC(linkname))
564                                 linkname += 4;
565                 }
566                 if (!wcsncmp(target,L"\\\\?\\", 4)) {
567                         target += 4;
568                         if (IS_UNC(target))
569                                 target += 4;
570                 }
571 #undef IS_UNC
572                 ret = (*f)(linkname, target, NULL);
573         }
574         return (ret);
575 }
576
577 static int
578 la_ftruncate(HANDLE handle, int64_t length)
579 {
580         LARGE_INTEGER distance;
581
582         if (GetFileType(handle) != FILE_TYPE_DISK) {
583                 errno = EBADF;
584                 return (-1);
585         }
586         distance.QuadPart = length;
587         if (!SetFilePointerEx_perso(handle, distance, NULL, FILE_BEGIN)) {
588                 la_dosmaperr(GetLastError());
589                 return (-1);
590         }
591         if (!SetEndOfFile(handle)) {
592                 la_dosmaperr(GetLastError());
593                 return (-1);
594         }
595         return (0);
596 }
597
598 static int
599 lazy_stat(struct archive_write_disk *a)
600 {
601         if (a->pst != NULL) {
602                 /* Already have stat() data available. */
603                 return (ARCHIVE_OK);
604         }
605         if (a->fh != INVALID_HANDLE_VALUE &&
606             GetFileInformationByHandle(a->fh, &a->st) == 0) {
607                 a->pst = &a->st;
608                 return (ARCHIVE_OK);
609         }
610
611         /*
612          * XXX At this point, symlinks should not be hit, otherwise
613          * XXX a race occurred.  Do we want to check explicitly for that?
614          */
615         if (file_information(a, a->name, &a->st, NULL, 1) == 0) {
616                 a->pst = &a->st;
617                 return (ARCHIVE_OK);
618         }
619         archive_set_error(&a->archive, errno, "Couldn't stat file");
620         return (ARCHIVE_WARN);
621 }
622
623 static struct archive_vtable *
624 archive_write_disk_vtable(void)
625 {
626         static struct archive_vtable av;
627         static int inited = 0;
628
629         if (!inited) {
630                 av.archive_close = _archive_write_disk_close;
631                 av.archive_filter_bytes = _archive_write_disk_filter_bytes;
632                 av.archive_free = _archive_write_disk_free;
633                 av.archive_write_header = _archive_write_disk_header;
634                 av.archive_write_finish_entry
635                     = _archive_write_disk_finish_entry;
636                 av.archive_write_data = _archive_write_disk_data;
637                 av.archive_write_data_block = _archive_write_disk_data_block;
638                 inited = 1;
639         }
640         return (&av);
641 }
642
643 static int64_t
644 _archive_write_disk_filter_bytes(struct archive *_a, int n)
645 {
646         struct archive_write_disk *a = (struct archive_write_disk *)_a;
647         (void)n; /* UNUSED */
648         if (n == -1 || n == 0)
649                 return (a->total_bytes_written);
650         return (-1);
651 }
652
653
654 int
655 archive_write_disk_set_options(struct archive *_a, int flags)
656 {
657         struct archive_write_disk *a = (struct archive_write_disk *)_a;
658
659         a->flags = flags;
660         return (ARCHIVE_OK);
661 }
662
663
664 /*
665  * Extract this entry to disk.
666  *
667  * TODO: Validate hardlinks.  According to the standards, we're
668  * supposed to check each extracted hardlink and squawk if it refers
669  * to a file that we didn't restore.  I'm not entirely convinced this
670  * is a good idea, but more importantly: Is there any way to validate
671  * hardlinks without keeping a complete list of filenames from the
672  * entire archive?? Ugh.
673  *
674  */
675 static int
676 _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
677 {
678         struct archive_write_disk *a = (struct archive_write_disk *)_a;
679         struct fixup_entry *fe;
680         int ret, r;
681
682         archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
683             ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
684             "archive_write_disk_header");
685         archive_clear_error(&a->archive);
686         if (a->archive.state & ARCHIVE_STATE_DATA) {
687                 r = _archive_write_disk_finish_entry(&a->archive);
688                 if (r == ARCHIVE_FATAL)
689                         return (r);
690         }
691
692         /* Set up for this particular entry. */
693         a->pst = NULL;
694         a->current_fixup = NULL;
695         a->deferred = 0;
696         if (a->entry) {
697                 archive_entry_free(a->entry);
698                 a->entry = NULL;
699         }
700         a->entry = archive_entry_clone(entry);
701         a->fh = INVALID_HANDLE_VALUE;
702         a->fd_offset = 0;
703         a->offset = 0;
704         a->restore_pwd = -1;
705         a->uid = a->user_uid;
706         a->mode = archive_entry_mode(a->entry);
707         if (archive_entry_size_is_set(a->entry))
708                 a->filesize = archive_entry_size(a->entry);
709         else
710                 a->filesize = -1;
711         archive_wstrcpy(&(a->_name_data), archive_entry_pathname_w(a->entry));
712         a->name = a->_name_data.s;
713         archive_clear_error(&a->archive);
714
715         /*
716          * Clean up the requested path.  This is necessary for correct
717          * dir restores; the dir restore logic otherwise gets messed
718          * up by nonsense like "dir/.".
719          */
720         ret = cleanup_pathname(a);
721         if (ret != ARCHIVE_OK)
722                 return (ret);
723
724         /*
725          * Generate a full-pathname and use it from here.
726          */
727         if (permissive_name_w(a) < 0) {
728                 errno = EINVAL;
729                 return (ARCHIVE_FAILED);
730         }
731
732         /*
733          * Query the umask so we get predictable mode settings.
734          * This gets done on every call to _write_header in case the
735          * user edits their umask during the extraction for some
736          * reason.
737          */
738         umask(a->user_umask = umask(0));
739
740         /* Figure out what we need to do for this entry. */
741         a->todo = TODO_MODE_BASE;
742         if (a->flags & ARCHIVE_EXTRACT_PERM) {
743                 a->todo |= TODO_MODE_FORCE; /* Be pushy about permissions. */
744                 /*
745                  * SGID requires an extra "check" step because we
746                  * cannot easily predict the GID that the system will
747                  * assign.  (Different systems assign GIDs to files
748                  * based on a variety of criteria, including process
749                  * credentials and the gid of the enclosing
750                  * directory.)  We can only restore the SGID bit if
751                  * the file has the right GID, and we only know the
752                  * GID if we either set it (see set_ownership) or if
753                  * we've actually called stat() on the file after it
754                  * was restored.  Since there are several places at
755                  * which we might verify the GID, we need a TODO bit
756                  * to keep track.
757                  */
758                 if (a->mode & S_ISGID)
759                         a->todo |= TODO_SGID | TODO_SGID_CHECK;
760                 /*
761                  * Verifying the SUID is simpler, but can still be
762                  * done in multiple ways, hence the separate "check" bit.
763                  */
764                 if (a->mode & S_ISUID)
765                         a->todo |= TODO_SUID | TODO_SUID_CHECK;
766         } else {
767                 /*
768                  * User didn't request full permissions, so don't
769                  * restore SUID, SGID bits and obey umask.
770                  */
771                 a->mode &= ~S_ISUID;
772                 a->mode &= ~S_ISGID;
773                 a->mode &= ~S_ISVTX;
774                 a->mode &= ~a->user_umask;
775         }
776 #if 0
777         if (a->flags & ARCHIVE_EXTRACT_OWNER)
778                 a->todo |= TODO_OWNER;
779 #endif
780         if (a->flags & ARCHIVE_EXTRACT_TIME)
781                 a->todo |= TODO_TIMES;
782         if (a->flags & ARCHIVE_EXTRACT_ACL) {
783                 if (archive_entry_filetype(a->entry) == AE_IFDIR)
784                         a->deferred |= TODO_ACLS;
785                 else
786                         a->todo |= TODO_ACLS;
787         }
788         if (a->flags & ARCHIVE_EXTRACT_XATTR)
789                 a->todo |= TODO_XATTR;
790         if (a->flags & ARCHIVE_EXTRACT_FFLAGS)
791                 a->todo |= TODO_FFLAGS;
792         if (a->flags & ARCHIVE_EXTRACT_SECURE_SYMLINKS) {
793                 ret = check_symlinks(a);
794                 if (ret != ARCHIVE_OK)
795                         return (ret);
796         }
797
798         ret = restore_entry(a);
799
800         /*
801          * TODO: There are rumours that some extended attributes must
802          * be restored before file data is written.  If this is true,
803          * then we either need to write all extended attributes both
804          * before and after restoring the data, or find some rule for
805          * determining which must go first and which last.  Due to the
806          * many ways people are using xattrs, this may prove to be an
807          * intractable problem.
808          */
809
810         /*
811          * Fixup uses the unedited pathname from archive_entry_pathname(),
812          * because it is relative to the base dir and the edited path
813          * might be relative to some intermediate dir as a result of the
814          * deep restore logic.
815          */
816         if (a->deferred & TODO_MODE) {
817                 fe = current_fixup(a, archive_entry_pathname_w(entry));
818                 fe->fixup |= TODO_MODE_BASE;
819                 fe->mode = a->mode;
820         }
821
822         if ((a->deferred & TODO_TIMES)
823                 && (archive_entry_mtime_is_set(entry)
824                     || archive_entry_atime_is_set(entry))) {
825                 fe = current_fixup(a, archive_entry_pathname_w(entry));
826                 fe->mode = a->mode;
827                 fe->fixup |= TODO_TIMES;
828                 if (archive_entry_atime_is_set(entry)) {
829                         fe->atime = archive_entry_atime(entry);
830                         fe->atime_nanos = archive_entry_atime_nsec(entry);
831                 } else {
832                         /* If atime is unset, use start time. */
833                         fe->atime = a->start_time;
834                         fe->atime_nanos = 0;
835                 }
836                 if (archive_entry_mtime_is_set(entry)) {
837                         fe->mtime = archive_entry_mtime(entry);
838                         fe->mtime_nanos = archive_entry_mtime_nsec(entry);
839                 } else {
840                         /* If mtime is unset, use start time. */
841                         fe->mtime = a->start_time;
842                         fe->mtime_nanos = 0;
843                 }
844                 if (archive_entry_birthtime_is_set(entry)) {
845                         fe->birthtime = archive_entry_birthtime(entry);
846                         fe->birthtime_nanos = archive_entry_birthtime_nsec(entry);
847                 } else {
848                         /* If birthtime is unset, use mtime. */
849                         fe->birthtime = fe->mtime;
850                         fe->birthtime_nanos = fe->mtime_nanos;
851                 }
852         }
853
854         if (a->deferred & TODO_ACLS) {
855                 fe = current_fixup(a, archive_entry_pathname_w(entry));
856                 archive_acl_copy(&fe->acl, archive_entry_acl(entry));
857         }
858
859         if (a->deferred & TODO_FFLAGS) {
860                 fe = current_fixup(a, archive_entry_pathname_w(entry));
861                 fe->fixup |= TODO_FFLAGS;
862                 /* TODO: Complete this.. defer fflags from below. */
863         }
864
865         /*
866          * On Windows, A creating sparse file requires a special mark.
867          */
868         if (a->fh != INVALID_HANDLE_VALUE &&
869             archive_entry_sparse_count(entry) > 0) {
870                 int64_t base = 0, offset, length;
871                 int i, cnt = archive_entry_sparse_reset(entry);
872                 int sparse = 0;
873
874                 for (i = 0; i < cnt; i++) {
875                         archive_entry_sparse_next(entry, &offset, &length);
876                         if (offset - base >= 4096) {
877                                 sparse = 1;/* we have a hole. */
878                                 break;
879                         }
880                         base = offset + length;
881                 }
882                 if (sparse) {
883                         DWORD dmy;
884                         /* Mark this file as sparse. */
885                         DeviceIoControl(a->fh, FSCTL_SET_SPARSE,
886                             NULL, 0, NULL, 0, &dmy, NULL);
887                 }
888         }
889
890         /* We've created the object and are ready to pour data into it. */
891         if (ret >= ARCHIVE_WARN)
892                 a->archive.state = ARCHIVE_STATE_DATA;
893         /*
894          * If it's not open, tell our client not to try writing.
895          * In particular, dirs, links, etc, don't get written to.
896          */
897         if (a->fh == INVALID_HANDLE_VALUE) {
898                 archive_entry_set_size(entry, 0);
899                 a->filesize = 0;
900         }
901
902         return (ret);
903 }
904
905 int
906 archive_write_disk_set_skip_file(struct archive *_a, int64_t d, int64_t i)
907 {
908         struct archive_write_disk *a = (struct archive_write_disk *)_a;
909         archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
910             ARCHIVE_STATE_ANY, "archive_write_disk_set_skip_file");
911         a->skip_file_set = 1;
912         a->skip_file_dev = d;
913         a->skip_file_ino = i;
914         return (ARCHIVE_OK);
915 }
916
917 static ssize_t
918 write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
919 {
920         uint64_t start_size = size;
921         DWORD bytes_written = 0;
922         ssize_t block_size = 0, bytes_to_write;
923
924         if (size == 0)
925                 return (ARCHIVE_OK);
926
927         if (a->filesize == 0 || a->fh == INVALID_HANDLE_VALUE) {
928                 archive_set_error(&a->archive, 0,
929                     "Attempt to write to an empty file");
930                 return (ARCHIVE_WARN);
931         }
932
933         if (a->flags & ARCHIVE_EXTRACT_SPARSE) {
934                 /* XXX TODO XXX Is there a more appropriate choice here ? */
935                 /* This needn't match the filesystem allocation size. */
936                 block_size = 16*1024;
937         }
938
939         /* If this write would run beyond the file size, truncate it. */
940         if (a->filesize >= 0 && (int64_t)(a->offset + size) > a->filesize)
941                 start_size = size = (size_t)(a->filesize - a->offset);
942
943         /* Write the data. */
944         while (size > 0) {
945                 if (block_size == 0) {
946                         bytes_to_write = size;
947                 } else {
948                         /* We're sparsifying the file. */
949                         const char *p, *end;
950                         int64_t block_end;
951
952                         /* Skip leading zero bytes. */
953                         for (p = buff, end = buff + size; p < end; ++p) {
954                                 if (*p != '\0')
955                                         break;
956                         }
957                         a->offset += p - buff;
958                         size -= p - buff;
959                         buff = p;
960                         if (size == 0)
961                                 break;
962
963                         /* Calculate next block boundary after offset. */
964                         block_end
965                             = (a->offset / block_size + 1) * block_size;
966
967                         /* If the adjusted write would cross block boundary,
968                          * truncate it to the block boundary. */
969                         bytes_to_write = size;
970                         if (a->offset + bytes_to_write > block_end)
971                                 bytes_to_write = block_end - a->offset;
972                 }
973                 /* Seek if necessary to the specified offset. */
974                 if (a->offset != a->fd_offset) {
975                         LARGE_INTEGER distance;
976                         distance.QuadPart = a->offset;
977                         if (SetFilePointerEx_perso(a->fh, distance, NULL, FILE_BEGIN) == 0) {
978                                 DWORD lasterr = GetLastError();
979                                 if (lasterr == ERROR_ACCESS_DENIED)
980                                         errno = EBADF;
981                                 else
982                                         la_dosmaperr(lasterr);
983                                 archive_set_error(&a->archive, errno,
984                                     "Seek failed");
985                                 return (ARCHIVE_FATAL);
986                         }
987                         a->fd_offset = a->offset;
988                 }
989                 if (!WriteFile(a->fh, buff, (uint32_t)bytes_to_write,
990                     &bytes_written, NULL)) {
991                         DWORD lasterr;
992
993                         lasterr = GetLastError();
994                         if (lasterr == ERROR_ACCESS_DENIED)
995                                 errno = EBADF;
996                         else
997                                 la_dosmaperr(lasterr);
998                         archive_set_error(&a->archive, errno, "Write failed");
999                         return (ARCHIVE_WARN);
1000                 }
1001                 buff += bytes_written;
1002                 size -= bytes_written;
1003                 a->total_bytes_written += bytes_written;
1004                 a->offset += bytes_written;
1005                 a->fd_offset = a->offset;
1006         }
1007         return (start_size - size);
1008 }
1009
1010 static ssize_t
1011 _archive_write_disk_data_block(struct archive *_a,
1012     const void *buff, size_t size, int64_t offset)
1013 {
1014         struct archive_write_disk *a = (struct archive_write_disk *)_a;
1015         ssize_t r;
1016
1017         archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
1018             ARCHIVE_STATE_DATA, "archive_write_data_block");
1019
1020         a->offset = offset;
1021         r = write_data_block(a, buff, size);
1022         if (r < ARCHIVE_OK)
1023                 return (r);
1024         if ((size_t)r < size) {
1025                 archive_set_error(&a->archive, 0,
1026                     "Write request too large");
1027                 return (ARCHIVE_WARN);
1028         }
1029         return (ARCHIVE_OK);
1030 }
1031
1032 static ssize_t
1033 _archive_write_disk_data(struct archive *_a, const void *buff, size_t size)
1034 {
1035         struct archive_write_disk *a = (struct archive_write_disk *)_a;
1036
1037         archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
1038             ARCHIVE_STATE_DATA, "archive_write_data");
1039
1040         return (write_data_block(a, buff, size));
1041 }
1042
1043 static int
1044 _archive_write_disk_finish_entry(struct archive *_a)
1045 {
1046         struct archive_write_disk *a = (struct archive_write_disk *)_a;
1047         int ret = ARCHIVE_OK;
1048
1049         archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
1050             ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
1051             "archive_write_finish_entry");
1052         if (a->archive.state & ARCHIVE_STATE_HEADER)
1053                 return (ARCHIVE_OK);
1054         archive_clear_error(&a->archive);
1055
1056         /* Pad or truncate file to the right size. */
1057         if (a->fh == INVALID_HANDLE_VALUE) {
1058                 /* There's no file. */
1059         } else if (a->filesize < 0) {
1060                 /* File size is unknown, so we can't set the size. */
1061         } else if (a->fd_offset == a->filesize) {
1062                 /* Last write ended at exactly the filesize; we're done. */
1063                 /* Hopefully, this is the common case. */
1064         } else {
1065                 if (la_ftruncate(a->fh, a->filesize) == -1) {
1066                         archive_set_error(&a->archive, errno,
1067                             "File size could not be restored");
1068                         return (ARCHIVE_FAILED);
1069                 }
1070         }
1071
1072         /* Restore metadata. */
1073
1074         /*
1075          * Look up the "real" UID only if we're going to need it.
1076          * TODO: the TODO_SGID condition can be dropped here, can't it?
1077          */
1078         if (a->todo & (TODO_OWNER | TODO_SUID | TODO_SGID)) {
1079                 a->uid = archive_write_disk_uid(&a->archive,
1080                     archive_entry_uname(a->entry),
1081                     archive_entry_uid(a->entry));
1082         }
1083         /* Look up the "real" GID only if we're going to need it. */
1084         /* TODO: the TODO_SUID condition can be dropped here, can't it? */
1085         if (a->todo & (TODO_OWNER | TODO_SGID | TODO_SUID)) {
1086                 a->gid = archive_write_disk_gid(&a->archive,
1087                     archive_entry_gname(a->entry),
1088                     archive_entry_gid(a->entry));
1089          }
1090
1091         /*
1092          * Restore ownership before set_mode tries to restore suid/sgid
1093          * bits.  If we set the owner, we know what it is and can skip
1094          * a stat() call to examine the ownership of the file on disk.
1095          */
1096         if (a->todo & TODO_OWNER)
1097                 ret = set_ownership(a);
1098
1099         /*
1100          * set_mode must precede ACLs on systems such as Solaris and
1101          * FreeBSD where setting the mode implicitly clears extended ACLs
1102          */
1103         if (a->todo & TODO_MODE) {
1104                 int r2 = set_mode(a, a->mode);
1105                 if (r2 < ret) ret = r2;
1106         }
1107
1108         /*
1109          * Security-related extended attributes (such as
1110          * security.capability on Linux) have to be restored last,
1111          * since they're implicitly removed by other file changes.
1112          */
1113         if (a->todo & TODO_XATTR) {
1114                 int r2 = set_xattrs(a);
1115                 if (r2 < ret) ret = r2;
1116         }
1117
1118         /*
1119          * Some flags prevent file modification; they must be restored after
1120          * file contents are written.
1121          */
1122         if (a->todo & TODO_FFLAGS) {
1123                 int r2 = set_fflags(a);
1124                 if (r2 < ret) ret = r2;
1125         }
1126
1127         /*
1128          * Time must follow most other metadata;
1129          * otherwise atime will get changed.
1130          */
1131         if (a->todo & TODO_TIMES) {
1132                 int r2 = set_times_from_entry(a);
1133                 if (r2 < ret) ret = r2;
1134         }
1135
1136         /*
1137          * ACLs must be restored after timestamps because there are
1138          * ACLs that prevent attribute changes (including time).
1139          */
1140         if (a->todo & TODO_ACLS) {
1141                 int r2 = set_acls(a, a->fh,
1142                                   archive_entry_pathname_w(a->entry),
1143                                   archive_entry_acl(a->entry));
1144                 if (r2 < ret) ret = r2;
1145         }
1146
1147         /* If there's an fd, we can close it now. */
1148         if (a->fh != INVALID_HANDLE_VALUE) {
1149                 CloseHandle(a->fh);
1150                 a->fh = INVALID_HANDLE_VALUE;
1151         }
1152         /* If there's an entry, we can release it now. */
1153         if (a->entry) {
1154                 archive_entry_free(a->entry);
1155                 a->entry = NULL;
1156         }
1157         a->archive.state = ARCHIVE_STATE_HEADER;
1158         return (ret);
1159 }
1160
1161 int
1162 archive_write_disk_set_group_lookup(struct archive *_a,
1163     void *private_data,
1164     int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid),
1165     void (*cleanup_gid)(void *private))
1166 {
1167         struct archive_write_disk *a = (struct archive_write_disk *)_a;
1168         archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
1169             ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup");
1170
1171         if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
1172                 (a->cleanup_gid)(a->lookup_gid_data);
1173
1174         a->lookup_gid = lookup_gid;
1175         a->cleanup_gid = cleanup_gid;
1176         a->lookup_gid_data = private_data;
1177         return (ARCHIVE_OK);
1178 }
1179
1180 int
1181 archive_write_disk_set_user_lookup(struct archive *_a,
1182     void *private_data,
1183     int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid),
1184     void (*cleanup_uid)(void *private))
1185 {
1186         struct archive_write_disk *a = (struct archive_write_disk *)_a;
1187         archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
1188             ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup");
1189
1190         if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
1191                 (a->cleanup_uid)(a->lookup_uid_data);
1192
1193         a->lookup_uid = lookup_uid;
1194         a->cleanup_uid = cleanup_uid;
1195         a->lookup_uid_data = private_data;
1196         return (ARCHIVE_OK);
1197 }
1198
1199 int64_t
1200 archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
1201 {
1202        struct archive_write_disk *a = (struct archive_write_disk *)_a;
1203        archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
1204            ARCHIVE_STATE_ANY, "archive_write_disk_gid");
1205        if (a->lookup_gid)
1206                return (a->lookup_gid)(a->lookup_gid_data, name, id);
1207        return (id);
1208 }
1209  
1210 int64_t
1211 archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
1212 {
1213        struct archive_write_disk *a = (struct archive_write_disk *)_a;
1214        archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
1215            ARCHIVE_STATE_ANY, "archive_write_disk_uid");
1216        if (a->lookup_uid)
1217                return (a->lookup_uid)(a->lookup_uid_data, name, id);
1218        return (id);
1219 }
1220
1221 /*
1222  * Create a new archive_write_disk object and initialize it with global state.
1223  */
1224 struct archive *
1225 archive_write_disk_new(void)
1226 {
1227         struct archive_write_disk *a;
1228
1229         a = (struct archive_write_disk *)malloc(sizeof(*a));
1230         if (a == NULL)
1231                 return (NULL);
1232         memset(a, 0, sizeof(*a));
1233         a->archive.magic = ARCHIVE_WRITE_DISK_MAGIC;
1234         /* We're ready to write a header immediately. */
1235         a->archive.state = ARCHIVE_STATE_HEADER;
1236         a->archive.vtable = archive_write_disk_vtable();
1237         a->start_time = time(NULL);
1238         /* Query and restore the umask. */
1239         umask(a->user_umask = umask(0));
1240         if (archive_wstring_ensure(&a->path_safe, 512) == NULL) {
1241                 free(a);
1242                 return (NULL);
1243         }
1244         return (&a->archive);
1245 }
1246
1247 static int
1248 disk_unlink(wchar_t *path)
1249 {
1250         wchar_t *fullname;
1251         int r;
1252
1253         r = _wunlink(path);
1254         if (r != 0 && GetLastError() == ERROR_INVALID_NAME) {
1255                 fullname = __la_win_permissive_name_w(path);
1256                 r = _wunlink(fullname);
1257                 free(fullname);
1258         }
1259         return (r);
1260 }
1261
1262 static int
1263 disk_rmdir(wchar_t *path)
1264 {
1265         wchar_t *fullname;
1266         int r;
1267
1268         r = _wrmdir(path);
1269         if (r != 0 && GetLastError() == ERROR_INVALID_NAME) {
1270                 fullname = __la_win_permissive_name_w(path);
1271                 r = _wrmdir(fullname);
1272                 free(fullname);
1273         }
1274         return (r);
1275 }
1276
1277 /*
1278  * The main restore function.
1279  */
1280 static int
1281 restore_entry(struct archive_write_disk *a)
1282 {
1283         int ret = ARCHIVE_OK, en;
1284
1285         if (a->flags & ARCHIVE_EXTRACT_UNLINK && !S_ISDIR(a->mode)) {
1286                 /*
1287                  * TODO: Fix this.  Apparently, there are platforms
1288                  * that still allow root to hose the entire filesystem
1289                  * by unlinking a dir.  The S_ISDIR() test above
1290                  * prevents us from using unlink() here if the new
1291                  * object is a dir, but that doesn't mean the old
1292                  * object isn't a dir.
1293                  */
1294                 if (disk_unlink(a->name) == 0) {
1295                         /* We removed it, reset cached stat. */
1296                         a->pst = NULL;
1297                 } else if (errno == ENOENT) {
1298                         /* File didn't exist, that's just as good. */
1299                 } else if (disk_rmdir(a->name) == 0) {
1300                         /* It was a dir, but now it's gone. */
1301                         a->pst = NULL;
1302                 } else {
1303                         /* We tried, but couldn't get rid of it. */
1304                         archive_set_error(&a->archive, errno,
1305                             "Could not unlink");
1306                         return(ARCHIVE_FAILED);
1307                 }
1308         }
1309
1310         /* Try creating it first; if this fails, we'll try to recover. */
1311         en = create_filesystem_object(a);
1312
1313         if ((en == ENOTDIR || en == ENOENT)
1314             && !(a->flags & ARCHIVE_EXTRACT_NO_AUTODIR)) {
1315                 wchar_t *full;
1316                 /* If the parent dir doesn't exist, try creating it. */
1317                 create_parent_dir(a, a->name);
1318                 /* Now try to create the object again. */
1319                 full = __la_win_permissive_name_w(a->name);
1320                 if (full == NULL) {
1321                         en = EINVAL;
1322                 } else {
1323                         /* Remove multiple directories such as "a/../b../c" */
1324                         archive_wstrcpy(&(a->_name_data), full);
1325                         a->name = a->_name_data.s;
1326                         free(full);
1327                         en = create_filesystem_object(a);
1328                 }
1329         }
1330
1331         if ((en == EISDIR || en == EEXIST)
1332             && (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
1333                 /* If we're not overwriting, we're done. */
1334                 archive_entry_unset_size(a->entry);
1335                 return (ARCHIVE_OK);
1336         }
1337
1338         /*
1339          * Some platforms return EISDIR if you call
1340          * open(O_WRONLY | O_EXCL | O_CREAT) on a directory, some
1341          * return EEXIST.  POSIX is ambiguous, requiring EISDIR
1342          * for open(O_WRONLY) on a dir and EEXIST for open(O_EXCL | O_CREAT)
1343          * on an existing item.
1344          */
1345         if (en == EISDIR) {
1346                 /* A dir is in the way of a non-dir, rmdir it. */
1347                 if (disk_rmdir(a->name) != 0) {
1348                         archive_set_error(&a->archive, errno,
1349                             "Can't remove already-existing dir");
1350                         return (ARCHIVE_FAILED);
1351                 }
1352                 a->pst = NULL;
1353                 /* Try again. */
1354                 en = create_filesystem_object(a);
1355         } else if (en == EEXIST) {
1356                 mode_t st_mode;
1357                 /*
1358                  * We know something is in the way, but we don't know what;
1359                  * we need to find out before we go any further.
1360                  */
1361                 int r = 0;
1362                 /*
1363                  * The SECURE_SYMLINK logic has already removed a
1364                  * symlink to a dir if the client wants that.  So
1365                  * follow the symlink if we're creating a dir.
1366                  */
1367                 if (S_ISDIR(a->mode))
1368                         r = file_information(a, a->name, &a->st, &st_mode, 0);
1369                 /*
1370                  * If it's not a dir (or it's a broken symlink),
1371                  * then don't follow it.
1372                  */
1373                 if (r != 0 || !S_ISDIR(a->mode))
1374                         r = file_information(a, a->name, &a->st, &st_mode, 1);
1375                 if (r != 0) {
1376                         archive_set_error(&a->archive, errno,
1377                             "Can't stat existing object");
1378                         return (ARCHIVE_FAILED);
1379                 }
1380
1381                 /*
1382                  * NO_OVERWRITE_NEWER doesn't apply to directories.
1383                  */
1384                 if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER)
1385                     &&  !S_ISDIR(st_mode)) {
1386                         if (!older(&(a->st), a->entry)) {
1387                                 archive_entry_unset_size(a->entry);
1388                                 return (ARCHIVE_OK);
1389                         }
1390                 }
1391
1392                 /* If it's our archive, we're done. */
1393                 if (a->skip_file_set &&
1394                     bhfi_dev(&a->st) == a->skip_file_dev &&
1395                     bhfi_ino(&a->st) == a->skip_file_ino) {
1396                         archive_set_error(&a->archive, 0, "Refusing to overwrite archive");
1397                         return (ARCHIVE_FAILED);
1398                 }
1399
1400                 if (!S_ISDIR(st_mode)) {
1401                         /* A non-dir is in the way, unlink it. */
1402                         if (disk_unlink(a->name) != 0) {
1403                                 archive_set_error(&a->archive, errno,
1404                                     "Can't unlink already-existing object");
1405                                 return (ARCHIVE_FAILED);
1406                         }
1407                         a->pst = NULL;
1408                         /* Try again. */
1409                         en = create_filesystem_object(a);
1410                 } else if (!S_ISDIR(a->mode)) {
1411                         /* A dir is in the way of a non-dir, rmdir it. */
1412                         if (disk_rmdir(a->name) != 0) {
1413                                 archive_set_error(&a->archive, errno,
1414                                     "Can't remove already-existing dir");
1415                                 return (ARCHIVE_FAILED);
1416                         }
1417                         /* Try again. */
1418                         en = create_filesystem_object(a);
1419                 } else {
1420                         /*
1421                          * There's a dir in the way of a dir.  Don't
1422                          * waste time with rmdir()/mkdir(), just fix
1423                          * up the permissions on the existing dir.
1424                          * Note that we don't change perms on existing
1425                          * dirs unless _EXTRACT_PERM is specified.
1426                          */
1427                         if ((a->mode != st_mode)
1428                             && (a->todo & TODO_MODE_FORCE))
1429                                 a->deferred |= (a->todo & TODO_MODE);
1430                         /* Ownership doesn't need deferred fixup. */
1431                         en = 0; /* Forget the EEXIST. */
1432                 }
1433         }
1434
1435         if (en) {
1436                 /* Everything failed; give up here. */
1437                 archive_set_error(&a->archive, en, "Can't create '%ls'",
1438                     a->name);
1439                 return (ARCHIVE_FAILED);
1440         }
1441
1442         a->pst = NULL; /* Cached stat data no longer valid. */
1443         return (ret);
1444 }
1445
1446 /*
1447  * Returns 0 if creation succeeds, or else returns errno value from
1448  * the failed system call.   Note:  This function should only ever perform
1449  * a single system call.
1450  */
1451 static int
1452 create_filesystem_object(struct archive_write_disk *a)
1453 {
1454         /* Create the entry. */
1455         const wchar_t *linkname;
1456         wchar_t *fullname;
1457         mode_t final_mode, mode;
1458         int r;
1459
1460         /* We identify hard/symlinks according to the link names. */
1461         /* Since link(2) and symlink(2) don't handle modes, we're done here. */
1462         linkname = archive_entry_hardlink_w(a->entry);
1463         if (linkname != NULL) {
1464                 wchar_t *linkfull, *namefull;
1465
1466                 linkfull = __la_win_permissive_name_w(linkname);
1467                 namefull = __la_win_permissive_name_w(a->name);
1468                 if (linkfull == NULL || namefull == NULL) {
1469                         errno = EINVAL;
1470                         r = -1;
1471                 } else {
1472                         r = la_CreateHardLinkW(namefull, linkfull);
1473                         if (r == 0) {
1474                                 la_dosmaperr(GetLastError());
1475                                 r = errno;
1476                         } else
1477                                 r = 0;
1478                 }
1479                 /*
1480                  * New cpio and pax formats allow hardlink entries
1481                  * to carry data, so we may have to open the file
1482                  * for hardlink entries.
1483                  *
1484                  * If the hardlink was successfully created and
1485                  * the archive doesn't have carry data for it,
1486                  * consider it to be non-authoritative for meta data.
1487                  * This is consistent with GNU tar and BSD pax.
1488                  * If the hardlink does carry data, let the last
1489                  * archive entry decide ownership.
1490                  */
1491                 if (r == 0 && a->filesize <= 0) {
1492                         a->todo = 0;
1493                         a->deferred = 0;
1494                 } else if (r == 0 && a->filesize > 0) {
1495                         a->fh = CreateFileW(namefull, GENERIC_WRITE, 0, NULL,
1496                             TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
1497                         if (a->fh == INVALID_HANDLE_VALUE) {
1498                                 la_dosmaperr(GetLastError());
1499                                 r = errno;
1500                         }
1501                 }
1502                 free(linkfull);
1503                 free(namefull);
1504                 return (r);
1505         }
1506         linkname = archive_entry_symlink_w(a->entry);
1507         if (linkname != NULL) {
1508 #if HAVE_SYMLINK
1509                 return symlink(linkname, a->name) ? errno : 0;
1510 #else
1511                 return (EPERM);
1512 #endif
1513         }
1514
1515         /*
1516          * The remaining system calls all set permissions, so let's
1517          * try to take advantage of that to avoid an extra chmod()
1518          * call.  (Recall that umask is set to zero right now!)
1519          */
1520
1521         /* Mode we want for the final restored object (w/o file type bits). */
1522         final_mode = a->mode & 07777;
1523         /*
1524          * The mode that will actually be restored in this step.  Note
1525          * that SUID, SGID, etc, require additional work to ensure
1526          * security, so we never restore them at this point.
1527          */
1528         mode = final_mode & 0777 & a->user_umask;
1529
1530         switch (a->mode & AE_IFMT) {
1531         default:
1532                 /* POSIX requires that we fall through here. */
1533                 /* FALLTHROUGH */
1534         case AE_IFREG:
1535                 fullname = a->name;
1536                 /* O_WRONLY | O_CREAT | O_EXCL */
1537                 a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
1538                     CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
1539                 if (a->fh == INVALID_HANDLE_VALUE &&
1540                     GetLastError() == ERROR_INVALID_NAME &&
1541                     fullname == a->name) {
1542                         fullname = __la_win_permissive_name_w(a->name);
1543                         a->fh = CreateFileW(fullname, GENERIC_WRITE, 0, NULL,
1544                             CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
1545                 }
1546                 if (a->fh == INVALID_HANDLE_VALUE) {
1547                         if (GetLastError() == ERROR_ACCESS_DENIED) {
1548                                 DWORD attr;
1549                                 /* Simulate an errno of POSIX system. */
1550                                 attr = GetFileAttributesW(fullname);
1551                                 if (attr == (DWORD)-1)
1552                                         la_dosmaperr(GetLastError());
1553                                 else if (attr & FILE_ATTRIBUTE_DIRECTORY)
1554                                         errno = EISDIR;
1555                                 else
1556                                         errno = EACCES;
1557                         } else
1558                                 la_dosmaperr(GetLastError());
1559                         r = 1;
1560                 } else
1561                         r = 0;
1562                 if (fullname != a->name)
1563                         free(fullname);
1564                 break;
1565         case AE_IFCHR:
1566         case AE_IFBLK:
1567                 /* TODO: Find a better way to warn about our inability
1568                  * to restore a block device node. */
1569                 return (EINVAL);
1570         case AE_IFDIR:
1571                 mode = (mode | MINIMUM_DIR_MODE) & MAXIMUM_DIR_MODE;
1572                 fullname = a->name;
1573                 r = CreateDirectoryW(fullname, NULL);
1574                 if (r == 0 && GetLastError() == ERROR_INVALID_NAME &&
1575                         fullname == a->name) {
1576                         fullname = __la_win_permissive_name_w(a->name);
1577                         r = CreateDirectoryW(fullname, NULL);
1578                 }
1579                 if (r != 0) {
1580                         r = 0;
1581                         /* Defer setting dir times. */
1582                         a->deferred |= (a->todo & TODO_TIMES);
1583                         a->todo &= ~TODO_TIMES;
1584                         /* Never use an immediate chmod(). */
1585                         /* We can't avoid the chmod() entirely if EXTRACT_PERM
1586                          * because of SysV SGID inheritance. */
1587                         if ((mode != final_mode)
1588                             || (a->flags & ARCHIVE_EXTRACT_PERM))
1589                                 a->deferred |= (a->todo & TODO_MODE);
1590                         a->todo &= ~TODO_MODE;
1591                 } else {
1592                         la_dosmaperr(GetLastError());
1593                         r = -1;
1594                 }
1595                 if (fullname != a->name)
1596                         free(fullname);
1597                 break;
1598         case AE_IFIFO:
1599                 /* TODO: Find a better way to warn about our inability
1600                  * to restore a fifo. */
1601                 return (EINVAL);
1602         }
1603
1604         /* All the system calls above set errno on failure. */
1605         if (r)
1606                 return (errno);
1607
1608         /* If we managed to set the final mode, we've avoided a chmod(). */
1609         if (mode == final_mode)
1610                 a->todo &= ~TODO_MODE;
1611         return (0);
1612 }
1613
1614 /*
1615  * Cleanup function for archive_extract.  Mostly, this involves processing
1616  * the fixup list, which is used to address a number of problems:
1617  *   * Dir permissions might prevent us from restoring a file in that
1618  *     dir, so we restore the dir with minimum 0700 permissions first,
1619  *     then correct the mode at the end.
1620  *   * Similarly, the act of restoring a file touches the directory
1621  *     and changes the timestamp on the dir, so we have to touch-up dir
1622  *     timestamps at the end as well.
1623  *   * Some file flags can interfere with the restore by, for example,
1624  *     preventing the creation of hardlinks to those files.
1625  *   * Mac OS extended metadata includes ACLs, so must be deferred on dirs.
1626  *
1627  * Note that tar/cpio do not require that archives be in a particular
1628  * order; there is no way to know when the last file has been restored
1629  * within a directory, so there's no way to optimize the memory usage
1630  * here by fixing up the directory any earlier than the
1631  * end-of-archive.
1632  *
1633  * XXX TODO: Directory ACLs should be restored here, for the same
1634  * reason we set directory perms here. XXX
1635  */
1636 static int
1637 _archive_write_disk_close(struct archive *_a)
1638 {
1639         struct archive_write_disk *a = (struct archive_write_disk *)_a;
1640         struct fixup_entry *next, *p;
1641         int ret;
1642
1643         archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
1644             ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
1645             "archive_write_disk_close");
1646         ret = _archive_write_disk_finish_entry(&a->archive);
1647
1648         /* Sort dir list so directories are fixed up in depth-first order. */
1649         p = sort_dir_list(a->fixup_list);
1650
1651         while (p != NULL) {
1652                 a->pst = NULL; /* Mark stat cache as out-of-date. */
1653                 if (p->fixup & TODO_TIMES) {
1654                         set_times(a, INVALID_HANDLE_VALUE, p->mode, p->name,
1655                             p->atime, p->atime_nanos,
1656                             p->birthtime, p->birthtime_nanos,
1657                             p->mtime, p->mtime_nanos,
1658                             p->ctime, p->ctime_nanos);
1659                 }
1660                 if (p->fixup & TODO_MODE_BASE)
1661                         la_chmod(p->name, p->mode);
1662                 if (p->fixup & TODO_ACLS)
1663                         set_acls(a, INVALID_HANDLE_VALUE, p->name, &p->acl);
1664                 next = p->next;
1665                 archive_acl_clear(&p->acl);
1666                 free(p->name);
1667                 free(p);
1668                 p = next;
1669         }
1670         a->fixup_list = NULL;
1671         return (ret);
1672 }
1673
1674 static int
1675 _archive_write_disk_free(struct archive *_a)
1676 {
1677         struct archive_write_disk *a;
1678         int ret;
1679         if (_a == NULL)
1680                 return (ARCHIVE_OK);
1681         archive_check_magic(_a, ARCHIVE_WRITE_DISK_MAGIC,
1682             ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free");
1683         a = (struct archive_write_disk *)_a;
1684         ret = _archive_write_disk_close(&a->archive);
1685         archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL);
1686         archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
1687         if (a->entry)
1688                 archive_entry_free(a->entry);
1689         archive_wstring_free(&a->_name_data);
1690         archive_string_free(&a->archive.error_string);
1691         archive_wstring_free(&a->path_safe);
1692         a->archive.magic = 0;
1693         __archive_clean(&a->archive);
1694         free(a);
1695         return (ret);
1696 }
1697
1698 /*
1699  * Simple O(n log n) merge sort to order the fixup list.  In
1700  * particular, we want to restore dir timestamps depth-first.
1701  */
1702 static struct fixup_entry *
1703 sort_dir_list(struct fixup_entry *p)
1704 {
1705         struct fixup_entry *a, *b, *t;
1706
1707         if (p == NULL)
1708                 return (NULL);
1709         /* A one-item list is already sorted. */
1710         if (p->next == NULL)
1711                 return (p);
1712
1713         /* Step 1: split the list. */
1714         t = p;
1715         a = p->next->next;
1716         while (a != NULL) {
1717                 /* Step a twice, t once. */
1718                 a = a->next;
1719                 if (a != NULL)
1720                         a = a->next;
1721                 t = t->next;
1722         }
1723         /* Now, t is at the mid-point, so break the list here. */
1724         b = t->next;
1725         t->next = NULL;
1726         a = p;
1727
1728         /* Step 2: Recursively sort the two sub-lists. */
1729         a = sort_dir_list(a);
1730         b = sort_dir_list(b);
1731
1732         /* Step 3: Merge the returned lists. */
1733         /* Pick the first element for the merged list. */
1734         if (wcscmp(a->name, b->name) > 0) {
1735                 t = p = a;
1736                 a = a->next;
1737         } else {
1738                 t = p = b;
1739                 b = b->next;
1740         }
1741
1742         /* Always put the later element on the list first. */
1743         while (a != NULL && b != NULL) {
1744                 if (wcscmp(a->name, b->name) > 0) {
1745                         t->next = a;
1746                         a = a->next;
1747                 } else {
1748                         t->next = b;
1749                         b = b->next;
1750                 }
1751                 t = t->next;
1752         }
1753
1754         /* Only one list is non-empty, so just splice it on. */
1755         if (a != NULL)
1756                 t->next = a;
1757         if (b != NULL)
1758                 t->next = b;
1759
1760         return (p);
1761 }
1762
1763 /*
1764  * Returns a new, initialized fixup entry.
1765  *
1766  * TODO: Reduce the memory requirements for this list by using a tree
1767  * structure rather than a simple list of names.
1768  */
1769 static struct fixup_entry *
1770 new_fixup(struct archive_write_disk *a, const wchar_t *pathname)
1771 {
1772         struct fixup_entry *fe;
1773
1774         fe = (struct fixup_entry *)calloc(1, sizeof(struct fixup_entry));
1775         if (fe == NULL)
1776                 return (NULL);
1777         fe->next = a->fixup_list;
1778         a->fixup_list = fe;
1779         fe->fixup = 0;
1780         fe->name = _wcsdup(pathname);
1781         return (fe);
1782 }
1783
1784 /*
1785  * Returns a fixup structure for the current entry.
1786  */
1787 static struct fixup_entry *
1788 current_fixup(struct archive_write_disk *a, const wchar_t *pathname)
1789 {
1790         if (a->current_fixup == NULL)
1791                 a->current_fixup = new_fixup(a, pathname);
1792         return (a->current_fixup);
1793 }
1794
1795 /* TODO: Make this work. */
1796 /*
1797  * TODO: The deep-directory support bypasses this; disable deep directory
1798  * support if we're doing symlink checks.
1799  */
1800 /*
1801  * TODO: Someday, integrate this with the deep dir support; they both
1802  * scan the path and both can be optimized by comparing against other
1803  * recent paths.
1804  */
1805 /* TODO: Extend this to support symlinks on Windows Vista and later. */
1806 static int
1807 check_symlinks(struct archive_write_disk *a)
1808 {
1809         wchar_t *pn, *p;
1810         wchar_t c;
1811         int r;
1812         BY_HANDLE_FILE_INFORMATION st;
1813         mode_t st_mode;
1814
1815         /*
1816          * Guard against symlink tricks.  Reject any archive entry whose
1817          * destination would be altered by a symlink.
1818          */
1819         /* Whatever we checked last time doesn't need to be re-checked. */
1820         pn = a->name;
1821         p = a->path_safe.s;
1822         while ((*pn != '\0') && (*p == *pn))
1823                 ++p, ++pn;
1824         c = pn[0];
1825         /* Keep going until we've checked the entire name. */
1826         while (pn[0] != '\0' && (pn[0] != '\\' || pn[1] != '\0')) {
1827                 /* Skip the next path element. */
1828                 while (*pn != '\0' && *pn != '\\')
1829                         ++pn;
1830                 c = pn[0];
1831                 pn[0] = '\0';
1832                 /* Check that we haven't hit a symlink. */
1833                 r = file_information(a, a->name, &st, &st_mode, 1);
1834                 if (r != 0) {
1835                         /* We've hit a dir that doesn't exist; stop now. */
1836                         if (errno == ENOENT)
1837                                 break;
1838                 } else if (S_ISLNK(st_mode)) {
1839                         if (c == '\0') {
1840                                 /*
1841                                  * Last element is symlink; remove it
1842                                  * so we can overwrite it with the
1843                                  * item being extracted.
1844                                  */
1845                                 if (disk_unlink(a->name)) {
1846                                         archive_set_error(&a->archive, errno,
1847                                             "Could not remove symlink %ls",
1848                                             a->name);
1849                                         pn[0] = c;
1850                                         return (ARCHIVE_FAILED);
1851                                 }
1852                                 a->pst = NULL;
1853                                 /*
1854                                  * Even if we did remove it, a warning
1855                                  * is in order.  The warning is silly,
1856                                  * though, if we're just replacing one
1857                                  * symlink with another symlink.
1858                                  */
1859                                 if (!S_ISLNK(a->mode)) {
1860                                         archive_set_error(&a->archive, 0,
1861                                             "Removing symlink %ls",
1862                                             a->name);
1863                                 }
1864                                 /* Symlink gone.  No more problem! */
1865                                 pn[0] = c;
1866                                 return (0);
1867                         } else if (a->flags & ARCHIVE_EXTRACT_UNLINK) {
1868                                 /* User asked us to remove problems. */
1869                                 if (disk_unlink(a->name) != 0) {
1870                                         archive_set_error(&a->archive, 0,
1871                                             "Cannot remove intervening "
1872                                             "symlink %ls", a->name);
1873                                         pn[0] = c;
1874                                         return (ARCHIVE_FAILED);
1875                                 }
1876                                 a->pst = NULL;
1877                         } else {
1878                                 archive_set_error(&a->archive, 0,
1879                                     "Cannot extract through symlink %ls",
1880                                     a->name);
1881                                 pn[0] = c;
1882                                 return (ARCHIVE_FAILED);
1883                         }
1884                 }
1885         }
1886         pn[0] = c;
1887         /* We've checked and/or cleaned the whole path, so remember it. */
1888         archive_wstrcpy(&a->path_safe, a->name);
1889         return (ARCHIVE_OK);
1890 }
1891
1892 static int
1893 guidword(wchar_t *p, int n)
1894 {
1895         int i;
1896
1897         for (i = 0; i < n; i++) {
1898                 if ((*p >= L'0' && *p <= L'9') ||
1899                     (*p >= L'a' && *p <= L'f') ||
1900                     (*p >= L'A' && *p <= L'F'))
1901                         p++;
1902                 else
1903                         return (-1);
1904         }
1905         return (0);
1906 }
1907
1908 /*
1909  * Canonicalize the pathname.  In particular, this strips duplicate
1910  * '\' characters, '.' elements, and trailing '\'.  It also raises an
1911  * error for an empty path, a trailing '..' or (if _SECURE_NODOTDOT is
1912  * set) any '..' in the path.
1913  */
1914 static int
1915 cleanup_pathname(struct archive_write_disk *a)
1916 {
1917         wchar_t *dest, *src, *p, *top;
1918         wchar_t separator = L'\0';
1919
1920         p = a->name;
1921         if (*p == L'\0') {
1922                 archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1923                     "Invalid empty pathname");
1924                 return (ARCHIVE_FAILED);
1925         }
1926
1927         /* Replace '/' by '\' */
1928         for (; *p != L'\0'; p++) {
1929                 if (*p == L'/')
1930                         *p = L'\\';
1931         }
1932         p = a->name;
1933
1934         /* Skip leading "\\.\" or "\\?\" or "\\?\UNC\" or
1935          * "\\?\Volume{GUID}\"
1936          * (absolute path prefixes used by Windows API) */
1937         if (p[0] == L'\\' && p[1] == L'\\' &&
1938             (p[2] == L'.' || p[2] == L'?') && p[3] ==  L'\\')
1939         {
1940                 /* A path begin with "\\?\UNC\" */
1941                 if (p[2] == L'?' &&
1942                     (p[4] == L'U' || p[4] == L'u') &&
1943                     (p[5] == L'N' || p[5] == L'n') &&
1944                     (p[6] == L'C' || p[6] == L'c') &&
1945                     p[7] == L'\\')
1946                         p += 8;
1947                 /* A path begin with "\\?\Volume{GUID}\" */
1948                 else if (p[2] == L'?' &&
1949                     (p[4] == L'V' || p[4] == L'v') &&
1950                     (p[5] == L'O' || p[5] == L'o') &&
1951                     (p[6] == L'L' || p[6] == L'l') &&
1952                     (p[7] == L'U' || p[7] == L'u') &&
1953                     (p[8] == L'M' || p[8] == L'm') &&
1954                     (p[9] == L'E' || p[9] == L'e') &&
1955                     p[10] == L'{') {
1956                         if (guidword(p+11, 8) == 0 && p[19] == L'-' &&
1957                             guidword(p+20, 4) == 0 && p[24] == L'-' &&
1958                             guidword(p+25, 4) == 0 && p[29] == L'-' &&
1959                             guidword(p+30, 4) == 0 && p[34] == L'-' &&
1960                             guidword(p+35, 12) == 0 && p[47] == L'}' &&
1961                             p[48] == L'\\')
1962                                 p += 49;
1963                         else
1964                                 p += 4;
1965                 /* A path begin with "\\.\PhysicalDriveX" */
1966                 } else if (p[2] == L'.' &&
1967                     (p[4] == L'P' || p[4] == L'p') &&
1968                     (p[5] == L'H' || p[5] == L'h') &&
1969                     (p[6] == L'Y' || p[6] == L'y') &&
1970                     (p[7] == L'S' || p[7] == L's') &&
1971                     (p[8] == L'I' || p[8] == L'i') &&
1972                     (p[9] == L'C' || p[9] == L'c') &&
1973                     (p[9] == L'A' || p[9] == L'a') &&
1974                     (p[9] == L'L' || p[9] == L'l') &&
1975                     (p[9] == L'D' || p[9] == L'd') &&
1976                     (p[9] == L'R' || p[9] == L'r') &&
1977                     (p[9] == L'I' || p[9] == L'i') &&
1978                     (p[9] == L'V' || p[9] == L'v') &&
1979                     (p[9] == L'E' || p[9] == L'e') &&
1980                     (p[10] >= L'0' && p[10] <= L'9') &&
1981                     p[11] == L'\0') {
1982                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1983                             "Path is a physical drive name");
1984                         return (ARCHIVE_FAILED);
1985                 } else
1986                         p += 4;
1987         }
1988
1989         /* Skip leading drive letter from archives created
1990          * on Windows. */
1991         if (((p[0] >= L'a' && p[0] <= L'z') ||
1992              (p[0] >= L'A' && p[0] <= L'Z')) &&
1993                  p[1] == L':') {
1994                 if (p[2] == L'\0') {
1995                         archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
1996                             "Path is a drive name");
1997                         return (ARCHIVE_FAILED);
1998                 }
1999                 if (p[2] == L'\\')
2000                         p += 2;
2001         }
2002
2003         top = dest = src = p;
2004         /* Rewrite the path name if its character is a unusable. */
2005         for (; *p != L'\0'; p++) {
2006                 if (*p == L':' || *p == L'*' || *p == L'?' || *p == L'"' ||
2007                     *p == L'<' || *p == L'>' || *p == L'|')
2008                         *p = L'_';
2009         }
2010         /* Skip leading '\'. */
2011         if (*src == L'\\')
2012                 separator = *src++;
2013
2014         /* Scan the pathname one element at a time. */
2015         for (;;) {
2016                 /* src points to first char after '\' */
2017                 if (src[0] == L'\0') {
2018                         break;
2019                 } else if (src[0] == L'\\') {
2020                         /* Found '\\'('//'), ignore second one. */
2021                         src++;
2022                         continue;
2023                 } else if (src[0] == L'.') {
2024                         if (src[1] == L'\0') {
2025                                 /* Ignore trailing '.' */
2026                                 break;
2027                         } else if (src[1] == L'\\') {
2028                                 /* Skip '.\'. */
2029                                 src += 2;
2030                                 continue;
2031                         } else if (src[1] == L'.') {
2032                                 if (src[2] == L'\\' || src[2] == L'\0') {
2033                                         /* Conditionally warn about '..' */
2034                                         if (a->flags &
2035                                             ARCHIVE_EXTRACT_SECURE_NODOTDOT) {
2036                                                 archive_set_error(&a->archive,
2037                                                     ARCHIVE_ERRNO_MISC,
2038                                                     "Path contains '..'");
2039                                                 return (ARCHIVE_FAILED);
2040                                         }
2041                                 }
2042                                 /*
2043                                  * Note: Under no circumstances do we
2044                                  * remove '..' elements.  In
2045                                  * particular, restoring
2046                                  * '\foo\..\bar\' should create the
2047                                  * 'foo' dir as a side-effect.
2048                                  */
2049                         }
2050                 }
2051
2052                 /* Copy current element, including leading '\'. */
2053                 if (separator)
2054                         *dest++ = L'\\';
2055                 while (*src != L'\0' && *src != L'\\') {
2056                         *dest++ = *src++;
2057                 }
2058
2059                 if (*src == L'\0')
2060                         break;
2061
2062                 /* Skip '\' separator. */
2063                 separator = *src++;
2064         }
2065         /*
2066          * We've just copied zero or more path elements, not including the
2067          * final '\'.
2068          */
2069         if (dest == top) {
2070                 /*
2071                  * Nothing got copied.  The path must have been something
2072                  * like '.' or '\' or './' or '/././././/./'.
2073                  */
2074                 if (separator)
2075                         *dest++ = L'\\';
2076                 else
2077                         *dest++ = L'.';
2078         }
2079         /* Terminate the result. */
2080         *dest = L'\0';
2081         return (ARCHIVE_OK);
2082 }
2083
2084 /*
2085  * Create the parent directory of the specified path, assuming path
2086  * is already in mutable storage.
2087  */
2088 static int
2089 create_parent_dir(struct archive_write_disk *a, wchar_t *path)
2090 {
2091         wchar_t *slash;
2092         int r;
2093
2094         /* Remove tail element to obtain parent name. */
2095         slash = wcsrchr(path, L'\\');
2096         if (slash == NULL)
2097                 return (ARCHIVE_OK);
2098         *slash = L'\0';
2099         r = create_dir(a, path);
2100         *slash = L'\\';
2101         return (r);
2102 }
2103
2104 /*
2105  * Create the specified dir, recursing to create parents as necessary.
2106  *
2107  * Returns ARCHIVE_OK if the path exists when we're done here.
2108  * Otherwise, returns ARCHIVE_FAILED.
2109  * Assumes path is in mutable storage; path is unchanged on exit.
2110  */
2111 static int
2112 create_dir(struct archive_write_disk *a, wchar_t *path)
2113 {
2114         BY_HANDLE_FILE_INFORMATION st;
2115         struct fixup_entry *le;
2116         wchar_t *slash, *base, *full;
2117         mode_t mode_final, mode, st_mode;
2118         int r;
2119
2120         /* Check for special names and just skip them. */
2121         slash = wcsrchr(path, L'\\');
2122         if (slash == NULL)
2123                 base = path;
2124         else
2125                 base = slash + 1;
2126
2127         if (base[0] == L'\0' ||
2128             (base[0] == L'.' && base[1] == L'\0') ||
2129             (base[0] == L'.' && base[1] == L'.' && base[2] == L'\0')) {
2130                 /* Don't bother trying to create null path, '.', or '..'. */
2131                 if (slash != NULL) {
2132                         *slash = L'\0';
2133                         r = create_dir(a, path);
2134                         *slash = L'\\';
2135                         return (r);
2136                 }
2137                 return (ARCHIVE_OK);
2138         }
2139
2140         /*
2141          * Yes, this should be stat() and not lstat().  Using lstat()
2142          * here loses the ability to extract through symlinks.  Also note
2143          * that this should not use the a->st cache.
2144          */
2145         if (file_information(a, path, &st, &st_mode, 0) == 0) {
2146                 if (S_ISDIR(st_mode))
2147                         return (ARCHIVE_OK);
2148                 if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
2149                         archive_set_error(&a->archive, EEXIST,
2150                             "Can't create directory '%ls'", path);
2151                         return (ARCHIVE_FAILED);
2152                 }
2153                 if (disk_unlink(path) != 0) {
2154                         archive_set_error(&a->archive, errno,
2155                             "Can't create directory '%ls': "
2156                             "Conflicting file cannot be removed",
2157                             path);
2158                         return (ARCHIVE_FAILED);
2159                 }
2160         } else if (errno != ENOENT && errno != ENOTDIR) {
2161                 /* Stat failed? */
2162                 archive_set_error(&a->archive, errno,
2163                     "Can't test directory '%ls'", path);
2164                 return (ARCHIVE_FAILED);
2165         } else if (slash != NULL) {
2166                 *slash = '\0';
2167                 r = create_dir(a, path);
2168                 *slash = '\\';
2169                 if (r != ARCHIVE_OK)
2170                         return (r);
2171         }
2172
2173         /*
2174          * Mode we want for the final restored directory.  Per POSIX,
2175          * implicitly-created dirs must be created obeying the umask.
2176          * There's no mention whether this is different for privileged
2177          * restores (which the rest of this code handles by pretending
2178          * umask=0).  I've chosen here to always obey the user's umask for
2179          * implicit dirs, even if _EXTRACT_PERM was specified.
2180          */
2181         mode_final = DEFAULT_DIR_MODE & ~a->user_umask;
2182         /* Mode we want on disk during the restore process. */
2183         mode = mode_final;
2184         mode |= MINIMUM_DIR_MODE;
2185         mode &= MAXIMUM_DIR_MODE;
2186         /*
2187          * Apply __la_win_permissive_name_w to path in order to
2188          * remove '../' path string.
2189          */
2190         full = __la_win_permissive_name_w(path);
2191         if (full == NULL)
2192                 errno = EINVAL;
2193         else if (CreateDirectoryW(full, NULL) != 0) {
2194                 if (mode != mode_final) {
2195                         le = new_fixup(a, path);
2196                         le->fixup |=TODO_MODE_BASE;
2197                         le->mode = mode_final;
2198                 }
2199                 free(full);
2200                 return (ARCHIVE_OK);
2201         } else {
2202                 la_dosmaperr(GetLastError());
2203         }
2204         free(full);
2205
2206         /*
2207          * Without the following check, a/b/../b/c/d fails at the
2208          * second visit to 'b', so 'd' can't be created.  Note that we
2209          * don't add it to the fixup list here, as it's already been
2210          * added.
2211          */
2212         if (file_information(a, path, &st, &st_mode, 0) == 0 && S_ISDIR(st_mode))
2213                 return (ARCHIVE_OK);
2214
2215         archive_set_error(&a->archive, errno, "Failed to create dir '%ls'",
2216             path);
2217         return (ARCHIVE_FAILED);
2218 }
2219
2220 /*
2221  * Note: Although we can skip setting the user id if the desired user
2222  * id matches the current user, we cannot skip setting the group, as
2223  * many systems set the gid based on the containing directory.  So
2224  * we have to perform a chown syscall if we want to set the SGID
2225  * bit.  (The alternative is to stat() and then possibly chown(); it's
2226  * more efficient to skip the stat() and just always chown().)  Note
2227  * that a successful chown() here clears the TODO_SGID_CHECK bit, which
2228  * allows set_mode to skip the stat() check for the GID.
2229  */
2230 static int
2231 set_ownership(struct archive_write_disk *a)
2232 {
2233 /* unfortunately, on win32 there is no 'root' user with uid 0,
2234    so we just have to try the chown and see if it works */
2235
2236         /* If we know we can't change it, don't bother trying. */
2237         if (a->user_uid != 0  &&  a->user_uid != a->uid) {
2238                 archive_set_error(&a->archive, errno,
2239                     "Can't set UID=%jd", (intmax_t)a->uid);
2240                 return (ARCHIVE_WARN);
2241         }
2242
2243         archive_set_error(&a->archive, errno,
2244             "Can't set user=%jd/group=%jd for %ls",
2245             (intmax_t)a->uid, (intmax_t)a->gid, a->name);
2246         return (ARCHIVE_WARN);
2247 }
2248
2249 static int
2250 set_times(struct archive_write_disk *a,
2251     HANDLE h, int mode, const wchar_t *name,
2252     time_t atime, long atime_nanos,
2253     time_t birthtime, long birthtime_nanos,
2254     time_t mtime, long mtime_nanos,
2255     time_t ctime, long ctime_nanos)
2256 {
2257 #define EPOC_TIME ARCHIVE_LITERAL_ULL(116444736000000000)
2258 #define WINTIME(sec, nsec) ((Int32x32To64(sec, 10000000) + EPOC_TIME)\
2259          + (((nsec)/1000)*10))
2260
2261         HANDLE hw = 0;
2262         ULARGE_INTEGER wintm;
2263         FILETIME *pfbtime;
2264         FILETIME fatime, fbtime, fmtime;
2265
2266         (void)ctime; /* UNUSED */
2267         (void)ctime_nanos; /* UNUSED */
2268
2269         if (h != INVALID_HANDLE_VALUE) {
2270                 hw = NULL;
2271         } else {
2272                 wchar_t *ws;
2273
2274                 if (S_ISLNK(mode))
2275                         return (ARCHIVE_OK);
2276                 ws = __la_win_permissive_name_w(name);
2277                 if (ws == NULL)
2278                         goto settimes_failed;
2279                 hw = CreateFileW(ws, FILE_WRITE_ATTRIBUTES,
2280                     0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
2281                 free(ws);
2282                 if (hw == INVALID_HANDLE_VALUE)
2283                         goto settimes_failed;
2284                 h = hw;
2285         }
2286
2287         wintm.QuadPart = WINTIME(atime, atime_nanos);
2288         fatime.dwLowDateTime = wintm.LowPart;
2289         fatime.dwHighDateTime = wintm.HighPart;
2290         wintm.QuadPart = WINTIME(mtime, mtime_nanos);
2291         fmtime.dwLowDateTime = wintm.LowPart;
2292         fmtime.dwHighDateTime = wintm.HighPart;
2293         /*
2294          * SetFileTime() supports birthtime.
2295          */
2296         if (birthtime > 0 || birthtime_nanos > 0) {
2297                 wintm.QuadPart = WINTIME(birthtime, birthtime_nanos);
2298                 fbtime.dwLowDateTime = wintm.LowPart;
2299                 fbtime.dwHighDateTime = wintm.HighPart;
2300                 pfbtime = &fbtime;
2301         } else
2302                 pfbtime = NULL;
2303         if (SetFileTime(h, pfbtime, &fatime, &fmtime) == 0)
2304                 goto settimes_failed;
2305         CloseHandle(hw);
2306         return (ARCHIVE_OK);
2307
2308 settimes_failed:
2309         CloseHandle(hw);
2310         archive_set_error(&a->archive, EINVAL, "Can't restore time");
2311         return (ARCHIVE_WARN);
2312 }
2313
2314 static int
2315 set_times_from_entry(struct archive_write_disk *a)
2316 {
2317         time_t atime, birthtime, mtime, ctime;
2318         long atime_nsec, birthtime_nsec, mtime_nsec, ctime_nsec;
2319
2320         /* Suitable defaults. */
2321         atime = birthtime = mtime = ctime = a->start_time;
2322         atime_nsec = birthtime_nsec = mtime_nsec = ctime_nsec = 0;
2323
2324         /* If no time was provided, we're done. */
2325         if (!archive_entry_atime_is_set(a->entry)
2326             && !archive_entry_birthtime_is_set(a->entry)
2327             && !archive_entry_mtime_is_set(a->entry))
2328                 return (ARCHIVE_OK);
2329
2330         if (archive_entry_atime_is_set(a->entry)) {
2331                 atime = archive_entry_atime(a->entry);
2332                 atime_nsec = archive_entry_atime_nsec(a->entry);
2333         }
2334         if (archive_entry_birthtime_is_set(a->entry)) {
2335                 birthtime = archive_entry_birthtime(a->entry);
2336                 birthtime_nsec = archive_entry_birthtime_nsec(a->entry);
2337         }
2338         if (archive_entry_mtime_is_set(a->entry)) {
2339                 mtime = archive_entry_mtime(a->entry);
2340                 mtime_nsec = archive_entry_mtime_nsec(a->entry);
2341         }
2342         if (archive_entry_ctime_is_set(a->entry)) {
2343                 ctime = archive_entry_ctime(a->entry);
2344                 ctime_nsec = archive_entry_ctime_nsec(a->entry);
2345         }
2346
2347         return set_times(a, a->fh, a->mode, a->name,
2348                          atime, atime_nsec,
2349                          birthtime, birthtime_nsec,
2350                          mtime, mtime_nsec,
2351                          ctime, ctime_nsec);
2352 }
2353
2354 static int
2355 set_mode(struct archive_write_disk *a, int mode)
2356 {
2357         int r = ARCHIVE_OK;
2358         mode &= 07777; /* Strip off file type bits. */
2359
2360         if (a->todo & TODO_SGID_CHECK) {
2361                 /*
2362                  * If we don't know the GID is right, we must stat()
2363                  * to verify it.  We can't just check the GID of this
2364                  * process, since systems sometimes set GID from
2365                  * the enclosing dir or based on ACLs.
2366                  */
2367                 if ((r = lazy_stat(a)) != ARCHIVE_OK)
2368                         return (r);
2369                 if (0 != a->gid) {
2370                         mode &= ~ S_ISGID;
2371                 }
2372                 /* While we're here, double-check the UID. */
2373                 if (0 != a->uid
2374                     && (a->todo & TODO_SUID)) {
2375                         mode &= ~ S_ISUID;
2376                 }
2377                 a->todo &= ~TODO_SGID_CHECK;
2378                 a->todo &= ~TODO_SUID_CHECK;
2379         } else if (a->todo & TODO_SUID_CHECK) {
2380                 /*
2381                  * If we don't know the UID is right, we can just check
2382                  * the user, since all systems set the file UID from
2383                  * the process UID.
2384                  */
2385                 if (a->user_uid != a->uid) {
2386                         mode &= ~ S_ISUID;
2387                 }
2388                 a->todo &= ~TODO_SUID_CHECK;
2389         }
2390
2391         if (S_ISLNK(a->mode)) {
2392 #ifdef HAVE_LCHMOD
2393                 /*
2394                  * If this is a symlink, use lchmod().  If the
2395                  * platform doesn't support lchmod(), just skip it.  A
2396                  * platform that doesn't provide a way to set
2397                  * permissions on symlinks probably ignores
2398                  * permissions on symlinks, so a failure here has no
2399                  * impact.
2400                  */
2401                 if (lchmod(a->name, mode) != 0) {
2402                         archive_set_error(&a->archive, errno,
2403                             "Can't set permissions to 0%o", (int)mode);
2404                         r = ARCHIVE_WARN;
2405                 }
2406 #endif
2407         } else if (!S_ISDIR(a->mode)) {
2408                 /*
2409                  * If it's not a symlink and not a dir, then use
2410                  * fchmod() or chmod(), depending on whether we have
2411                  * an fd.  Dirs get their perms set during the
2412                  * post-extract fixup, which is handled elsewhere.
2413                  */
2414 #ifdef HAVE_FCHMOD
2415                 if (a->fd >= 0) {
2416                         if (fchmod(a->fd, mode) != 0) {
2417                                 archive_set_error(&a->archive, errno,
2418                                     "Can't set permissions to 0%o", (int)mode);
2419                                 r = ARCHIVE_WARN;
2420                         }
2421                 } else
2422 #endif
2423                         /* If this platform lacks fchmod(), then
2424                          * we'll just use chmod(). */
2425                         if (la_chmod(a->name, mode) != 0) {
2426                                 archive_set_error(&a->archive, errno,
2427                                     "Can't set permissions to 0%o", (int)mode);
2428                                 r = ARCHIVE_WARN;
2429                         }
2430         }
2431         return (r);
2432 }
2433
2434 static int
2435 set_fflags(struct archive_write_disk *a)
2436 {
2437         (void)a; /* UNUSED */
2438         return (ARCHIVE_OK);
2439 }
2440
2441 /* Default empty function body to satisfy mainline code. */
2442 static int
2443 set_acls(struct archive_write_disk *a, HANDLE h, const wchar_t *name,
2444          struct archive_acl *acl)
2445 {
2446         (void)a; /* UNUSED */
2447         (void)h; /* UNUSED */
2448         (void)name; /* UNUSED */
2449         (void)acl; /* UNUSED */
2450         return (ARCHIVE_OK);
2451 }
2452
2453 /*
2454  * Restore extended attributes - stub implementation for unsupported systems
2455  */
2456 static int
2457 set_xattrs(struct archive_write_disk *a)
2458 {
2459         static int warning_done = 0;
2460
2461         /* If there aren't any extended attributes, then it's okay not
2462          * to extract them, otherwise, issue a single warning. */
2463         if (archive_entry_xattr_count(a->entry) != 0 && !warning_done) {
2464                 warning_done = 1;
2465                 archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
2466                     "Cannot restore extended attributes on this system");
2467                 return (ARCHIVE_WARN);
2468         }
2469         /* Warning was already emitted; suppress further warnings. */
2470         return (ARCHIVE_OK);
2471 }
2472
2473 static void
2474 fileTimeToUtc(const FILETIME *filetime, time_t *time, long *ns)
2475 {
2476         ULARGE_INTEGER utc;
2477
2478         utc.HighPart = filetime->dwHighDateTime;
2479         utc.LowPart  = filetime->dwLowDateTime;
2480         if (utc.QuadPart >= EPOC_TIME) {
2481                 utc.QuadPart -= EPOC_TIME;
2482                 /* milli seconds base */
2483                 *time = (time_t)(utc.QuadPart / 10000000);
2484                 /* nano seconds base */
2485                 *ns = (long)(utc.QuadPart % 10000000) * 100;
2486         } else {
2487                 *time = 0;
2488                 *ns = 0;
2489         }
2490 }
2491 /*
2492  * Test if file on disk is older than entry.
2493  */
2494 static int
2495 older(BY_HANDLE_FILE_INFORMATION *st, struct archive_entry *entry)
2496 {
2497         time_t sec;
2498         long nsec;
2499
2500         fileTimeToUtc(&st->ftLastWriteTime, &sec, &nsec);
2501         /* First, test the seconds and return if we have a definite answer. */
2502         /* Definitely older. */
2503         if (sec < archive_entry_mtime(entry))
2504                 return (1);
2505         /* Definitely younger. */
2506         if (sec > archive_entry_mtime(entry))
2507                 return (0);
2508         if (nsec < archive_entry_mtime_nsec(entry))
2509                 return (1);
2510         /* Same age or newer, so not older. */
2511         return (0);
2512 }
2513
2514 #endif /* _WIN32 && !__CYGWIN__ */
2515