]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libarchive/archive_read_extract.c
This commit was generated by cvs2svn to compensate for changes in r154258,
[FreeBSD/FreeBSD.git] / lib / libarchive / archive_read_extract.c
1 /*-
2  * Copyright (c) 2003-2005 Tim Kientzle
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer
10  *    in this position and unchanged.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "archive_platform.h"
28 __FBSDID("$FreeBSD$");
29
30 #include <sys/types.h>
31 #ifdef HAVE_SYS_ACL_H
32 #include <sys/acl.h>
33 #endif
34 #ifdef HAVE_SYS_IOCTL_H
35 #include <sys/ioctl.h>
36 #endif
37 #include <sys/stat.h>
38 #include <sys/time.h>
39
40 #ifdef HAVE_EXT2FS_EXT2_FS_H
41 #include <ext2fs/ext2_fs.h>     /* for Linux file flags */
42 #endif
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <grp.h>
46 #ifdef HAVE_LINUX_EXT2_FS_H
47 #include <linux/ext2_fs.h>      /* for Linux file flags */
48 #endif
49 #include <limits.h>
50 #include <pwd.h>
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <string.h>
54 #include <unistd.h>
55
56 #include "archive.h"
57 #include "archive_string.h"
58 #include "archive_entry.h"
59 #include "archive_private.h"
60
61 struct fixup_entry {
62         struct fixup_entry      *next;
63         mode_t                   mode;
64         int64_t                  mtime;
65         int64_t                  atime;
66         unsigned long            mtime_nanos;
67         unsigned long            atime_nanos;
68         unsigned long            fflags_set;
69         int                      fixup; /* bitmask of what needs fixing */
70         char                    *name;
71 };
72
73 #define FIXUP_MODE      1
74 #define FIXUP_TIMES     2
75 #define FIXUP_FFLAGS    4
76
77 struct bucket {
78         char    *name;
79         int      hash;
80         id_t     id;
81 };
82
83 struct extract {
84         mode_t                   umask;
85         mode_t                   default_dir_mode;
86         struct archive_string    create_parent_dir;
87         struct fixup_entry      *fixup_list;
88         struct fixup_entry      *current_fixup;
89
90         struct bucket ucache[127];
91         struct bucket gcache[127];
92
93         /*
94          * Cached stat data from disk for the current entry.
95          * If this is valid, pst points to st.  Otherwise,
96          * pst is null.
97          */
98         struct stat              st;
99         struct stat             *pst;
100 };
101
102 /* Default mode for dirs created automatically (will be modified by umask). */
103 #define DEFAULT_DIR_MODE 0777
104 /*
105  * Mode to use for newly-created dirs during extraction; the correct
106  * mode will be set at the end of the extraction.
107  */
108 #define SECURE_DIR_MODE 0700
109
110 static void     archive_extract_cleanup(struct archive *);
111 static int      extract_block_device(struct archive *,
112                     struct archive_entry *, int);
113 static int      extract_char_device(struct archive *,
114                     struct archive_entry *, int);
115 static int      extract_device(struct archive *,
116                     struct archive_entry *, int flags, mode_t mode);
117 static int      extract_dir(struct archive *, struct archive_entry *, int);
118 static int      extract_fifo(struct archive *, struct archive_entry *, int);
119 static int      extract_file(struct archive *, struct archive_entry *, int);
120 static int      extract_hard_link(struct archive *, struct archive_entry *, int);
121 static int      extract_symlink(struct archive *, struct archive_entry *, int);
122 static unsigned int     hash(const char *);
123 static gid_t    lookup_gid(struct archive *, const char *uname, gid_t);
124 static uid_t    lookup_uid(struct archive *, const char *uname, uid_t);
125 static int      create_dir(struct archive *, const char *, int flags);
126 static int      create_dir_mutable(struct archive *, char *, int flags);
127 static int      create_dir_recursive(struct archive *, char *, int flags);
128 static int      create_parent_dir(struct archive *, const char *, int flags);
129 static int      create_parent_dir_mutable(struct archive *, char *, int flags);
130 static int      restore_metadata(struct archive *, int fd,
131                     struct archive_entry *, int flags);
132 #ifdef HAVE_POSIX_ACL
133 static int      set_acl(struct archive *, int fd, struct archive_entry *,
134                     acl_type_t, int archive_entry_acl_type, const char *tn);
135 #endif
136 static int      set_acls(struct archive *, int fd, struct archive_entry *);
137 static int      set_fflags(struct archive *, int fd, const char *name, mode_t,
138                     unsigned long fflags_set, unsigned long fflags_clear);
139 static int      set_ownership(struct archive *, int fd, struct archive_entry *,
140                     int flags);
141 static int      set_perm(struct archive *, int fd, struct archive_entry *,
142                     int mode, int flags);
143 static int      set_time(struct archive *, int fd, struct archive_entry *, int);
144 static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
145
146
147 /*
148  * Extract this entry to disk.
149  *
150  * TODO: Validate hardlinks.  According to the standards, we're
151  * supposed to check each extracted hardlink and squawk if it refers
152  * to a file that we didn't restore.  I'm not entirely convinced this
153  * is a good idea, but more importantly: Is there any way to validate
154  * hardlinks without keeping a complete list of filenames from the
155  * entire archive?? Ugh.
156  *
157  */
158 int
159 archive_read_extract(struct archive *a, struct archive_entry *entry, int flags)
160 {
161         mode_t mode;
162         struct extract *extract;
163         int ret;
164         int restore_pwd;
165         char *original_filename;
166
167         if (a->extract == NULL) {
168                 a->extract = malloc(sizeof(*a->extract));
169                 if (a->extract == NULL) {
170                         archive_set_error(a, ENOMEM, "Can't extract");
171                         return (ARCHIVE_FATAL);
172                 }
173                 a->cleanup_archive_extract = archive_extract_cleanup;
174                 memset(a->extract, 0, sizeof(*a->extract));
175         }
176         extract = a->extract;
177         umask(extract->umask = umask(0)); /* Read the current umask. */
178         extract->default_dir_mode = DEFAULT_DIR_MODE & ~extract->umask;
179         extract->pst = NULL;
180         extract->current_fixup = NULL;
181         restore_pwd = -1;
182         original_filename = NULL;
183
184         /* The following is not possible without fchdir.  <sigh> */
185 #ifdef HAVE_FCHDIR
186         /*
187          * If pathname is longer than PATH_MAX, record starting directory
188          * and chdir to a suitable intermediate dir.
189          */
190         if (strlen(archive_entry_pathname(entry)) > PATH_MAX) {
191                 char *intdir, *tail;
192
193                 restore_pwd = open(".", O_RDONLY);
194                 if (restore_pwd < 0) {
195                                 archive_set_error(a, errno,
196                                     "Unable to restore long pathname");
197                                 return (ARCHIVE_WARN);
198                 }
199
200                 /*
201                  * Yes, the copy here is necessary because we edit
202                  * the pathname in-place to create intermediate dirnames.
203                  */
204                 original_filename = strdup(archive_entry_pathname(entry));
205
206                 /*
207                  * "intdir" points to the initial dir section we're going
208                  * to remove, "tail" points to the remainder of the path.
209                  */
210                 intdir = tail = original_filename;
211                 while (strlen(tail) > PATH_MAX) {
212                         intdir = tail;
213
214                         /* Locate a dir prefix shorter than PATH_MAX. */
215                         tail = intdir + PATH_MAX - 8;
216                         while (tail > intdir && *tail != '/')
217                                 tail--;
218                         if (tail <= intdir) {
219                                 archive_set_error(a, EPERM,
220                                     "Path element too long");
221                                 ret = ARCHIVE_WARN;
222                                 goto cleanup;
223                         }
224
225                         /* Create intdir and chdir to it. */
226                         *tail = '\0'; /* Terminate dir portion */
227                         ret = create_dir(a, intdir, flags);
228                         if (ret == ARCHIVE_OK && chdir(intdir) != 0) {
229                                 archive_set_error(a, errno, "Couldn't chdir");
230                                 ret = ARCHIVE_WARN;
231                         }
232                         *tail = '/'; /* Restore the / we removed. */
233                         if (ret != ARCHIVE_OK)
234                                 goto cleanup;
235                         tail++;
236                 }
237                 archive_entry_set_pathname(entry, tail);
238         }
239 #endif
240
241         if (stat(archive_entry_pathname(entry), &extract->st) == 0)
242                 extract->pst = &extract->st;
243
244         if (extract->pst != NULL &&
245             extract->pst->st_dev == a->skip_file_dev &&
246             extract->pst->st_ino == a->skip_file_ino) {
247                 archive_set_error(a, 0, "Refusing to overwrite archive");
248                 ret = ARCHIVE_WARN;
249         } else if (archive_entry_hardlink(entry) != NULL)
250                 ret = extract_hard_link(a, entry, flags);
251         else {
252                 mode = archive_entry_mode(entry);
253                 switch (mode & S_IFMT) {
254                 default:
255                         /* Fall through, as required by POSIX. */
256                 case S_IFREG:
257                         ret = extract_file(a, entry, flags);
258                         break;
259                 case S_IFLNK:   /* Symlink */
260                         ret = extract_symlink(a, entry, flags);
261                         break;
262                 case S_IFCHR:
263                         ret = extract_char_device(a, entry, flags);
264                         break;
265                 case S_IFBLK:
266                         ret = extract_block_device(a, entry, flags);
267                         break;
268                 case S_IFDIR:
269                         ret = extract_dir(a, entry, flags);
270                         break;
271                 case S_IFIFO:
272                         ret = extract_fifo(a, entry, flags);
273                         break;
274                 }
275         }
276
277
278 cleanup:
279 #ifdef HAVE_FCHDIR
280         /* If we changed directory above, restore it here. */
281         if (restore_pwd >= 0 && original_filename != NULL) {
282                 fchdir(restore_pwd);
283                 close(restore_pwd);
284                 archive_entry_copy_pathname(entry, original_filename);
285                 free(original_filename);
286         }
287 #endif
288
289         return (ret);
290 }
291
292 /*
293  * Cleanup function for archive_extract.  Mostly, this involves processing
294  * the fixup list, which is used to address a number of problems:
295  *   * Dir permissions might prevent us from restoring a file in that
296  *     dir, so we restore the dir 0700 first, then correct the
297  *     mode at the end.
298  *   * Similarly, the act of restoring a file touches the directory
299  *     and changes the timestamp on the dir, so we have to touch-up dir
300  *     timestamps at the end as well.
301  *   * Some file flags can interfere with the restore by, for example,
302  *     preventing the creation of hardlinks to those files.
303  *
304  * Note that tar/cpio do not require that archives be in a particular
305  * order; there is no way to know when the last file has been restored
306  * within a directory, so there's no way to optimize the memory usage
307  * here by fixing up the directory any earlier than the
308  * end-of-archive.
309  *
310  * XXX TODO: Directory ACLs should be restored here, for the same
311  * reason we set directory perms here. XXX
312  *
313  * Registering this function (rather than calling it explicitly by
314  * name from archive_read_finish) reduces static link pollution, since
315  * applications that don't use this API won't get this file linked in.
316  */
317 static void
318 archive_extract_cleanup(struct archive *a)
319 {
320         struct fixup_entry *next, *p;
321         struct extract *extract;
322
323         /* Sort dir list so directories are fixed up in depth-first order. */
324         extract = a->extract;
325         p = sort_dir_list(extract->fixup_list);
326
327         while (p != NULL) {
328                 extract->pst = NULL; /* Mark stat cache as out-of-date. */
329                 if (p->fixup & FIXUP_TIMES) {
330                         struct timeval times[2];
331                         times[1].tv_sec = p->mtime;
332                         times[1].tv_usec = p->mtime_nanos / 1000;
333                         times[0].tv_sec = p->atime;
334                         times[0].tv_usec = p->atime_nanos / 1000;
335                         utimes(p->name, times);
336                 }
337                 if (p->fixup & FIXUP_MODE)
338                         chmod(p->name, p->mode);
339
340                 if (p->fixup & FIXUP_FFLAGS)
341                         set_fflags(a, -1, p->name, p->mode, p->fflags_set, 0);
342
343                 next = p->next;
344                 free(p->name);
345                 free(p);
346                 p = next;
347         }
348         extract->fixup_list = NULL;
349         archive_string_free(&extract->create_parent_dir);
350         free(a->extract);
351         a->extract = NULL;
352 }
353
354 /*
355  * Simple O(n log n) merge sort to order the fixup list.  In
356  * particular, we want to restore dir timestamps depth-first.
357  */
358 static struct fixup_entry *
359 sort_dir_list(struct fixup_entry *p)
360 {
361         struct fixup_entry *a, *b, *t;
362
363         if (p == NULL)
364                 return (NULL);
365         /* A one-item list is already sorted. */
366         if (p->next == NULL)
367                 return (p);
368
369         /* Step 1: split the list. */
370         t = p;
371         a = p->next->next;
372         while (a != NULL) {
373                 /* Step a twice, t once. */
374                 a = a->next;
375                 if (a != NULL)
376                         a = a->next;
377                 t = t->next;
378         }
379         /* Now, t is at the mid-point, so break the list here. */
380         b = t->next;
381         t->next = NULL;
382         a = p;
383
384         /* Step 2: Recursively sort the two sub-lists. */
385         a = sort_dir_list(a);
386         b = sort_dir_list(b);
387
388         /* Step 3: Merge the returned lists. */
389         /* Pick the first element for the merged list. */
390         if (strcmp(a->name, b->name) > 0) {
391                 t = p = a;
392                 a = a->next;
393         } else {
394                 t = p = b;
395                 b = b->next;
396         }
397
398         /* Always put the later element on the list first. */
399         while (a != NULL && b != NULL) {
400                 if (strcmp(a->name, b->name) > 0) {
401                         t->next = a;
402                         a = a->next;
403                 } else {
404                         t->next = b;
405                         b = b->next;
406                 }
407                 t = t->next;
408         }
409
410         /* Only one list is non-empty, so just splice it on. */
411         if (a != NULL)
412                 t->next = a;
413         if (b != NULL)
414                 t->next = b;
415
416         return (p);
417 }
418
419 /*
420  * Returns a new, initialized fixup entry.
421  *
422  * TODO: Reduce the memory requirements for this list by using a tree
423  * structure rather than a simple list of names.
424  */
425 static struct fixup_entry *
426 new_fixup(struct archive *a, const char *pathname)
427 {
428         struct extract *extract;
429         struct fixup_entry *fe;
430
431         extract = a->extract;
432         fe = malloc(sizeof(struct fixup_entry));
433         if (fe == NULL)
434                 return (NULL);
435         fe->next = extract->fixup_list;
436         extract->fixup_list = fe;
437         fe->fixup = 0;
438         fe->name = strdup(pathname);
439         return (fe);
440 }
441
442 /*
443  * Returns a fixup structure for the current entry.
444  */
445 static struct fixup_entry *
446 current_fixup(struct archive *a, const char *pathname)
447 {
448         struct extract *extract;
449
450         extract = a->extract;
451         if (extract->current_fixup == NULL)
452                 extract->current_fixup = new_fixup(a, pathname);
453         return (extract->current_fixup);
454 }
455
456 static int
457 extract_file(struct archive *a, struct archive_entry *entry, int flags)
458 {
459         struct extract *extract;
460         const char *name;
461         mode_t mode;
462         int fd, r, r2;
463
464         extract = a->extract;
465         name = archive_entry_pathname(entry);
466         mode = archive_entry_mode(entry) & 0777;
467         r = ARCHIVE_OK;
468
469         /*
470          * If we're not supposed to overwrite pre-existing files,
471          * use O_EXCL.  Otherwise, use O_TRUNC.
472          */
473         if (flags & (ARCHIVE_EXTRACT_UNLINK | ARCHIVE_EXTRACT_NO_OVERWRITE))
474                 fd = open(name, O_WRONLY | O_CREAT | O_EXCL, mode);
475         else
476                 fd = open(name, O_WRONLY | O_CREAT | O_TRUNC, mode);
477
478         /* Try removing a pre-existing file. */
479         if (fd < 0 && !(flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
480                 unlink(name);
481                 fd = open(name, O_WRONLY | O_CREAT | O_EXCL, mode);
482         }
483
484         /* Might be a non-existent parent dir; try fixing that. */
485         if (fd < 0) {
486                 create_parent_dir(a, name, flags);
487                 fd = open(name, O_WRONLY | O_CREAT | O_EXCL, mode);
488         }
489         if (fd < 0) {
490                 archive_set_error(a, errno, "Can't open '%s'", name);
491                 return (ARCHIVE_WARN);
492         }
493         r = archive_read_data_into_fd(a, fd);
494         extract->pst = NULL; /* Cached stat data no longer valid. */
495         r2 = restore_metadata(a, fd, entry, flags);
496         close(fd);
497         return (err_combine(r, r2));
498 }
499
500 static int
501 extract_dir(struct archive *a, struct archive_entry *entry, int flags)
502 {
503         struct extract *extract;
504         struct fixup_entry *fe;
505         char *path, *p;
506
507         extract = a->extract;
508         extract->pst = NULL; /* Invalidate cached stat data. */
509
510         /* Copy path to mutable storage. */
511         archive_strcpy(&(extract->create_parent_dir),
512             archive_entry_pathname(entry));
513         path = extract->create_parent_dir.s;
514
515         if (*path == '\0') {
516                 archive_set_error(a, ARCHIVE_ERRNO_MISC,
517                     "Invalid empty pathname");
518                 return (ARCHIVE_WARN);
519         }
520
521         /* Deal with any troublesome trailing path elements. */
522         /* TODO: Someday, generalize this to remove '//' or '/./' from
523          * the middle of paths.  But, it should not compress '..' from
524          * the middle of paths.  It's a feature that restoring
525          * "a/../b" creates both 'a' and 'b' directories. */
526         for (;;) {
527                 /* Locate last element. */
528                 p = strrchr(path, '/');
529                 if (p != NULL)
530                         p++;
531                 else
532                         p = path;
533                 /* Trim trailing '/' unless that's the entire path. */
534                 if (p[0] == '\0' && p - 1 > path) {
535                         p[-1] = '\0';
536                         continue;
537                 }
538                 /* Trim trailing '.' unless that's the entire path. */
539                 if (p > path && p[0] == '.' && p[1] == '\0') {
540                         p[0] = '\0';
541                         continue;
542                 }
543                 /* Just exit on trailing '..'. */
544                 if (p[0] == '.' && p[1] == '.' && p[2] == '\0') {
545                         archive_set_error(a, ARCHIVE_ERRNO_MISC,
546                             "Can't restore directory '..'");
547                         return (ARCHIVE_WARN);
548                 }
549                 break;
550         }
551
552         if (mkdir(path, SECURE_DIR_MODE) == 0)
553                 goto success;
554
555         if (extract->pst == NULL && stat(path, &extract->st) == 0)
556                 extract->pst = &extract->st;
557
558         if (extract->pst != NULL) {
559                 extract->pst = &extract->st;
560                 /* If dir already exists, don't reset permissions. */
561                 if (S_ISDIR(extract->pst->st_mode))
562                         return (ARCHIVE_OK);
563                 /* It exists but isn't a dir. */
564                 if ((flags & ARCHIVE_EXTRACT_UNLINK))
565                         unlink(path);
566         } else {
567                 /* Doesn't already exist; try building the parent path. */
568                 if (create_parent_dir_mutable(a, path, flags) != ARCHIVE_OK)
569                         return (ARCHIVE_WARN);
570         }
571
572         /* One final attempt to create the dir. */
573         if (mkdir(path, SECURE_DIR_MODE) != 0) {
574                 archive_set_error(a, errno, "Can't create directory");
575                 return (ARCHIVE_WARN);
576         }
577
578 success:
579         /* Add this dir to the fixup list. */
580         fe = current_fixup(a, path);
581         fe->fixup |= FIXUP_MODE;
582         fe->mode = archive_entry_mode(entry);
583         if ((flags & ARCHIVE_EXTRACT_PERM) == 0)
584                 fe->mode &= ~extract->umask;
585         if (flags & ARCHIVE_EXTRACT_TIME) {
586                 fe->fixup |= FIXUP_TIMES;
587                 fe->mtime = archive_entry_mtime(entry);
588                 fe->mtime_nanos = archive_entry_mtime_nsec(entry);
589                 fe->atime = archive_entry_atime(entry);
590                 fe->atime_nanos = archive_entry_atime_nsec(entry);
591         }
592         /* For now, set the mode to SECURE_DIR_MODE. */
593         archive_entry_set_mode(entry, SECURE_DIR_MODE);
594         return (restore_metadata(a, -1, entry, flags));
595 }
596
597
598 /*
599  * Create the parent of the specified path.  Copy the provided
600  * path into mutable storage first.
601  */
602 static int
603 create_parent_dir(struct archive *a, const char *path, int flags)
604 {
605         int r;
606
607         /* Copy path to mutable storage. */
608         archive_strcpy(&(a->extract->create_parent_dir), path);
609         r = create_parent_dir_mutable(a, a->extract->create_parent_dir.s, flags);
610         return (r);
611 }
612
613 /*
614  * Like create_parent_dir, but creates the dir actually requested, not
615  * the parent.
616  */
617 static int
618 create_dir(struct archive *a, const char *path, int flags)
619 {
620         int r;
621         /* Copy path to mutable storage. */
622         archive_strcpy(&(a->extract->create_parent_dir), path);
623         r = create_dir_mutable(a, a->extract->create_parent_dir.s, flags);
624         return (r);
625 }
626
627 /*
628  * Create the parent directory of the specified path, assuming path
629  * is already in mutable storage.
630  */
631 static int
632 create_parent_dir_mutable(struct archive *a, char *path, int flags)
633 {
634         char *slash;
635         int r;
636
637         /* Remove tail element to obtain parent name. */
638         slash = strrchr(path, '/');
639         if (slash == NULL)
640                 return (ARCHIVE_OK);
641         *slash = '\0';
642         r = create_dir_mutable(a, path, flags);
643         *slash = '/';
644         return (r);
645 }
646
647 /*
648  * Create the specified dir, assuming path is already in
649  * mutable storage.
650  */
651 static int
652 create_dir_mutable(struct archive *a, char *path, int flags)
653 {
654         mode_t old_umask;
655         int r;
656
657         old_umask = umask(~SECURE_DIR_MODE);
658         r = create_dir_recursive(a, path, flags);
659         umask(old_umask);
660         return (r);
661 }
662
663 /*
664  * Create the specified dir, recursing to create parents as necessary.
665  *
666  * Returns ARCHIVE_OK if the path exists when we're done here.
667  * Otherwise, returns ARCHIVE_WARN.
668  */
669 static int
670 create_dir_recursive(struct archive *a, char *path, int flags)
671 {
672         struct stat st;
673         struct extract *extract;
674         struct fixup_entry *le;
675         char *slash, *base;
676         int r;
677
678         extract = a->extract;
679         r = ARCHIVE_OK;
680
681         /* Check for special names and just skip them. */
682         slash = strrchr(path, '/');
683         base = strrchr(path, '/');
684         if (slash == NULL)
685                 base = path;
686         else
687                 base = slash + 1;
688
689         if (base[0] == '\0' ||
690             (base[0] == '.' && base[1] == '\0') ||
691             (base[0] == '.' && base[1] == '.' && base[2] == '\0')) {
692                 /* Don't bother trying to create null path, '.', or '..'. */
693                 if (slash != NULL) {
694                         *slash = '\0';
695                         r = create_dir_recursive(a, path, flags);
696                         *slash = '/';
697                         return (r);
698                 }
699                 return (ARCHIVE_OK);
700         }
701
702         /*
703          * Yes, this should be stat() and not lstat().  Using lstat()
704          * here loses the ability to extract through symlinks.  Also note
705          * that this should not use the extract->st cache.
706          */
707         if (stat(path, &st) == 0) {
708                 if (S_ISDIR(st.st_mode))
709                         return (ARCHIVE_OK);
710                 if ((flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
711                         archive_set_error(a, EEXIST,
712                             "Can't create directory '%s'", path);
713                         return (ARCHIVE_WARN);
714                 }
715                 if (unlink(path) != 0) {
716                         archive_set_error(a, errno,
717                             "Can't create directory '%s': "
718                             "Conflicting file cannot be removed");
719                         return (ARCHIVE_WARN);
720                 }
721         } else if (errno != ENOENT && errno != ENOTDIR) {
722                 /* Stat failed? */
723                 archive_set_error(a, errno, "Can't test directory '%s'", path);
724                 return (ARCHIVE_WARN);
725         } else if (slash != NULL) {
726                 *slash = '\0';
727                 r = create_dir_recursive(a, path, flags);
728                 *slash = '/';
729                 if (r != ARCHIVE_OK)
730                         return (r);
731         }
732
733         if (mkdir(path, SECURE_DIR_MODE) == 0) {
734                 le = new_fixup(a, path);
735                 le->fixup |= FIXUP_MODE;
736                 le->mode = extract->default_dir_mode;
737                 return (ARCHIVE_OK);
738         }
739
740         /*
741          * Without the following check, a/b/../b/c/d fails at the
742          * second visit to 'b', so 'd' can't be created.  Note that we
743          * don't add it to the fixup list here, as it's already been
744          * added.
745          */
746         if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
747                 return (ARCHIVE_OK);
748
749         archive_set_error(a, errno, "Failed to create dir '%s'", path);
750         return (ARCHIVE_WARN);
751 }
752
753 static int
754 extract_hard_link(struct archive *a, struct archive_entry *entry, int flags)
755 {
756         struct extract *extract;
757         int r;
758         const char *pathname;
759         const char *linkname;
760
761         extract = a->extract;
762         pathname = archive_entry_pathname(entry);
763         linkname = archive_entry_hardlink(entry);
764
765         /* Just remove any pre-existing file with this name. */
766         if (!(flags & ARCHIVE_EXTRACT_NO_OVERWRITE))
767                 unlink(pathname);
768
769         r = link(linkname, pathname);
770         extract->pst = NULL; /* Invalidate cached stat data. */
771
772         if (r != 0) {
773                 /* Might be a non-existent parent dir; try fixing that. */
774                 create_parent_dir(a, pathname, flags);
775                 r = link(linkname, pathname);
776         }
777
778         if (r != 0) {
779                 /* XXX Better error message here XXX */
780                 archive_set_error(a, errno,
781                     "Can't restore hardlink to '%s'", linkname);
782                 return (ARCHIVE_WARN);
783         }
784
785         /* Set ownership, time, permission information. */
786         r = restore_metadata(a, -1, entry, flags);
787         return (r);
788 }
789
790 static int
791 extract_symlink(struct archive *a, struct archive_entry *entry, int flags)
792 {
793         struct extract *extract;
794         int r;
795         const char *pathname;
796         const char *linkname;
797
798         extract = a->extract;
799         pathname = archive_entry_pathname(entry);
800         linkname = archive_entry_symlink(entry);
801
802         /* Just remove any pre-existing file with this name. */
803         if (!(flags & ARCHIVE_EXTRACT_NO_OVERWRITE))
804                 unlink(pathname);
805
806         r = symlink(linkname, pathname);
807         extract->pst = NULL; /* Invalidate cached stat data. */
808
809         if (r != 0) {
810                 /* Might be a non-existent parent dir; try fixing that. */
811                 create_parent_dir(a, pathname, flags);
812                 r = symlink(linkname, pathname);
813         }
814
815         if (r != 0) {
816                 /* XXX Better error message here XXX */
817                 archive_set_error(a, errno,
818                     "Can't restore symlink to '%s'", linkname);
819                 return (ARCHIVE_WARN);
820         }
821
822         r = restore_metadata(a, -1, entry, flags);
823         return (r);
824 }
825
826 static int
827 extract_device(struct archive *a, struct archive_entry *entry,
828     int flags, mode_t mode)
829 {
830         struct extract *extract;
831         int r;
832
833         extract = a->extract;
834         /* Just remove any pre-existing file with this name. */
835         if (!(flags & ARCHIVE_EXTRACT_NO_OVERWRITE))
836                 unlink(archive_entry_pathname(entry));
837
838         r = mknod(archive_entry_pathname(entry), mode,
839             archive_entry_rdev(entry));
840         extract->pst = NULL; /* Invalidate cached stat data. */
841
842         /* Might be a non-existent parent dir; try fixing that. */
843         if (r != 0 && errno == ENOENT) {
844                 create_parent_dir(a, archive_entry_pathname(entry), flags);
845                 r = mknod(archive_entry_pathname(entry), mode,
846                     archive_entry_rdev(entry));
847         }
848
849         if (r != 0) {
850                 archive_set_error(a, errno, "Can't restore device node");
851                 return (ARCHIVE_WARN);
852         }
853
854         r = restore_metadata(a, -1, entry, flags);
855         return (r);
856 }
857
858 static int
859 extract_char_device(struct archive *a, struct archive_entry *entry, int flags)
860 {
861         mode_t mode;
862
863         mode = (archive_entry_mode(entry) & ~S_IFMT) | S_IFCHR;
864         return (extract_device(a, entry, flags, mode));
865 }
866
867 static int
868 extract_block_device(struct archive *a, struct archive_entry *entry, int flags)
869 {
870         mode_t mode;
871
872         mode = (archive_entry_mode(entry) & ~S_IFMT) | S_IFBLK;
873         return (extract_device(a, entry, flags, mode));
874 }
875
876 static int
877 extract_fifo(struct archive *a, struct archive_entry *entry, int flags)
878 {
879         struct extract *extract;
880         int r;
881
882         extract = a->extract;
883         /* Just remove any pre-existing file with this name. */
884         if (!(flags & ARCHIVE_EXTRACT_NO_OVERWRITE))
885                 unlink(archive_entry_pathname(entry));
886
887         r = mkfifo(archive_entry_pathname(entry),
888             archive_entry_mode(entry));
889         extract->pst = NULL; /* Invalidate cached stat data. */
890
891         /* Might be a non-existent parent dir; try fixing that. */
892         if (r != 0 && errno == ENOENT) {
893                 create_parent_dir(a, archive_entry_pathname(entry), flags);
894                 r = mkfifo(archive_entry_pathname(entry),
895                     archive_entry_mode(entry));
896         }
897
898         if (r != 0) {
899                 archive_set_error(a, errno, "Can't restore fifo");
900                 return (ARCHIVE_WARN);
901         }
902
903         r = restore_metadata(a, -1, entry, flags);
904         return (r);
905 }
906
907 static int
908 restore_metadata(struct archive *a, int fd, struct archive_entry *entry, int flags)
909 {
910         int r, r2;
911
912         r = set_ownership(a, fd, entry, flags);
913         r2 = set_time(a, fd, entry, flags);
914         r = err_combine(r, r2);
915         r2 = set_perm(a, fd, entry, archive_entry_mode(entry), flags);
916         return (err_combine(r, r2));
917 }
918
919 static int
920 set_ownership(struct archive *a, int fd,
921     struct archive_entry *entry, int flags)
922 {
923         uid_t uid;
924         gid_t gid;
925
926         /* Not changed. */
927         if ((flags & ARCHIVE_EXTRACT_OWNER) == 0)
928                 return (ARCHIVE_OK);
929
930         uid = lookup_uid(a, archive_entry_uname(entry),
931             archive_entry_uid(entry));
932         gid = lookup_gid(a, archive_entry_gname(entry),
933             archive_entry_gid(entry));
934
935         /* If we know we can't change it, don't bother trying. */
936         if (a->user_uid != 0  &&  a->user_uid != uid)
937                 return (ARCHIVE_OK);
938
939 #ifdef HAVE_FCHOWN
940         if (fd >= 0 && fchown(fd, uid, gid) == 0)
941                 return (ARCHIVE_OK);
942 #endif
943
944 #ifdef HAVE_LCHOWN
945         if (lchown(archive_entry_pathname(entry), uid, gid))
946 #else
947         if (!S_ISLNK(archive_entry_mode(entry))
948             && chown(archive_entry_pathname(entry), uid, gid) != 0)
949 #endif
950         {
951                 archive_set_error(a, errno,
952                     "Can't set user=%d/group=%d for %s", uid, gid,
953                     archive_entry_pathname(entry));
954                 return (ARCHIVE_WARN);
955         }
956         return (ARCHIVE_OK);
957 }
958
959 static int
960 set_time(struct archive *a, int fd, struct archive_entry *entry, int flags)
961 {
962         const struct stat *st;
963         struct timeval times[2];
964
965         (void)a; /* UNUSED */
966         st = archive_entry_stat(entry);
967
968         if ((flags & ARCHIVE_EXTRACT_TIME) == 0)
969                 return (ARCHIVE_OK);
970         /* It's a waste of time to mess with dir timestamps here. */
971         if (S_ISDIR(archive_entry_mode(entry)))
972                 return (ARCHIVE_OK);
973
974         times[1].tv_sec = st->st_mtime;
975         times[1].tv_usec = ARCHIVE_STAT_MTIME_NANOS(st) / 1000;
976
977         times[0].tv_sec = st->st_atime;
978         times[0].tv_usec = ARCHIVE_STAT_ATIME_NANOS(st) / 1000;
979
980 #ifdef HAVE_FUTIMES
981         if (fd >= 0 && futimes(fd, times) == 0)
982                 return (ARCHIVE_OK);
983 #endif
984
985 #ifdef HAVE_LUTIMES
986         if (lutimes(archive_entry_pathname(entry), times) != 0) {
987 #else
988         if ((archive_entry_mode(entry) & S_IFMT) != S_IFLNK &&
989             utimes(archive_entry_pathname(entry), times) != 0) {
990 #endif
991                 archive_set_error(a, errno, "Can't update time for %s",
992                     archive_entry_pathname(entry));
993                 return (ARCHIVE_WARN);
994         }
995
996         /*
997          * Note: POSIX does not provide a portable way to restore ctime.
998          * (Apart from resetting the system clock, which is distasteful.)
999          * So, any restoration of ctime will necessarily be OS-specific.
1000          */
1001
1002         /* XXX TODO: Can FreeBSD restore ctime? XXX */
1003
1004         return (ARCHIVE_OK);
1005 }
1006
1007 static int
1008 set_perm(struct archive *a, int fd, struct archive_entry *entry,
1009     int mode, int flags)
1010 {
1011         struct extract *extract;
1012         struct fixup_entry *le;
1013         const char *name;
1014         unsigned long    set, clear;
1015         int              r;
1016         int              critical_flags;
1017
1018         extract = a->extract;
1019
1020         /* Obey umask unless ARCHIVE_EXTRACT_PERM. */
1021         if ((flags & ARCHIVE_EXTRACT_PERM) == 0)
1022                 mode &= ~extract->umask; /* Enforce umask. */
1023         name = archive_entry_pathname(entry);
1024
1025         if (mode & (S_ISUID | S_ISGID)) {
1026                 if (extract->pst != NULL) {
1027                         /* Already have stat() data available. */
1028 #ifdef HAVE_FSTAT
1029                 } else if (fd >= 0 && fstat(fd, &extract->st) == 0) {
1030                         extract->pst = &extract->st;
1031 #endif
1032                 } else if (stat(name, &extract->st) == 0) {
1033                         extract->pst = &extract->st;
1034                 } else {
1035                         archive_set_error(a, errno,
1036                             "Couldn't stat file");
1037                         return (ARCHIVE_WARN);
1038                 }
1039
1040                 /*
1041                  * TODO: Use the uid/gid looked up in set_ownership
1042                  * above rather than the uid/gid stored in the entry.
1043                  */
1044                 if (extract->pst->st_uid != archive_entry_uid(entry))
1045                         mode &= ~ S_ISUID;
1046                 if (extract->pst->st_gid != archive_entry_gid(entry))
1047                         mode &= ~ S_ISGID;
1048         }
1049
1050         /*
1051          * Ensure we change permissions on the object we extracted,
1052          * and not any incidental symlink that might have gotten in
1053          * the way.
1054          */
1055         if (!S_ISLNK(archive_entry_mode(entry))) {
1056 #ifdef HAVE_FCHMOD
1057                 if (fd >= 0) {
1058                         if (fchmod(fd, mode) != 0) {
1059                                 archive_set_error(a, errno,
1060                                     "Can't set permissions");
1061                                 return (ARCHIVE_WARN);
1062                         }
1063                 } else
1064 #endif
1065                 if (chmod(name, mode) != 0) {
1066                         archive_set_error(a, errno, "Can't set permissions");
1067                         return (ARCHIVE_WARN);
1068                 }
1069 #ifdef HAVE_LCHMOD
1070         } else {
1071                 /*
1072                  * If lchmod() isn't supported, it's no big deal.
1073                  * Permissions on symlinks are actually ignored on
1074                  * most platforms.
1075                  */
1076                 if (lchmod(name, mode) != 0) {
1077                         archive_set_error(a, errno, "Can't set permissions");
1078                         return (ARCHIVE_WARN);
1079                 }
1080 #endif
1081         }
1082
1083         if (flags & ARCHIVE_EXTRACT_ACL) {
1084                 r = set_acls(a, fd, entry);
1085                 if (r != ARCHIVE_OK)
1086                         return (r);
1087         }
1088
1089         /*
1090          * Make 'critical_flags' hold all file flags that can't be
1091          * immediately restored.  For example, on BSD systems,
1092          * SF_IMMUTABLE prevents hardlinks from being created, so
1093          * should not be set until after any hardlinks are created.  To
1094          * preserve some semblance of portability, this uses #ifdef
1095          * extensively.  Ugly, but it works.
1096          *
1097          * Yes, Virginia, this does create a security race.  It's mitigated
1098          * somewhat by the practice of creating dirs 0700 until the extract
1099          * is done, but it would be nice if we could do more than that.
1100          * People restoring critical file systems should be wary of
1101          * other programs that might try to muck with files as they're
1102          * being restored.
1103          */
1104         /* Hopefully, the compiler will optimize this mess into a constant. */
1105         critical_flags = 0;
1106 #ifdef SF_IMMUTABLE
1107         critical_flags |= SF_IMMUTABLE;
1108 #endif
1109 #ifdef UF_IMMUTABLE
1110         critical_flags |= UF_IMMUTABLE;
1111 #endif
1112 #ifdef SF_APPEND
1113         critical_flags |= SF_APPEND;
1114 #endif
1115 #ifdef UF_APPEND
1116         critical_flags |= UF_APPEND;
1117 #endif
1118 #ifdef EXT2_APPEND_FL
1119         critical_flags |= EXT2_APPEND_FL;
1120 #endif
1121 #ifdef EXT2_IMMUTABLE_FL
1122         critical_flags |= EXT2_IMMUTABLE_FL;
1123 #endif
1124
1125         if (flags & ARCHIVE_EXTRACT_FFLAGS) {
1126                 archive_entry_fflags(entry, &set, &clear);
1127
1128                 /*
1129                  * The first test encourages the compiler to eliminate
1130                  * all of this if it's not necessary.
1131                  */
1132                 if ((critical_flags != 0)  &&  (set & critical_flags)) {
1133                         le = current_fixup(a, archive_entry_pathname(entry));
1134                         le->fixup |= FIXUP_FFLAGS;
1135                         le->fflags_set = set;
1136                         /* Store the mode if it's not already there. */
1137                         if ((le->fixup & FIXUP_MODE) == 0)
1138                                 le->mode = mode;
1139                 } else {
1140                         r = set_fflags(a, fd, archive_entry_pathname(entry),
1141                             mode, set, clear);
1142                         if (r != ARCHIVE_OK)
1143                                 return (r);
1144                 }
1145         }
1146         return (ARCHIVE_OK);
1147 }
1148
1149
1150 #if ( defined(HAVE_LCHFLAGS) || defined(HAVE_CHFLAGS) || defined(HAVE_FCHFLAGS) ) && !defined(__linux)
1151 static int
1152 set_fflags(struct archive *a, int fd, const char *name, mode_t mode,
1153     unsigned long set, unsigned long clear)
1154 {
1155         struct extract *extract;
1156
1157         extract = a->extract;
1158         if (set == 0  && clear == 0)
1159                 return (ARCHIVE_OK);
1160
1161         (void)mode; /* UNUSED */
1162         /*
1163          * XXX Is the stat here really necessary?  Or can I just use
1164          * the 'set' flags directly?  In particular, I'm not sure
1165          * about the correct approach if we're overwriting an existing
1166          * file that already has flags on it. XXX
1167          */
1168         if (extract->pst != NULL) {
1169                 /* Already have stat() data available. */
1170         } else if (fd >= 0 && fstat(fd, &extract->st) == 0)
1171                 extract->pst = &extract->st;
1172         else if (stat(name, &extract->st) == 0)
1173                 extract->pst = &extract->st;
1174         else {
1175                 archive_set_error(a, errno,
1176                     "Couldn't stat file");
1177                 return (ARCHIVE_WARN);
1178         }
1179
1180         extract->st.st_flags &= ~clear;
1181         extract->st.st_flags |= set;
1182 #ifdef HAVE_FCHFLAGS
1183         /* If platform has fchflags() and we were given an fd, use it. */
1184         if (fd >= 0 && fchflags(fd, extract->st.st_flags) == 0)
1185                 return (ARCHIVE_OK);
1186 #endif
1187         /*
1188          * If we can't use the fd to set the flags, we'll use the
1189          * pathname to set flags.  We prefer lchflags() but will use
1190          * chflags() if we must.
1191          */
1192 #ifdef HAVE_LCHFLAGS
1193         if (lchflags(name, extract->st.st_flags) == 0)
1194                 return (ARCHIVE_OK);
1195 #elif defined(HAVE_CHFLAGS)
1196         if (chflags(name, extract->st.st_flags) == 0)
1197                 return (ARCHIVE_OK);
1198 #endif
1199         archive_set_error(a, errno,
1200             "Failed to set file flags");
1201         return (ARCHIVE_WARN);
1202 }
1203
1204 #elif defined(__linux)
1205
1206 /*
1207  * Linux has flags too, but uses ioctl() to access them instead of
1208  * having a separate chflags() system call.
1209  */
1210 static int
1211 set_fflags(struct archive *a, int fd, const char *name, mode_t mode,
1212     unsigned long set, unsigned long clear)
1213 {
1214         struct extract *extract;
1215         int              ret;
1216         int              myfd = fd;
1217         int              err;
1218         unsigned long newflags, oldflags;
1219
1220         extract = a->extract;
1221         if (set == 0  && clear == 0)
1222                 return (ARCHIVE_OK);
1223         /* Only regular files and dirs can have flags. */
1224         if (!S_ISREG(mode) && !S_ISDIR(mode))
1225                 return (ARCHIVE_OK);
1226
1227         /* If we weren't given an fd, open it ourselves. */
1228         if (myfd < 0)
1229                 myfd = open(name, O_RDONLY|O_NONBLOCK);
1230         if (myfd < 0)
1231                 return (ARCHIVE_OK);
1232
1233         /*
1234          * Linux has no define for the flags that are only settable
1235          * by the root user...
1236          */
1237 #define SF_MASK                 (EXT2_IMMUTABLE_FL|EXT2_APPEND_FL)
1238         /*
1239          * XXX As above, this would be way simpler if we didn't have
1240          * to read the current flags from disk. XXX
1241          */
1242         ret = ARCHIVE_OK;
1243         /* Try setting the flags as given. */
1244         if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) >= 0) {
1245                 newflags = (oldflags & ~clear) | set;
1246                 if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
1247                         goto cleanup;
1248                 if (errno != EPERM)
1249                         goto fail;
1250         }
1251         /* If we couldn't set all the flags, try again with a subset. */
1252         if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) >= 0) {
1253                 newflags &= ~SF_MASK;
1254                 oldflags &= SF_MASK;
1255                 newflags |= oldflags;
1256                 if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
1257                         goto cleanup;
1258         }
1259         /* We couldn't set the flags, so report the failure. */
1260 fail:
1261         archive_set_error(a, errno,
1262             "Failed to set file flags");
1263         ret = ARCHIVE_WARN;
1264 cleanup:
1265         if (fd < 0)
1266                 close(myfd);
1267         return (ret);
1268 }
1269
1270 #else /* Not HAVE_CHFLAGS && Not __linux */
1271
1272 /*
1273  * Of course, some systems have neither BSD chflags() nor Linux' flags
1274  * support through ioctl().
1275  */
1276 static int
1277 set_fflags(struct archive *a, int fd, const char *name, mode_t mode,
1278     unsigned long set, unsigned long clear)
1279 {
1280         (void)a;
1281         (void)fd;
1282         (void)name;
1283         (void)mode;
1284         (void)set;
1285         (void)clear;
1286         return (ARCHIVE_OK);
1287 }
1288
1289 #endif /* __linux */
1290
1291 #ifndef HAVE_POSIX_ACL
1292 /* Default empty function body to satisfy mainline code. */
1293 static int
1294 set_acls(struct archive *a, int fd, struct archive_entry *entry)
1295 {
1296         (void)a;
1297         (void)fd;
1298         (void)entry;
1299
1300         return (ARCHIVE_OK);
1301 }
1302
1303 #else
1304
1305 /*
1306  * XXX TODO: What about ACL types other than ACCESS and DEFAULT?
1307  */
1308 static int
1309 set_acls(struct archive *a, int fd, struct archive_entry *entry)
1310 {
1311         int              ret;
1312
1313         ret = set_acl(a, fd, entry, ACL_TYPE_ACCESS,
1314             ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
1315         if (ret != ARCHIVE_OK)
1316                 return (ret);
1317         ret = set_acl(a, fd, entry, ACL_TYPE_DEFAULT,
1318             ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
1319         return (ret);
1320 }
1321
1322
1323 static int
1324 set_acl(struct archive *a, int fd, struct archive_entry *entry,
1325     acl_type_t acl_type, int ae_requested_type, const char *typename)
1326 {
1327         acl_t            acl;
1328         acl_entry_t      acl_entry;
1329         acl_permset_t    acl_permset;
1330         int              ret;
1331         int              ae_type, ae_permset, ae_tag, ae_id;
1332         uid_t            ae_uid;
1333         gid_t            ae_gid;
1334         const char      *ae_name;
1335         int              entries;
1336         const char      *name;
1337
1338         ret = ARCHIVE_OK;
1339         entries = archive_entry_acl_reset(entry, ae_requested_type);
1340         if (entries == 0)
1341                 return (ARCHIVE_OK);
1342         acl = acl_init(entries);
1343         while (archive_entry_acl_next(entry, ae_requested_type, &ae_type,
1344                    &ae_permset, &ae_tag, &ae_id, &ae_name) == ARCHIVE_OK) {
1345                 acl_create_entry(&acl, &acl_entry);
1346
1347                 switch (ae_tag) {
1348                 case ARCHIVE_ENTRY_ACL_USER:
1349                         acl_set_tag_type(acl_entry, ACL_USER);
1350                         ae_uid = lookup_uid(a, ae_name, ae_id);
1351                         acl_set_qualifier(acl_entry, &ae_uid);
1352                         break;
1353                 case ARCHIVE_ENTRY_ACL_GROUP:
1354                         acl_set_tag_type(acl_entry, ACL_GROUP);
1355                         ae_gid = lookup_gid(a, ae_name, ae_id);
1356                         acl_set_qualifier(acl_entry, &ae_gid);
1357                         break;
1358                 case ARCHIVE_ENTRY_ACL_USER_OBJ:
1359                         acl_set_tag_type(acl_entry, ACL_USER_OBJ);
1360                         break;
1361                 case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
1362                         acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
1363                         break;
1364                 case ARCHIVE_ENTRY_ACL_MASK:
1365                         acl_set_tag_type(acl_entry, ACL_MASK);
1366                         break;
1367                 case ARCHIVE_ENTRY_ACL_OTHER:
1368                         acl_set_tag_type(acl_entry, ACL_OTHER);
1369                         break;
1370                 default:
1371                         /* XXX */
1372                         break;
1373                 }
1374
1375                 acl_get_permset(acl_entry, &acl_permset);
1376                 acl_clear_perms(acl_permset);
1377                 if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE)
1378                         acl_add_perm(acl_permset, ACL_EXECUTE);
1379                 if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE)
1380                         acl_add_perm(acl_permset, ACL_WRITE);
1381                 if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
1382                         acl_add_perm(acl_permset, ACL_READ);
1383         }
1384
1385         name = archive_entry_pathname(entry);
1386
1387         /* Try restoring the ACL through 'fd' if we can. */
1388 #if HAVE_ACL_SET_FD
1389         if (fd >= 0 && acl_type == ACL_TYPE_ACCESS && acl_set_fd(fd, acl) == 0)
1390                 ret = ARCHIVE_OK;
1391         else
1392 #endif
1393 #if HAVE_ACL_SET_FD_NP
1394         if (fd >= 0 && acl_set_fd_np(fd, acl, acl_type) == 0)
1395                 ret = ARCHIVE_OK;
1396         else
1397 #endif
1398         if (acl_set_file(name, acl_type, acl) != 0) {
1399                 archive_set_error(a, errno, "Failed to set %s acl", typename);
1400                 ret = ARCHIVE_WARN;
1401         }
1402         acl_free(acl);
1403         return (ret);
1404 }
1405 #endif
1406
1407 /*
1408  * The following routines do some basic caching of uname/gname lookups.
1409  * All such lookups go through these routines, including ACL conversions.
1410  *
1411  * TODO: Provide an API for clients to override these routines.
1412  */
1413 static gid_t
1414 lookup_gid(struct archive *a, const char *gname, gid_t gid)
1415 {
1416         struct group    *grent;
1417         struct extract *extract;
1418         int h;
1419         struct bucket *b;
1420         int cache_size;
1421
1422         extract = a->extract;
1423         cache_size = sizeof(extract->gcache) / sizeof(extract->gcache[0]);
1424
1425         /* If no gname, just use the gid provided. */
1426         if (gname == NULL || *gname == '\0')
1427                 return (gid);
1428
1429         /* Try to find gname in the cache. */
1430         h = hash(gname);
1431         b = &extract->gcache[h % cache_size ];
1432         if (b->name != NULL && b->hash == h && strcmp(gname, b->name) == 0)
1433                 return ((gid_t)b->id);
1434
1435         /* Free the cache slot for a new entry. */
1436         if (b->name != NULL)
1437                 free(b->name);
1438         b->name = strdup(gname);
1439         /* Note: If strdup fails, that's okay; we just won't cache. */
1440         b->hash = h;
1441         grent = getgrnam(gname);
1442         if (grent != NULL)
1443                 gid = grent->gr_gid;
1444         b->id = gid;
1445
1446         return (gid);
1447 }
1448
1449 static uid_t
1450 lookup_uid(struct archive *a, const char *uname, uid_t uid)
1451 {
1452         struct passwd   *pwent;
1453         struct extract *extract;
1454         int h;
1455         struct bucket *b;
1456         int cache_size;
1457
1458         extract = a->extract;
1459         cache_size = sizeof(extract->ucache) / sizeof(extract->ucache[0]);
1460
1461         /* If no uname, just use the uid provided. */
1462         if (uname == NULL || *uname == '\0')
1463                 return (uid);
1464
1465         /* Try to find uname in the cache. */
1466         h = hash(uname);
1467         b = &extract->ucache[h % cache_size ];
1468         if (b->name != NULL && b->hash == h && strcmp(uname, b->name) == 0)
1469                 return ((uid_t)b->id);
1470
1471         /* Free the cache slot for a new entry. */
1472         if (b->name != NULL)
1473                 free(b->name);
1474         b->name = strdup(uname);
1475         /* Note: If strdup fails, that's okay; we just won't cache. */
1476         b->hash = h;
1477         pwent = getpwnam(uname);
1478         if (pwent != NULL)
1479                 uid = pwent->pw_uid;
1480         b->id = uid;
1481
1482         return (uid);
1483 }
1484
1485 static unsigned int
1486 hash(const char *p)
1487 {
1488   /* A 32-bit version of Peter Weinberger's (PJW) hash algorithm,
1489      as used by ELF for hashing function names. */
1490   unsigned g,h = 0;
1491   while(*p != '\0') {
1492     h = ( h << 4 ) + *p++;
1493     if (( g = h & 0xF0000000 )) {
1494       h ^= g >> 24;
1495       h &= 0x0FFFFFFF;
1496     }
1497   }
1498   return h;
1499 }
1500
1501 void
1502 archive_read_extract_set_progress_callback(struct archive *a,
1503     void (*progress_func)(void *), void *user_data)
1504 {
1505         a->extract_progress = progress_func;
1506         a->extract_progress_user_data = user_data;
1507 }