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