~ubuntu-branches/ubuntu/quantal/libarchive/quantal

« back to all changes in this revision

Viewing changes to libarchive/archive_write_disk_posix.c

  • Committer: Package Import Robot
  • Author(s): Andres Mejia
  • Date: 2012-02-23 19:29:24 UTC
  • mfrom: (8.1.10 sid)
  • Revision ID: package-import@ubuntu.com-20120223192924-73n4iedok5fwgsyr
Tags: 3.0.3-5
* Detect if locales or locales-all is installed for use with test suite.
* Bump Standards-Version to 3.9.3.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-
 
2
 * Copyright (c) 2003-2010 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
#if !defined(_WIN32) || defined(__CYGWIN__)
 
31
 
 
32
#ifdef HAVE_SYS_TYPES_H
 
33
#include <sys/types.h>
 
34
#endif
 
35
#ifdef HAVE_SYS_ACL_H
 
36
#include <sys/acl.h>
 
37
#endif
 
38
#ifdef HAVE_SYS_EXTATTR_H
 
39
#include <sys/extattr.h>
 
40
#endif
 
41
#ifdef HAVE_SYS_XATTR_H
 
42
#include <sys/xattr.h>
 
43
#endif
 
44
#ifdef HAVE_SYS_EA_H
 
45
#include <sys/ea.h>
 
46
#endif
 
47
#ifdef HAVE_ATTR_XATTR_H
 
48
#include <attr/xattr.h>
 
49
#endif
 
50
#ifdef HAVE_SYS_IOCTL_H
 
51
#include <sys/ioctl.h>
 
52
#endif
 
53
#ifdef HAVE_SYS_STAT_H
 
54
#include <sys/stat.h>
 
55
#endif
 
56
#ifdef HAVE_SYS_TIME_H
 
57
#include <sys/time.h>
 
58
#endif
 
59
#ifdef HAVE_SYS_UTIME_H
 
60
#include <sys/utime.h>
 
61
#endif
 
62
#ifdef HAVE_COPYFILE_H
 
63
#include <copyfile.h>
 
64
#endif
 
65
#ifdef HAVE_ERRNO_H
 
66
#include <errno.h>
 
67
#endif
 
68
#ifdef HAVE_FCNTL_H
 
69
#include <fcntl.h>
 
70
#endif
 
71
#ifdef HAVE_GRP_H
 
72
#include <grp.h>
 
73
#endif
 
74
#ifdef HAVE_LANGINFO_H
 
75
#include <langinfo.h>
 
76
#endif
 
77
#ifdef HAVE_LINUX_FS_H
 
78
#include <linux/fs.h>   /* for Linux file flags */
 
79
#endif
 
80
/*
 
81
 * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h.
 
82
 * As the include guards don't agree, the order of include is important.
 
83
 */
 
84
#ifdef HAVE_LINUX_EXT2_FS_H
 
85
#include <linux/ext2_fs.h>      /* for Linux file flags */
 
86
#endif
 
87
#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__)
 
88
#include <ext2fs/ext2_fs.h>     /* Linux file flags, broken on Cygwin */
 
89
#endif
 
90
#ifdef HAVE_LIMITS_H
 
91
#include <limits.h>
 
92
#endif
 
93
#ifdef HAVE_PWD_H
 
94
#include <pwd.h>
 
95
#endif
 
96
#include <stdio.h>
 
97
#ifdef HAVE_STDLIB_H
 
98
#include <stdlib.h>
 
99
#endif
 
100
#ifdef HAVE_STRING_H
 
101
#include <string.h>
 
102
#endif
 
103
#ifdef HAVE_UNISTD_H
 
104
#include <unistd.h>
 
105
#endif
 
106
#ifdef HAVE_UTIME_H
 
107
#include <utime.h>
 
108
#endif
 
109
#ifdef F_GETTIMES /* Tru64 specific */
 
110
#include <sys/fcntl1.h>
 
111
#endif
 
112
 
 
113
#if __APPLE__
 
114
#include <TargetConditionals.h>
 
115
#if TARGET_OS_MAC && !TARGET_OS_EMBEDDED && HAVE_QUARANTINE_H
 
116
#include <quarantine.h>
 
117
#define HAVE_QUARANTINE 1
 
118
#endif
 
119
#endif
 
120
 
 
121
/* TODO: Support Mac OS 'quarantine' feature.  This is really just a
 
122
 * standard tag to mark files that have been downloaded as "tainted".
 
123
 * On Mac OS, we should mark the extracted files as tainted if the
 
124
 * archive being read was tainted.  Windows has a similar feature; we
 
125
 * should investigate ways to support this generically. */
 
126
 
 
127
#include "archive.h"
 
128
#include "archive_acl_private.h"
 
129
#include "archive_string.h"
 
130
#include "archive_entry.h"
 
131
#include "archive_private.h"
 
132
 
 
133
#ifndef O_BINARY
 
134
#define O_BINARY 0
 
135
#endif
 
136
 
 
137
struct fixup_entry {
 
138
        struct fixup_entry      *next;
 
139
        struct archive_acl       acl;
 
140
        mode_t                   mode;
 
141
        int64_t                  atime;
 
142
        int64_t                  birthtime;
 
143
        int64_t                  mtime;
 
144
        int64_t                  ctime;
 
145
        unsigned long            atime_nanos;
 
146
        unsigned long            birthtime_nanos;
 
147
        unsigned long            mtime_nanos;
 
148
        unsigned long            ctime_nanos;
 
149
        unsigned long            fflags_set;
 
150
        size_t                   mac_metadata_size;
 
151
        void                    *mac_metadata;
 
152
        int                      fixup; /* bitmask of what needs fixing */
 
153
        char                    *name;
 
154
};
 
155
 
 
156
/*
 
157
 * We use a bitmask to track which operations remain to be done for
 
158
 * this file.  In particular, this helps us avoid unnecessary
 
159
 * operations when it's possible to take care of one step as a
 
160
 * side-effect of another.  For example, mkdir() can specify the mode
 
161
 * for the newly-created object but symlink() cannot.  This means we
 
162
 * can skip chmod() if mkdir() succeeded, but we must explicitly
 
163
 * chmod() if we're trying to create a directory that already exists
 
164
 * (mkdir() failed) or if we're restoring a symlink.  Similarly, we
 
165
 * need to verify UID/GID before trying to restore SUID/SGID bits;
 
166
 * that verification can occur explicitly through a stat() call or
 
167
 * implicitly because of a successful chown() call.
 
168
 */
 
169
#define TODO_MODE_FORCE         0x40000000
 
170
#define TODO_MODE_BASE          0x20000000
 
171
#define TODO_SUID               0x10000000
 
172
#define TODO_SUID_CHECK         0x08000000
 
173
#define TODO_SGID               0x04000000
 
174
#define TODO_SGID_CHECK         0x02000000
 
175
#define TODO_MODE               (TODO_MODE_BASE|TODO_SUID|TODO_SGID)
 
176
#define TODO_TIMES              ARCHIVE_EXTRACT_TIME
 
177
#define TODO_OWNER              ARCHIVE_EXTRACT_OWNER
 
178
#define TODO_FFLAGS             ARCHIVE_EXTRACT_FFLAGS
 
179
#define TODO_ACLS               ARCHIVE_EXTRACT_ACL
 
180
#define TODO_XATTR              ARCHIVE_EXTRACT_XATTR
 
181
#define TODO_MAC_METADATA       ARCHIVE_EXTRACT_MAC_METADATA
 
182
 
 
183
struct archive_write_disk {
 
184
        struct archive  archive;
 
185
 
 
186
        mode_t                   user_umask;
 
187
        struct fixup_entry      *fixup_list;
 
188
        struct fixup_entry      *current_fixup;
 
189
        int64_t                  user_uid;
 
190
        int                      skip_file_set;
 
191
        dev_t                    skip_file_dev;
 
192
        ino_t                    skip_file_ino;
 
193
        time_t                   start_time;
 
194
 
 
195
        int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid);
 
196
        void  (*cleanup_gid)(void *private);
 
197
        void                    *lookup_gid_data;
 
198
        int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid);
 
199
        void  (*cleanup_uid)(void *private);
 
200
        void                    *lookup_uid_data;
 
201
 
 
202
        /*
 
203
         * Full path of last file to satisfy symlink checks.
 
204
         */
 
205
        struct archive_string   path_safe;
 
206
 
 
207
        /*
 
208
         * Cached stat data from disk for the current entry.
 
209
         * If this is valid, pst points to st.  Otherwise,
 
210
         * pst is null.
 
211
         */
 
212
        struct stat              st;
 
213
        struct stat             *pst;
 
214
 
 
215
        /* Information about the object being restored right now. */
 
216
        struct archive_entry    *entry; /* Entry being extracted. */
 
217
        char                    *name; /* Name of entry, possibly edited. */
 
218
        struct archive_string    _name_data; /* backing store for 'name' */
 
219
        /* Tasks remaining for this object. */
 
220
        int                      todo;
 
221
        /* Tasks deferred until end-of-archive. */
 
222
        int                      deferred;
 
223
        /* Options requested by the client. */
 
224
        int                      flags;
 
225
        /* Handle for the file we're restoring. */
 
226
        int                      fd;
 
227
        /* Current offset for writing data to the file. */
 
228
        int64_t                  offset;
 
229
        /* Last offset actually written to disk. */
 
230
        int64_t                  fd_offset;
 
231
        /* Total bytes actually written to files. */
 
232
        int64_t                  total_bytes_written;
 
233
        /* Maximum size of file, -1 if unknown. */
 
234
        int64_t                  filesize;
 
235
        /* Dir we were in before this restore; only for deep paths. */
 
236
        int                      restore_pwd;
 
237
        /* Mode we should use for this entry; affected by _PERM and umask. */
 
238
        mode_t                   mode;
 
239
        /* UID/GID to use in restoring this entry. */
 
240
        int64_t                  uid;
 
241
        int64_t                  gid;
 
242
};
 
243
 
 
244
/*
 
245
 * Default mode for dirs created automatically (will be modified by umask).
 
246
 * Note that POSIX specifies 0777 for implicitly-created dirs, "modified
 
247
 * by the process' file creation mask."
 
248
 */
 
249
#define DEFAULT_DIR_MODE 0777
 
250
/*
 
251
 * Dir modes are restored in two steps:  During the extraction, the permissions
 
252
 * in the archive are modified to match the following limits.  During
 
253
 * the post-extract fixup pass, the permissions from the archive are
 
254
 * applied.
 
255
 */
 
256
#define MINIMUM_DIR_MODE 0700
 
257
#define MAXIMUM_DIR_MODE 0775
 
258
 
 
259
static int      check_symlinks(struct archive_write_disk *);
 
260
static int      create_filesystem_object(struct archive_write_disk *);
 
261
static struct fixup_entry *current_fixup(struct archive_write_disk *, const char *pathname);
 
262
#if defined(HAVE_FCHDIR) && defined(PATH_MAX)
 
263
static void     edit_deep_directories(struct archive_write_disk *ad);
 
264
#endif
 
265
static int      cleanup_pathname(struct archive_write_disk *);
 
266
static int      create_dir(struct archive_write_disk *, char *);
 
267
static int      create_parent_dir(struct archive_write_disk *, char *);
 
268
static int      older(struct stat *, struct archive_entry *);
 
269
static int      restore_entry(struct archive_write_disk *);
 
270
#ifdef HAVE_POSIX_ACL
 
271
static int      set_acl(struct archive_write_disk *, int fd, const char *, struct archive_acl *,
 
272
                    acl_type_t, int archive_entry_acl_type, const char *tn);
 
273
#endif
 
274
static int      set_acls(struct archive_write_disk *, int fd, const char *, struct archive_acl *);
 
275
static int      set_mac_metadata(struct archive_write_disk *, const char *,
 
276
                                 const void *, size_t);
 
277
static int      set_xattrs(struct archive_write_disk *);
 
278
static int      set_fflags(struct archive_write_disk *);
 
279
static int      set_fflags_platform(struct archive_write_disk *, int fd,
 
280
                    const char *name, mode_t mode,
 
281
                    unsigned long fflags_set, unsigned long fflags_clear);
 
282
static int      set_ownership(struct archive_write_disk *);
 
283
static int      set_mode(struct archive_write_disk *, int mode);
 
284
static int      set_time(int, int, const char *, time_t, long, time_t, long);
 
285
static int      set_times(struct archive_write_disk *, int, int, const char *,
 
286
                    time_t, long, time_t, long, time_t, long, time_t, long);
 
287
static int      set_times_from_entry(struct archive_write_disk *);
 
288
static struct fixup_entry *sort_dir_list(struct fixup_entry *p);
 
289
static ssize_t  write_data_block(struct archive_write_disk *,
 
290
                    const char *, size_t);
 
291
 
 
292
static struct archive_vtable *archive_write_disk_vtable(void);
 
293
 
 
294
static int      _archive_write_disk_close(struct archive *);
 
295
static int      _archive_write_disk_free(struct archive *);
 
296
static int      _archive_write_disk_header(struct archive *, struct archive_entry *);
 
297
static int64_t  _archive_write_disk_filter_bytes(struct archive *, int);
 
298
static int      _archive_write_disk_finish_entry(struct archive *);
 
299
static ssize_t  _archive_write_disk_data(struct archive *, const void *, size_t);
 
300
static ssize_t  _archive_write_disk_data_block(struct archive *, const void *, size_t, int64_t);
 
301
 
 
302
static int
 
303
lazy_stat(struct archive_write_disk *a)
 
304
{
 
305
        if (a->pst != NULL) {
 
306
                /* Already have stat() data available. */
 
307
                return (ARCHIVE_OK);
 
308
        }
 
309
#ifdef HAVE_FSTAT
 
310
        if (a->fd >= 0 && fstat(a->fd, &a->st) == 0) {
 
311
                a->pst = &a->st;
 
312
                return (ARCHIVE_OK);
 
313
        }
 
314
#endif
 
315
        /*
 
316
         * XXX At this point, symlinks should not be hit, otherwise
 
317
         * XXX a race occurred.  Do we want to check explicitly for that?
 
318
         */
 
319
        if (lstat(a->name, &a->st) == 0) {
 
320
                a->pst = &a->st;
 
321
                return (ARCHIVE_OK);
 
322
        }
 
323
        archive_set_error(&a->archive, errno, "Couldn't stat file");
 
324
        return (ARCHIVE_WARN);
 
325
}
 
326
 
 
327
static struct archive_vtable *
 
328
archive_write_disk_vtable(void)
 
329
{
 
330
        static struct archive_vtable av;
 
331
        static int inited = 0;
 
332
 
 
333
        if (!inited) {
 
334
                av.archive_close = _archive_write_disk_close;
 
335
                av.archive_filter_bytes = _archive_write_disk_filter_bytes;
 
336
                av.archive_free = _archive_write_disk_free;
 
337
                av.archive_write_header = _archive_write_disk_header;
 
338
                av.archive_write_finish_entry
 
339
                    = _archive_write_disk_finish_entry;
 
340
                av.archive_write_data = _archive_write_disk_data;
 
341
                av.archive_write_data_block = _archive_write_disk_data_block;
 
342
                inited = 1;
 
343
        }
 
344
        return (&av);
 
345
}
 
346
 
 
347
static int64_t
 
348
_archive_write_disk_filter_bytes(struct archive *_a, int n)
 
349
{
 
350
        struct archive_write_disk *a = (struct archive_write_disk *)_a;
 
351
        (void)n; /* UNUSED */
 
352
        if (n == -1 || n == 0)
 
353
                return (a->total_bytes_written);
 
354
        return (-1);
 
355
}
 
356
 
 
357
 
 
358
int
 
359
archive_write_disk_set_options(struct archive *_a, int flags)
 
360
{
 
361
        struct archive_write_disk *a = (struct archive_write_disk *)_a;
 
362
 
 
363
        a->flags = flags;
 
364
        return (ARCHIVE_OK);
 
365
}
 
366
 
 
367
 
 
368
/*
 
369
 * Extract this entry to disk.
 
370
 *
 
371
 * TODO: Validate hardlinks.  According to the standards, we're
 
372
 * supposed to check each extracted hardlink and squawk if it refers
 
373
 * to a file that we didn't restore.  I'm not entirely convinced this
 
374
 * is a good idea, but more importantly: Is there any way to validate
 
375
 * hardlinks without keeping a complete list of filenames from the
 
376
 * entire archive?? Ugh.
 
377
 *
 
378
 */
 
379
static int
 
380
_archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
 
381
{
 
382
        struct archive_write_disk *a = (struct archive_write_disk *)_a;
 
383
        struct fixup_entry *fe;
 
384
        int ret, r;
 
385
 
 
386
        archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
 
387
            ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
 
388
            "archive_write_disk_header");
 
389
        archive_clear_error(&a->archive);
 
390
        if (a->archive.state & ARCHIVE_STATE_DATA) {
 
391
                r = _archive_write_disk_finish_entry(&a->archive);
 
392
                if (r == ARCHIVE_FATAL)
 
393
                        return (r);
 
394
        }
 
395
 
 
396
        /* Set up for this particular entry. */
 
397
        a->pst = NULL;
 
398
        a->current_fixup = NULL;
 
399
        a->deferred = 0;
 
400
        if (a->entry) {
 
401
                archive_entry_free(a->entry);
 
402
                a->entry = NULL;
 
403
        }
 
404
        a->entry = archive_entry_clone(entry);
 
405
        a->fd = -1;
 
406
        a->fd_offset = 0;
 
407
        a->offset = 0;
 
408
        a->restore_pwd = -1;
 
409
        a->uid = a->user_uid;
 
410
        a->mode = archive_entry_mode(a->entry);
 
411
        if (archive_entry_size_is_set(a->entry))
 
412
                a->filesize = archive_entry_size(a->entry);
 
413
        else
 
414
                a->filesize = -1;
 
415
        archive_strcpy(&(a->_name_data), archive_entry_pathname(a->entry));
 
416
        a->name = a->_name_data.s;
 
417
        archive_clear_error(&a->archive);
 
418
 
 
419
        /*
 
420
         * Clean up the requested path.  This is necessary for correct
 
421
         * dir restores; the dir restore logic otherwise gets messed
 
422
         * up by nonsense like "dir/.".
 
423
         */
 
424
        ret = cleanup_pathname(a);
 
425
        if (ret != ARCHIVE_OK)
 
426
                return (ret);
 
427
 
 
428
        /*
 
429
         * Query the umask so we get predictable mode settings.
 
430
         * This gets done on every call to _write_header in case the
 
431
         * user edits their umask during the extraction for some
 
432
         * reason.
 
433
         */
 
434
        umask(a->user_umask = umask(0));
 
435
 
 
436
        /* Figure out what we need to do for this entry. */
 
437
        a->todo = TODO_MODE_BASE;
 
438
        if (a->flags & ARCHIVE_EXTRACT_PERM) {
 
439
                a->todo |= TODO_MODE_FORCE; /* Be pushy about permissions. */
 
440
                /*
 
441
                 * SGID requires an extra "check" step because we
 
442
                 * cannot easily predict the GID that the system will
 
443
                 * assign.  (Different systems assign GIDs to files
 
444
                 * based on a variety of criteria, including process
 
445
                 * credentials and the gid of the enclosing
 
446
                 * directory.)  We can only restore the SGID bit if
 
447
                 * the file has the right GID, and we only know the
 
448
                 * GID if we either set it (see set_ownership) or if
 
449
                 * we've actually called stat() on the file after it
 
450
                 * was restored.  Since there are several places at
 
451
                 * which we might verify the GID, we need a TODO bit
 
452
                 * to keep track.
 
453
                 */
 
454
                if (a->mode & S_ISGID)
 
455
                        a->todo |= TODO_SGID | TODO_SGID_CHECK;
 
456
                /*
 
457
                 * Verifying the SUID is simpler, but can still be
 
458
                 * done in multiple ways, hence the separate "check" bit.
 
459
                 */
 
460
                if (a->mode & S_ISUID)
 
461
                        a->todo |= TODO_SUID | TODO_SUID_CHECK;
 
462
        } else {
 
463
                /*
 
464
                 * User didn't request full permissions, so don't
 
465
                 * restore SUID, SGID bits and obey umask.
 
466
                 */
 
467
                a->mode &= ~S_ISUID;
 
468
                a->mode &= ~S_ISGID;
 
469
                a->mode &= ~S_ISVTX;
 
470
                a->mode &= ~a->user_umask;
 
471
        }
 
472
        if (a->flags & ARCHIVE_EXTRACT_OWNER)
 
473
                a->todo |= TODO_OWNER;
 
474
        if (a->flags & ARCHIVE_EXTRACT_TIME)
 
475
                a->todo |= TODO_TIMES;
 
476
        if (a->flags & ARCHIVE_EXTRACT_ACL) {
 
477
                if (archive_entry_filetype(a->entry) == AE_IFDIR)
 
478
                        a->deferred |= TODO_ACLS;
 
479
                else
 
480
                        a->todo |= TODO_ACLS;
 
481
        }
 
482
        if (a->flags & ARCHIVE_EXTRACT_MAC_METADATA) {
 
483
                if (archive_entry_filetype(a->entry) == AE_IFDIR)
 
484
                        a->deferred |= TODO_MAC_METADATA;
 
485
                else
 
486
                        a->todo |= TODO_MAC_METADATA;
 
487
        }
 
488
        if (a->flags & ARCHIVE_EXTRACT_XATTR)
 
489
                a->todo |= TODO_XATTR;
 
490
        if (a->flags & ARCHIVE_EXTRACT_FFLAGS)
 
491
                a->todo |= TODO_FFLAGS;
 
492
        if (a->flags & ARCHIVE_EXTRACT_SECURE_SYMLINKS) {
 
493
                ret = check_symlinks(a);
 
494
                if (ret != ARCHIVE_OK)
 
495
                        return (ret);
 
496
        }
 
497
#if defined(HAVE_FCHDIR) && defined(PATH_MAX)
 
498
        /* If path exceeds PATH_MAX, shorten the path. */
 
499
        edit_deep_directories(a);
 
500
#endif
 
501
 
 
502
        ret = restore_entry(a);
 
503
 
 
504
        /*
 
505
         * TODO: There are rumours that some extended attributes must
 
506
         * be restored before file data is written.  If this is true,
 
507
         * then we either need to write all extended attributes both
 
508
         * before and after restoring the data, or find some rule for
 
509
         * determining which must go first and which last.  Due to the
 
510
         * many ways people are using xattrs, this may prove to be an
 
511
         * intractable problem.
 
512
         */
 
513
 
 
514
#ifdef HAVE_FCHDIR
 
515
        /* If we changed directory above, restore it here. */
 
516
        if (a->restore_pwd >= 0) {
 
517
                r = fchdir(a->restore_pwd);
 
518
                if (r != 0) {
 
519
                        archive_set_error(&a->archive, errno, "chdir() failure");
 
520
                        ret = ARCHIVE_FATAL;
 
521
                }
 
522
                close(a->restore_pwd);
 
523
                a->restore_pwd = -1;
 
524
        }
 
525
#endif
 
526
 
 
527
        /*
 
528
         * Fixup uses the unedited pathname from archive_entry_pathname(),
 
529
         * because it is relative to the base dir and the edited path
 
530
         * might be relative to some intermediate dir as a result of the
 
531
         * deep restore logic.
 
532
         */
 
533
        if (a->deferred & TODO_MODE) {
 
534
                fe = current_fixup(a, archive_entry_pathname(entry));
 
535
                fe->fixup |= TODO_MODE_BASE;
 
536
                fe->mode = a->mode;
 
537
        }
 
538
 
 
539
        if ((a->deferred & TODO_TIMES)
 
540
                && (archive_entry_mtime_is_set(entry)
 
541
                    || archive_entry_atime_is_set(entry))) {
 
542
                fe = current_fixup(a, archive_entry_pathname(entry));
 
543
                fe->mode = a->mode;
 
544
                fe->fixup |= TODO_TIMES;
 
545
                if (archive_entry_atime_is_set(entry)) {
 
546
                        fe->atime = archive_entry_atime(entry);
 
547
                        fe->atime_nanos = archive_entry_atime_nsec(entry);
 
548
                } else {
 
549
                        /* If atime is unset, use start time. */
 
550
                        fe->atime = a->start_time;
 
551
                        fe->atime_nanos = 0;
 
552
                }
 
553
                if (archive_entry_mtime_is_set(entry)) {
 
554
                        fe->mtime = archive_entry_mtime(entry);
 
555
                        fe->mtime_nanos = archive_entry_mtime_nsec(entry);
 
556
                } else {
 
557
                        /* If mtime is unset, use start time. */
 
558
                        fe->mtime = a->start_time;
 
559
                        fe->mtime_nanos = 0;
 
560
                }
 
561
                if (archive_entry_birthtime_is_set(entry)) {
 
562
                        fe->birthtime = archive_entry_birthtime(entry);
 
563
                        fe->birthtime_nanos = archive_entry_birthtime_nsec(entry);
 
564
                } else {
 
565
                        /* If birthtime is unset, use mtime. */
 
566
                        fe->birthtime = fe->mtime;
 
567
                        fe->birthtime_nanos = fe->mtime_nanos;
 
568
                }
 
569
        }
 
570
 
 
571
        if (a->deferred & TODO_ACLS) {
 
572
                fe = current_fixup(a, archive_entry_pathname(entry));
 
573
                archive_acl_copy(&fe->acl, archive_entry_acl(entry));
 
574
        }
 
575
 
 
576
        if (a->deferred & TODO_MAC_METADATA) {
 
577
                const void *metadata;
 
578
                size_t metadata_size;
 
579
                metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
 
580
                if (metadata != NULL && metadata_size > 0) {
 
581
                        fe = current_fixup(a, archive_entry_pathname(entry));
 
582
                        fe->mac_metadata = malloc(metadata_size);
 
583
                        if (fe->mac_metadata != NULL) {
 
584
                                memcpy(fe->mac_metadata, metadata, metadata_size);
 
585
                                fe->mac_metadata_size = metadata_size;
 
586
                                fe->fixup |= TODO_MAC_METADATA;
 
587
                        }
 
588
                }
 
589
        }
 
590
 
 
591
        if (a->deferred & TODO_FFLAGS) {
 
592
                fe = current_fixup(a, archive_entry_pathname(entry));
 
593
                fe->fixup |= TODO_FFLAGS;
 
594
                /* TODO: Complete this.. defer fflags from below. */
 
595
        }
 
596
 
 
597
        /* We've created the object and are ready to pour data into it. */
 
598
        if (ret >= ARCHIVE_WARN)
 
599
                a->archive.state = ARCHIVE_STATE_DATA;
 
600
        /*
 
601
         * If it's not open, tell our client not to try writing.
 
602
         * In particular, dirs, links, etc, don't get written to.
 
603
         */
 
604
        if (a->fd < 0) {
 
605
                archive_entry_set_size(entry, 0);
 
606
                a->filesize = 0;
 
607
        }
 
608
 
 
609
        return (ret);
 
610
}
 
611
 
 
612
int
 
613
archive_write_disk_set_skip_file(struct archive *_a, int64_t d, int64_t i)
 
614
{
 
615
        struct archive_write_disk *a = (struct archive_write_disk *)_a;
 
616
        archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
 
617
            ARCHIVE_STATE_ANY, "archive_write_disk_set_skip_file");
 
618
        a->skip_file_set = 1;
 
619
        a->skip_file_dev = d;
 
620
        a->skip_file_ino = i;
 
621
        return (ARCHIVE_OK);
 
622
}
 
623
 
 
624
static ssize_t
 
625
write_data_block(struct archive_write_disk *a, const char *buff, size_t size)
 
626
{
 
627
        uint64_t start_size = size;
 
628
        ssize_t bytes_written = 0;
 
629
        ssize_t block_size = 0, bytes_to_write;
 
630
 
 
631
        if (size == 0)
 
632
                return (ARCHIVE_OK);
 
633
 
 
634
        if (a->filesize == 0 || a->fd < 0) {
 
635
                archive_set_error(&a->archive, 0,
 
636
                    "Attempt to write to an empty file");
 
637
                return (ARCHIVE_WARN);
 
638
        }
 
639
 
 
640
        if (a->flags & ARCHIVE_EXTRACT_SPARSE) {
 
641
#if HAVE_STRUCT_STAT_ST_BLKSIZE
 
642
                int r;
 
643
                if ((r = lazy_stat(a)) != ARCHIVE_OK)
 
644
                        return (r);
 
645
                block_size = a->pst->st_blksize;
 
646
#else
 
647
                /* XXX TODO XXX Is there a more appropriate choice here ? */
 
648
                /* This needn't match the filesystem allocation size. */
 
649
                block_size = 16*1024;
 
650
#endif
 
651
        }
 
652
 
 
653
        /* If this write would run beyond the file size, truncate it. */
 
654
        if (a->filesize >= 0 && (int64_t)(a->offset + size) > a->filesize)
 
655
                start_size = size = (size_t)(a->filesize - a->offset);
 
656
 
 
657
        /* Write the data. */
 
658
        while (size > 0) {
 
659
                if (block_size == 0) {
 
660
                        bytes_to_write = size;
 
661
                } else {
 
662
                        /* We're sparsifying the file. */
 
663
                        const char *p, *end;
 
664
                        int64_t block_end;
 
665
 
 
666
                        /* Skip leading zero bytes. */
 
667
                        for (p = buff, end = buff + size; p < end; ++p) {
 
668
                                if (*p != '\0')
 
669
                                        break;
 
670
                        }
 
671
                        a->offset += p - buff;
 
672
                        size -= p - buff;
 
673
                        buff = p;
 
674
                        if (size == 0)
 
675
                                break;
 
676
 
 
677
                        /* Calculate next block boundary after offset. */
 
678
                        block_end
 
679
                            = (a->offset / block_size + 1) * block_size;
 
680
 
 
681
                        /* If the adjusted write would cross block boundary,
 
682
                         * truncate it to the block boundary. */
 
683
                        bytes_to_write = size;
 
684
                        if (a->offset + bytes_to_write > block_end)
 
685
                                bytes_to_write = block_end - a->offset;
 
686
                }
 
687
                /* Seek if necessary to the specified offset. */
 
688
                if (a->offset != a->fd_offset) {
 
689
                        if (lseek(a->fd, a->offset, SEEK_SET) < 0) {
 
690
                                archive_set_error(&a->archive, errno,
 
691
                                    "Seek failed");
 
692
                                return (ARCHIVE_FATAL);
 
693
                        }
 
694
                        a->fd_offset = a->offset;
 
695
                }
 
696
                bytes_written = write(a->fd, buff, bytes_to_write);
 
697
                if (bytes_written < 0) {
 
698
                        archive_set_error(&a->archive, errno, "Write failed");
 
699
                        return (ARCHIVE_WARN);
 
700
                }
 
701
                buff += bytes_written;
 
702
                size -= bytes_written;
 
703
                a->total_bytes_written += bytes_written;
 
704
                a->offset += bytes_written;
 
705
                a->fd_offset = a->offset;
 
706
        }
 
707
        return (start_size - size);
 
708
}
 
709
 
 
710
static ssize_t
 
711
_archive_write_disk_data_block(struct archive *_a,
 
712
    const void *buff, size_t size, int64_t offset)
 
713
{
 
714
        struct archive_write_disk *a = (struct archive_write_disk *)_a;
 
715
        ssize_t r;
 
716
 
 
717
        archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
 
718
            ARCHIVE_STATE_DATA, "archive_write_data_block");
 
719
 
 
720
        a->offset = offset;
 
721
        r = write_data_block(a, buff, size);
 
722
        if (r < ARCHIVE_OK)
 
723
                return (r);
 
724
        if ((size_t)r < size) {
 
725
                archive_set_error(&a->archive, 0,
 
726
                    "Write request too large");
 
727
                return (ARCHIVE_WARN);
 
728
        }
 
729
        return (ARCHIVE_OK);
 
730
}
 
731
 
 
732
static ssize_t
 
733
_archive_write_disk_data(struct archive *_a, const void *buff, size_t size)
 
734
{
 
735
        struct archive_write_disk *a = (struct archive_write_disk *)_a;
 
736
 
 
737
        archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
 
738
            ARCHIVE_STATE_DATA, "archive_write_data");
 
739
 
 
740
        return (write_data_block(a, buff, size));
 
741
}
 
742
 
 
743
static int
 
744
_archive_write_disk_finish_entry(struct archive *_a)
 
745
{
 
746
        struct archive_write_disk *a = (struct archive_write_disk *)_a;
 
747
        int ret = ARCHIVE_OK;
 
748
 
 
749
        archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
 
750
            ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
 
751
            "archive_write_finish_entry");
 
752
        if (a->archive.state & ARCHIVE_STATE_HEADER)
 
753
                return (ARCHIVE_OK);
 
754
        archive_clear_error(&a->archive);
 
755
 
 
756
        /* Pad or truncate file to the right size. */
 
757
        if (a->fd < 0) {
 
758
                /* There's no file. */
 
759
        } else if (a->filesize < 0) {
 
760
                /* File size is unknown, so we can't set the size. */
 
761
        } else if (a->fd_offset == a->filesize) {
 
762
                /* Last write ended at exactly the filesize; we're done. */
 
763
                /* Hopefully, this is the common case. */
 
764
        } else {
 
765
#if HAVE_FTRUNCATE
 
766
                if (ftruncate(a->fd, a->filesize) == -1 &&
 
767
                    a->filesize == 0) {
 
768
                        archive_set_error(&a->archive, errno,
 
769
                            "File size could not be restored");
 
770
                        return (ARCHIVE_FAILED);
 
771
                }
 
772
#endif
 
773
                /*
 
774
                 * Not all platforms implement the XSI option to
 
775
                 * extend files via ftruncate.  Stat() the file again
 
776
                 * to see what happened.
 
777
                 */
 
778
                a->pst = NULL;
 
779
                if ((ret = lazy_stat(a)) != ARCHIVE_OK)
 
780
                        return (ret);
 
781
                /* We can use lseek()/write() to extend the file if
 
782
                 * ftruncate didn't work or isn't available. */
 
783
                if (a->st.st_size < a->filesize) {
 
784
                        const char nul = '\0';
 
785
                        if (lseek(a->fd, a->filesize - 1, SEEK_SET) < 0) {
 
786
                                archive_set_error(&a->archive, errno,
 
787
                                    "Seek failed");
 
788
                                return (ARCHIVE_FATAL);
 
789
                        }
 
790
                        if (write(a->fd, &nul, 1) < 0) {
 
791
                                archive_set_error(&a->archive, errno,
 
792
                                    "Write to restore size failed");
 
793
                                return (ARCHIVE_FATAL);
 
794
                        }
 
795
                        a->pst = NULL;
 
796
                }
 
797
        }
 
798
 
 
799
        /* Restore metadata. */
 
800
 
 
801
        /*
 
802
         * Look up the "real" UID only if we're going to need it.
 
803
         * TODO: the TODO_SGID condition can be dropped here, can't it?
 
804
         */
 
805
        if (a->todo & (TODO_OWNER | TODO_SUID | TODO_SGID)) {
 
806
                a->uid = archive_write_disk_uid(&a->archive,
 
807
                    archive_entry_uname(a->entry),
 
808
                    archive_entry_uid(a->entry));
 
809
        }
 
810
        /* Look up the "real" GID only if we're going to need it. */
 
811
        /* TODO: the TODO_SUID condition can be dropped here, can't it? */
 
812
        if (a->todo & (TODO_OWNER | TODO_SGID | TODO_SUID)) {
 
813
                a->gid = archive_write_disk_gid(&a->archive,
 
814
                    archive_entry_gname(a->entry),
 
815
                    archive_entry_gid(a->entry));
 
816
         }
 
817
 
 
818
        /*
 
819
         * Restore ownership before set_mode tries to restore suid/sgid
 
820
         * bits.  If we set the owner, we know what it is and can skip
 
821
         * a stat() call to examine the ownership of the file on disk.
 
822
         */
 
823
        if (a->todo & TODO_OWNER)
 
824
                ret = set_ownership(a);
 
825
 
 
826
        /*
 
827
         * set_mode must precede ACLs on systems such as Solaris and
 
828
         * FreeBSD where setting the mode implicitly clears extended ACLs
 
829
         */
 
830
        if (a->todo & TODO_MODE) {
 
831
                int r2 = set_mode(a, a->mode);
 
832
                if (r2 < ret) ret = r2;
 
833
        }
 
834
 
 
835
        /*
 
836
         * Security-related extended attributes (such as
 
837
         * security.capability on Linux) have to be restored last,
 
838
         * since they're implicitly removed by other file changes.
 
839
         */
 
840
        if (a->todo & TODO_XATTR) {
 
841
                int r2 = set_xattrs(a);
 
842
                if (r2 < ret) ret = r2;
 
843
        }
 
844
 
 
845
        /*
 
846
         * Some flags prevent file modification; they must be restored after
 
847
         * file contents are written.
 
848
         */
 
849
        if (a->todo & TODO_FFLAGS) {
 
850
                int r2 = set_fflags(a);
 
851
                if (r2 < ret) ret = r2;
 
852
        }
 
853
 
 
854
        /*
 
855
         * Time must follow most other metadata;
 
856
         * otherwise atime will get changed.
 
857
         */
 
858
        if (a->todo & TODO_TIMES) {
 
859
                int r2 = set_times_from_entry(a);
 
860
                if (r2 < ret) ret = r2;
 
861
        }
 
862
 
 
863
        /*
 
864
         * Mac extended metadata includes ACLs.
 
865
         */
 
866
        if (a->todo & TODO_MAC_METADATA) {
 
867
                const void *metadata;
 
868
                size_t metadata_size;
 
869
                metadata = archive_entry_mac_metadata(a->entry, &metadata_size);
 
870
                if (metadata != NULL && metadata_size > 0) {
 
871
                        int r2 = set_mac_metadata(a, archive_entry_pathname(a->entry), metadata, metadata_size);
 
872
                        if (r2 < ret) ret = r2;
 
873
                }
 
874
        }
 
875
 
 
876
        /*
 
877
         * ACLs must be restored after timestamps because there are
 
878
         * ACLs that prevent attribute changes (including time).
 
879
         */
 
880
        if (a->todo & TODO_ACLS) {
 
881
                int r2 = set_acls(a, a->fd,
 
882
                                  archive_entry_pathname(a->entry),
 
883
                                  archive_entry_acl(a->entry));
 
884
                if (r2 < ret) ret = r2;
 
885
        }
 
886
 
 
887
        /* If there's an fd, we can close it now. */
 
888
        if (a->fd >= 0) {
 
889
                close(a->fd);
 
890
                a->fd = -1;
 
891
        }
 
892
        /* If there's an entry, we can release it now. */
 
893
        if (a->entry) {
 
894
                archive_entry_free(a->entry);
 
895
                a->entry = NULL;
 
896
        }
 
897
        a->archive.state = ARCHIVE_STATE_HEADER;
 
898
        return (ret);
 
899
}
 
900
 
 
901
int
 
902
archive_write_disk_set_group_lookup(struct archive *_a,
 
903
    void *private_data,
 
904
    int64_t (*lookup_gid)(void *private, const char *gname, int64_t gid),
 
905
    void (*cleanup_gid)(void *private))
 
906
{
 
907
        struct archive_write_disk *a = (struct archive_write_disk *)_a;
 
908
        archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
 
909
            ARCHIVE_STATE_ANY, "archive_write_disk_set_group_lookup");
 
910
 
 
911
        if (a->cleanup_gid != NULL && a->lookup_gid_data != NULL)
 
912
                (a->cleanup_gid)(a->lookup_gid_data);
 
913
 
 
914
        a->lookup_gid = lookup_gid;
 
915
        a->cleanup_gid = cleanup_gid;
 
916
        a->lookup_gid_data = private_data;
 
917
        return (ARCHIVE_OK);
 
918
}
 
919
 
 
920
int
 
921
archive_write_disk_set_user_lookup(struct archive *_a,
 
922
    void *private_data,
 
923
    int64_t (*lookup_uid)(void *private, const char *uname, int64_t uid),
 
924
    void (*cleanup_uid)(void *private))
 
925
{
 
926
        struct archive_write_disk *a = (struct archive_write_disk *)_a;
 
927
        archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
 
928
            ARCHIVE_STATE_ANY, "archive_write_disk_set_user_lookup");
 
929
 
 
930
        if (a->cleanup_uid != NULL && a->lookup_uid_data != NULL)
 
931
                (a->cleanup_uid)(a->lookup_uid_data);
 
932
 
 
933
        a->lookup_uid = lookup_uid;
 
934
        a->cleanup_uid = cleanup_uid;
 
935
        a->lookup_uid_data = private_data;
 
936
        return (ARCHIVE_OK);
 
937
}
 
938
 
 
939
int64_t
 
940
archive_write_disk_gid(struct archive *_a, const char *name, int64_t id)
 
941
{
 
942
       struct archive_write_disk *a = (struct archive_write_disk *)_a;
 
943
       archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
 
944
           ARCHIVE_STATE_ANY, "archive_write_disk_gid");
 
945
       if (a->lookup_gid)
 
946
               return (a->lookup_gid)(a->lookup_gid_data, name, id);
 
947
       return (id);
 
948
}
 
949
 
 
950
int64_t
 
951
archive_write_disk_uid(struct archive *_a, const char *name, int64_t id)
 
952
{
 
953
       struct archive_write_disk *a = (struct archive_write_disk *)_a;
 
954
       archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
 
955
           ARCHIVE_STATE_ANY, "archive_write_disk_uid");
 
956
       if (a->lookup_uid)
 
957
               return (a->lookup_uid)(a->lookup_uid_data, name, id);
 
958
       return (id);
 
959
}
 
960
 
 
961
/*
 
962
 * Create a new archive_write_disk object and initialize it with global state.
 
963
 */
 
964
struct archive *
 
965
archive_write_disk_new(void)
 
966
{
 
967
        struct archive_write_disk *a;
 
968
 
 
969
        a = (struct archive_write_disk *)malloc(sizeof(*a));
 
970
        if (a == NULL)
 
971
                return (NULL);
 
972
        memset(a, 0, sizeof(*a));
 
973
        a->archive.magic = ARCHIVE_WRITE_DISK_MAGIC;
 
974
        /* We're ready to write a header immediately. */
 
975
        a->archive.state = ARCHIVE_STATE_HEADER;
 
976
        a->archive.vtable = archive_write_disk_vtable();
 
977
        a->start_time = time(NULL);
 
978
        /* Query and restore the umask. */
 
979
        umask(a->user_umask = umask(0));
 
980
#ifdef HAVE_GETEUID
 
981
        a->user_uid = geteuid();
 
982
#endif /* HAVE_GETEUID */
 
983
        if (archive_string_ensure(&a->path_safe, 512) == NULL) {
 
984
                free(a);
 
985
                return (NULL);
 
986
        }
 
987
        return (&a->archive);
 
988
}
 
989
 
 
990
 
 
991
/*
 
992
 * If pathname is longer than PATH_MAX, chdir to a suitable
 
993
 * intermediate dir and edit the path down to a shorter suffix.  Note
 
994
 * that this routine never returns an error; if the chdir() attempt
 
995
 * fails for any reason, we just go ahead with the long pathname.  The
 
996
 * object creation is likely to fail, but any error will get handled
 
997
 * at that time.
 
998
 */
 
999
#if defined(HAVE_FCHDIR) && defined(PATH_MAX)
 
1000
static void
 
1001
edit_deep_directories(struct archive_write_disk *a)
 
1002
{
 
1003
        int ret;
 
1004
        char *tail = a->name;
 
1005
 
 
1006
        /* If path is short, avoid the open() below. */
 
1007
        if (strlen(tail) <= PATH_MAX)
 
1008
                return;
 
1009
 
 
1010
        /* Try to record our starting dir. */
 
1011
        a->restore_pwd = open(".", O_RDONLY | O_BINARY);
 
1012
        if (a->restore_pwd < 0)
 
1013
                return;
 
1014
 
 
1015
        /* As long as the path is too long... */
 
1016
        while (strlen(tail) > PATH_MAX) {
 
1017
                /* Locate a dir prefix shorter than PATH_MAX. */
 
1018
                tail += PATH_MAX - 8;
 
1019
                while (tail > a->name && *tail != '/')
 
1020
                        tail--;
 
1021
                /* Exit if we find a too-long path component. */
 
1022
                if (tail <= a->name)
 
1023
                        return;
 
1024
                /* Create the intermediate dir and chdir to it. */
 
1025
                *tail = '\0'; /* Terminate dir portion */
 
1026
                ret = create_dir(a, a->name);
 
1027
                if (ret == ARCHIVE_OK && chdir(a->name) != 0)
 
1028
                        ret = ARCHIVE_FAILED;
 
1029
                *tail = '/'; /* Restore the / we removed. */
 
1030
                if (ret != ARCHIVE_OK)
 
1031
                        return;
 
1032
                tail++;
 
1033
                /* The chdir() succeeded; we've now shortened the path. */
 
1034
                a->name = tail;
 
1035
        }
 
1036
        return;
 
1037
}
 
1038
#endif
 
1039
 
 
1040
/*
 
1041
 * The main restore function.
 
1042
 */
 
1043
static int
 
1044
restore_entry(struct archive_write_disk *a)
 
1045
{
 
1046
        int ret = ARCHIVE_OK, en;
 
1047
 
 
1048
        if (a->flags & ARCHIVE_EXTRACT_UNLINK && !S_ISDIR(a->mode)) {
 
1049
                /*
 
1050
                 * TODO: Fix this.  Apparently, there are platforms
 
1051
                 * that still allow root to hose the entire filesystem
 
1052
                 * by unlinking a dir.  The S_ISDIR() test above
 
1053
                 * prevents us from using unlink() here if the new
 
1054
                 * object is a dir, but that doesn't mean the old
 
1055
                 * object isn't a dir.
 
1056
                 */
 
1057
                if (unlink(a->name) == 0) {
 
1058
                        /* We removed it, reset cached stat. */
 
1059
                        a->pst = NULL;
 
1060
                } else if (errno == ENOENT) {
 
1061
                        /* File didn't exist, that's just as good. */
 
1062
                } else if (rmdir(a->name) == 0) {
 
1063
                        /* It was a dir, but now it's gone. */
 
1064
                        a->pst = NULL;
 
1065
                } else {
 
1066
                        /* We tried, but couldn't get rid of it. */
 
1067
                        archive_set_error(&a->archive, errno,
 
1068
                            "Could not unlink");
 
1069
                        return(ARCHIVE_FAILED);
 
1070
                }
 
1071
        }
 
1072
 
 
1073
        /* Try creating it first; if this fails, we'll try to recover. */
 
1074
        en = create_filesystem_object(a);
 
1075
 
 
1076
        if ((en == ENOTDIR || en == ENOENT)
 
1077
            && !(a->flags & ARCHIVE_EXTRACT_NO_AUTODIR)) {
 
1078
                /* If the parent dir doesn't exist, try creating it. */
 
1079
                create_parent_dir(a, a->name);
 
1080
                /* Now try to create the object again. */
 
1081
                en = create_filesystem_object(a);
 
1082
        }
 
1083
 
 
1084
        if ((en == EISDIR || en == EEXIST)
 
1085
            && (a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
 
1086
                /* If we're not overwriting, we're done. */
 
1087
                archive_entry_unset_size(a->entry);
 
1088
                return (ARCHIVE_OK);
 
1089
        }
 
1090
 
 
1091
        /*
 
1092
         * Some platforms return EISDIR if you call
 
1093
         * open(O_WRONLY | O_EXCL | O_CREAT) on a directory, some
 
1094
         * return EEXIST.  POSIX is ambiguous, requiring EISDIR
 
1095
         * for open(O_WRONLY) on a dir and EEXIST for open(O_EXCL | O_CREAT)
 
1096
         * on an existing item.
 
1097
         */
 
1098
        if (en == EISDIR) {
 
1099
                /* A dir is in the way of a non-dir, rmdir it. */
 
1100
                if (rmdir(a->name) != 0) {
 
1101
                        archive_set_error(&a->archive, errno,
 
1102
                            "Can't remove already-existing dir");
 
1103
                        return (ARCHIVE_FAILED);
 
1104
                }
 
1105
                a->pst = NULL;
 
1106
                /* Try again. */
 
1107
                en = create_filesystem_object(a);
 
1108
        } else if (en == EEXIST) {
 
1109
                /*
 
1110
                 * We know something is in the way, but we don't know what;
 
1111
                 * we need to find out before we go any further.
 
1112
                 */
 
1113
                int r = 0;
 
1114
                /*
 
1115
                 * The SECURE_SYMLINKS logic has already removed a
 
1116
                 * symlink to a dir if the client wants that.  So
 
1117
                 * follow the symlink if we're creating a dir.
 
1118
                 */
 
1119
                if (S_ISDIR(a->mode))
 
1120
                        r = stat(a->name, &a->st);
 
1121
                /*
 
1122
                 * If it's not a dir (or it's a broken symlink),
 
1123
                 * then don't follow it.
 
1124
                 */
 
1125
                if (r != 0 || !S_ISDIR(a->mode))
 
1126
                        r = lstat(a->name, &a->st);
 
1127
                if (r != 0) {
 
1128
                        archive_set_error(&a->archive, errno,
 
1129
                            "Can't stat existing object");
 
1130
                        return (ARCHIVE_FAILED);
 
1131
                }
 
1132
 
 
1133
                /*
 
1134
                 * NO_OVERWRITE_NEWER doesn't apply to directories.
 
1135
                 */
 
1136
                if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE_NEWER)
 
1137
                    &&  !S_ISDIR(a->st.st_mode)) {
 
1138
                        if (!older(&(a->st), a->entry)) {
 
1139
                                archive_entry_unset_size(a->entry);
 
1140
                                return (ARCHIVE_OK);
 
1141
                        }
 
1142
                }
 
1143
 
 
1144
                /* If it's our archive, we're done. */
 
1145
                if (a->skip_file_set &&
 
1146
                    a->st.st_dev == a->skip_file_dev &&
 
1147
                    a->st.st_ino == a->skip_file_ino) {
 
1148
                        archive_set_error(&a->archive, 0, "Refusing to overwrite archive");
 
1149
                        return (ARCHIVE_FAILED);
 
1150
                }
 
1151
 
 
1152
                if (!S_ISDIR(a->st.st_mode)) {
 
1153
                        /* A non-dir is in the way, unlink it. */
 
1154
                        if (unlink(a->name) != 0) {
 
1155
                                archive_set_error(&a->archive, errno,
 
1156
                                    "Can't unlink already-existing object");
 
1157
                                return (ARCHIVE_FAILED);
 
1158
                        }
 
1159
                        a->pst = NULL;
 
1160
                        /* Try again. */
 
1161
                        en = create_filesystem_object(a);
 
1162
                } else if (!S_ISDIR(a->mode)) {
 
1163
                        /* A dir is in the way of a non-dir, rmdir it. */
 
1164
                        if (rmdir(a->name) != 0) {
 
1165
                                archive_set_error(&a->archive, errno,
 
1166
                                    "Can't remove already-existing dir");
 
1167
                                return (ARCHIVE_FAILED);
 
1168
                        }
 
1169
                        /* Try again. */
 
1170
                        en = create_filesystem_object(a);
 
1171
                } else {
 
1172
                        /*
 
1173
                         * There's a dir in the way of a dir.  Don't
 
1174
                         * waste time with rmdir()/mkdir(), just fix
 
1175
                         * up the permissions on the existing dir.
 
1176
                         * Note that we don't change perms on existing
 
1177
                         * dirs unless _EXTRACT_PERM is specified.
 
1178
                         */
 
1179
                        if ((a->mode != a->st.st_mode)
 
1180
                            && (a->todo & TODO_MODE_FORCE))
 
1181
                                a->deferred |= (a->todo & TODO_MODE);
 
1182
                        /* Ownership doesn't need deferred fixup. */
 
1183
                        en = 0; /* Forget the EEXIST. */
 
1184
                }
 
1185
        }
 
1186
 
 
1187
        if (en) {
 
1188
                /* Everything failed; give up here. */
 
1189
                archive_set_error(&a->archive, en, "Can't create '%s'",
 
1190
                    a->name);
 
1191
                return (ARCHIVE_FAILED);
 
1192
        }
 
1193
 
 
1194
        a->pst = NULL; /* Cached stat data no longer valid. */
 
1195
        return (ret);
 
1196
}
 
1197
 
 
1198
/*
 
1199
 * Returns 0 if creation succeeds, or else returns errno value from
 
1200
 * the failed system call.   Note:  This function should only ever perform
 
1201
 * a single system call.
 
1202
 */
 
1203
static int
 
1204
create_filesystem_object(struct archive_write_disk *a)
 
1205
{
 
1206
        /* Create the entry. */
 
1207
        const char *linkname;
 
1208
        mode_t final_mode, mode;
 
1209
        int r;
 
1210
 
 
1211
        /* We identify hard/symlinks according to the link names. */
 
1212
        /* Since link(2) and symlink(2) don't handle modes, we're done here. */
 
1213
        linkname = archive_entry_hardlink(a->entry);
 
1214
        if (linkname != NULL) {
 
1215
#if !HAVE_LINK
 
1216
                return (EPERM);
 
1217
#else
 
1218
                r = link(linkname, a->name) ? errno : 0;
 
1219
                /*
 
1220
                 * New cpio and pax formats allow hardlink entries
 
1221
                 * to carry data, so we may have to open the file
 
1222
                 * for hardlink entries.
 
1223
                 *
 
1224
                 * If the hardlink was successfully created and
 
1225
                 * the archive doesn't have carry data for it,
 
1226
                 * consider it to be non-authoritative for meta data.
 
1227
                 * This is consistent with GNU tar and BSD pax.
 
1228
                 * If the hardlink does carry data, let the last
 
1229
                 * archive entry decide ownership.
 
1230
                 */
 
1231
                if (r == 0 && a->filesize <= 0) {
 
1232
                        a->todo = 0;
 
1233
                        a->deferred = 0;
 
1234
                } else if (r == 0 && a->filesize > 0) {
 
1235
                        a->fd = open(a->name, O_WRONLY | O_TRUNC | O_BINARY);
 
1236
                        if (a->fd < 0)
 
1237
                                r = errno;
 
1238
                }
 
1239
                return (r);
 
1240
#endif
 
1241
        }
 
1242
        linkname = archive_entry_symlink(a->entry);
 
1243
        if (linkname != NULL) {
 
1244
#if HAVE_SYMLINK
 
1245
                return symlink(linkname, a->name) ? errno : 0;
 
1246
#else
 
1247
                return (EPERM);
 
1248
#endif
 
1249
        }
 
1250
 
 
1251
        /*
 
1252
         * The remaining system calls all set permissions, so let's
 
1253
         * try to take advantage of that to avoid an extra chmod()
 
1254
         * call.  (Recall that umask is set to zero right now!)
 
1255
         */
 
1256
 
 
1257
        /* Mode we want for the final restored object (w/o file type bits). */
 
1258
        final_mode = a->mode & 07777;
 
1259
        /*
 
1260
         * The mode that will actually be restored in this step.  Note
 
1261
         * that SUID, SGID, etc, require additional work to ensure
 
1262
         * security, so we never restore them at this point.
 
1263
         */
 
1264
        mode = final_mode & 0777 & a->user_umask;
 
1265
 
 
1266
        switch (a->mode & AE_IFMT) {
 
1267
        default:
 
1268
                /* POSIX requires that we fall through here. */
 
1269
                /* FALLTHROUGH */
 
1270
        case AE_IFREG:
 
1271
                a->fd = open(a->name,
 
1272
                    O_WRONLY | O_CREAT | O_EXCL | O_BINARY, mode);
 
1273
                r = (a->fd < 0);
 
1274
                break;
 
1275
        case AE_IFCHR:
 
1276
#ifdef HAVE_MKNOD
 
1277
                /* Note: we use AE_IFCHR for the case label, and
 
1278
                 * S_IFCHR for the mknod() call.  This is correct.  */
 
1279
                r = mknod(a->name, mode | S_IFCHR,
 
1280
                    archive_entry_rdev(a->entry));
 
1281
                break;
 
1282
#else
 
1283
                /* TODO: Find a better way to warn about our inability
 
1284
                 * to restore a char device node. */
 
1285
                return (EINVAL);
 
1286
#endif /* HAVE_MKNOD */
 
1287
        case AE_IFBLK:
 
1288
#ifdef HAVE_MKNOD
 
1289
                r = mknod(a->name, mode | S_IFBLK,
 
1290
                    archive_entry_rdev(a->entry));
 
1291
                break;
 
1292
#else
 
1293
                /* TODO: Find a better way to warn about our inability
 
1294
                 * to restore a block device node. */
 
1295
                return (EINVAL);
 
1296
#endif /* HAVE_MKNOD */
 
1297
        case AE_IFDIR:
 
1298
                mode = (mode | MINIMUM_DIR_MODE) & MAXIMUM_DIR_MODE;
 
1299
                r = mkdir(a->name, mode);
 
1300
                if (r == 0) {
 
1301
                        /* Defer setting dir times. */
 
1302
                        a->deferred |= (a->todo & TODO_TIMES);
 
1303
                        a->todo &= ~TODO_TIMES;
 
1304
                        /* Never use an immediate chmod(). */
 
1305
                        /* We can't avoid the chmod() entirely if EXTRACT_PERM
 
1306
                         * because of SysV SGID inheritance. */
 
1307
                        if ((mode != final_mode)
 
1308
                            || (a->flags & ARCHIVE_EXTRACT_PERM))
 
1309
                                a->deferred |= (a->todo & TODO_MODE);
 
1310
                        a->todo &= ~TODO_MODE;
 
1311
                }
 
1312
                break;
 
1313
        case AE_IFIFO:
 
1314
#ifdef HAVE_MKFIFO
 
1315
                r = mkfifo(a->name, mode);
 
1316
                break;
 
1317
#else
 
1318
                /* TODO: Find a better way to warn about our inability
 
1319
                 * to restore a fifo. */
 
1320
                return (EINVAL);
 
1321
#endif /* HAVE_MKFIFO */
 
1322
        }
 
1323
 
 
1324
        /* All the system calls above set errno on failure. */
 
1325
        if (r)
 
1326
                return (errno);
 
1327
 
 
1328
        /* If we managed to set the final mode, we've avoided a chmod(). */
 
1329
        if (mode == final_mode)
 
1330
                a->todo &= ~TODO_MODE;
 
1331
        return (0);
 
1332
}
 
1333
 
 
1334
/*
 
1335
 * Cleanup function for archive_extract.  Mostly, this involves processing
 
1336
 * the fixup list, which is used to address a number of problems:
 
1337
 *   * Dir permissions might prevent us from restoring a file in that
 
1338
 *     dir, so we restore the dir with minimum 0700 permissions first,
 
1339
 *     then correct the mode at the end.
 
1340
 *   * Similarly, the act of restoring a file touches the directory
 
1341
 *     and changes the timestamp on the dir, so we have to touch-up dir
 
1342
 *     timestamps at the end as well.
 
1343
 *   * Some file flags can interfere with the restore by, for example,
 
1344
 *     preventing the creation of hardlinks to those files.
 
1345
 *   * Mac OS extended metadata includes ACLs, so must be deferred on dirs.
 
1346
 *
 
1347
 * Note that tar/cpio do not require that archives be in a particular
 
1348
 * order; there is no way to know when the last file has been restored
 
1349
 * within a directory, so there's no way to optimize the memory usage
 
1350
 * here by fixing up the directory any earlier than the
 
1351
 * end-of-archive.
 
1352
 *
 
1353
 * XXX TODO: Directory ACLs should be restored here, for the same
 
1354
 * reason we set directory perms here. XXX
 
1355
 */
 
1356
static int
 
1357
_archive_write_disk_close(struct archive *_a)
 
1358
{
 
1359
        struct archive_write_disk *a = (struct archive_write_disk *)_a;
 
1360
        struct fixup_entry *next, *p;
 
1361
        int ret;
 
1362
 
 
1363
        archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC,
 
1364
            ARCHIVE_STATE_HEADER | ARCHIVE_STATE_DATA,
 
1365
            "archive_write_disk_close");
 
1366
        ret = _archive_write_disk_finish_entry(&a->archive);
 
1367
 
 
1368
        /* Sort dir list so directories are fixed up in depth-first order. */
 
1369
        p = sort_dir_list(a->fixup_list);
 
1370
 
 
1371
        while (p != NULL) {
 
1372
                a->pst = NULL; /* Mark stat cache as out-of-date. */
 
1373
                if (p->fixup & TODO_TIMES) {
 
1374
                        set_times(a, -1, p->mode, p->name,
 
1375
                            p->atime, p->atime_nanos,
 
1376
                            p->birthtime, p->birthtime_nanos,
 
1377
                            p->mtime, p->mtime_nanos,
 
1378
                            p->ctime, p->ctime_nanos);
 
1379
                }
 
1380
                if (p->fixup & TODO_MODE_BASE)
 
1381
                        chmod(p->name, p->mode);
 
1382
                if (p->fixup & TODO_ACLS)
 
1383
                        set_acls(a, -1, p->name, &p->acl);
 
1384
                if (p->fixup & TODO_FFLAGS)
 
1385
                        set_fflags_platform(a, -1, p->name,
 
1386
                            p->mode, p->fflags_set, 0);
 
1387
                if (p->fixup & TODO_MAC_METADATA)
 
1388
                        set_mac_metadata(a, p->name, p->mac_metadata,
 
1389
                                         p->mac_metadata_size);
 
1390
                next = p->next;
 
1391
                archive_acl_clear(&p->acl);
 
1392
                free(p->mac_metadata);
 
1393
                free(p->name);
 
1394
                free(p);
 
1395
                p = next;
 
1396
        }
 
1397
        a->fixup_list = NULL;
 
1398
        return (ret);
 
1399
}
 
1400
 
 
1401
static int
 
1402
_archive_write_disk_free(struct archive *_a)
 
1403
{
 
1404
        struct archive_write_disk *a;
 
1405
        int ret;
 
1406
        if (_a == NULL)
 
1407
                return (ARCHIVE_OK);
 
1408
        archive_check_magic(_a, ARCHIVE_WRITE_DISK_MAGIC,
 
1409
            ARCHIVE_STATE_ANY | ARCHIVE_STATE_FATAL, "archive_write_disk_free");
 
1410
        a = (struct archive_write_disk *)_a;
 
1411
        ret = _archive_write_disk_close(&a->archive);
 
1412
        archive_write_disk_set_group_lookup(&a->archive, NULL, NULL, NULL);
 
1413
        archive_write_disk_set_user_lookup(&a->archive, NULL, NULL, NULL);
 
1414
        if (a->entry)
 
1415
                archive_entry_free(a->entry);
 
1416
        archive_string_free(&a->_name_data);
 
1417
        archive_string_free(&a->archive.error_string);
 
1418
        archive_string_free(&a->path_safe);
 
1419
        a->archive.magic = 0;
 
1420
        __archive_clean(&a->archive);
 
1421
        free(a);
 
1422
        return (ret);
 
1423
}
 
1424
 
 
1425
/*
 
1426
 * Simple O(n log n) merge sort to order the fixup list.  In
 
1427
 * particular, we want to restore dir timestamps depth-first.
 
1428
 */
 
1429
static struct fixup_entry *
 
1430
sort_dir_list(struct fixup_entry *p)
 
1431
{
 
1432
        struct fixup_entry *a, *b, *t;
 
1433
 
 
1434
        if (p == NULL)
 
1435
                return (NULL);
 
1436
        /* A one-item list is already sorted. */
 
1437
        if (p->next == NULL)
 
1438
                return (p);
 
1439
 
 
1440
        /* Step 1: split the list. */
 
1441
        t = p;
 
1442
        a = p->next->next;
 
1443
        while (a != NULL) {
 
1444
                /* Step a twice, t once. */
 
1445
                a = a->next;
 
1446
                if (a != NULL)
 
1447
                        a = a->next;
 
1448
                t = t->next;
 
1449
        }
 
1450
        /* Now, t is at the mid-point, so break the list here. */
 
1451
        b = t->next;
 
1452
        t->next = NULL;
 
1453
        a = p;
 
1454
 
 
1455
        /* Step 2: Recursively sort the two sub-lists. */
 
1456
        a = sort_dir_list(a);
 
1457
        b = sort_dir_list(b);
 
1458
 
 
1459
        /* Step 3: Merge the returned lists. */
 
1460
        /* Pick the first element for the merged list. */
 
1461
        if (strcmp(a->name, b->name) > 0) {
 
1462
                t = p = a;
 
1463
                a = a->next;
 
1464
        } else {
 
1465
                t = p = b;
 
1466
                b = b->next;
 
1467
        }
 
1468
 
 
1469
        /* Always put the later element on the list first. */
 
1470
        while (a != NULL && b != NULL) {
 
1471
                if (strcmp(a->name, b->name) > 0) {
 
1472
                        t->next = a;
 
1473
                        a = a->next;
 
1474
                } else {
 
1475
                        t->next = b;
 
1476
                        b = b->next;
 
1477
                }
 
1478
                t = t->next;
 
1479
        }
 
1480
 
 
1481
        /* Only one list is non-empty, so just splice it on. */
 
1482
        if (a != NULL)
 
1483
                t->next = a;
 
1484
        if (b != NULL)
 
1485
                t->next = b;
 
1486
 
 
1487
        return (p);
 
1488
}
 
1489
 
 
1490
/*
 
1491
 * Returns a new, initialized fixup entry.
 
1492
 *
 
1493
 * TODO: Reduce the memory requirements for this list by using a tree
 
1494
 * structure rather than a simple list of names.
 
1495
 */
 
1496
static struct fixup_entry *
 
1497
new_fixup(struct archive_write_disk *a, const char *pathname)
 
1498
{
 
1499
        struct fixup_entry *fe;
 
1500
 
 
1501
        fe = (struct fixup_entry *)calloc(1, sizeof(struct fixup_entry));
 
1502
        if (fe == NULL)
 
1503
                return (NULL);
 
1504
        fe->next = a->fixup_list;
 
1505
        a->fixup_list = fe;
 
1506
        fe->fixup = 0;
 
1507
        fe->name = strdup(pathname);
 
1508
        return (fe);
 
1509
}
 
1510
 
 
1511
/*
 
1512
 * Returns a fixup structure for the current entry.
 
1513
 */
 
1514
static struct fixup_entry *
 
1515
current_fixup(struct archive_write_disk *a, const char *pathname)
 
1516
{
 
1517
        if (a->current_fixup == NULL)
 
1518
                a->current_fixup = new_fixup(a, pathname);
 
1519
        return (a->current_fixup);
 
1520
}
 
1521
 
 
1522
/* TODO: Make this work. */
 
1523
/*
 
1524
 * TODO: The deep-directory support bypasses this; disable deep directory
 
1525
 * support if we're doing symlink checks.
 
1526
 */
 
1527
/*
 
1528
 * TODO: Someday, integrate this with the deep dir support; they both
 
1529
 * scan the path and both can be optimized by comparing against other
 
1530
 * recent paths.
 
1531
 */
 
1532
/* TODO: Extend this to support symlinks on Windows Vista and later. */
 
1533
static int
 
1534
check_symlinks(struct archive_write_disk *a)
 
1535
{
 
1536
#if !defined(HAVE_LSTAT)
 
1537
        /* Platform doesn't have lstat, so we can't look for symlinks. */
 
1538
        (void)a; /* UNUSED */
 
1539
        return (ARCHIVE_OK);
 
1540
#else
 
1541
        char *pn;
 
1542
        char c;
 
1543
        int r;
 
1544
        struct stat st;
 
1545
 
 
1546
        /*
 
1547
         * Guard against symlink tricks.  Reject any archive entry whose
 
1548
         * destination would be altered by a symlink.
 
1549
         */
 
1550
        /* Whatever we checked last time doesn't need to be re-checked. */
 
1551
        pn = a->name;
 
1552
        if (archive_strlen(&(a->path_safe)) > 0) {
 
1553
                char *p = a->path_safe.s;
 
1554
                while ((*pn != '\0') && (*p == *pn))
 
1555
                        ++p, ++pn;
 
1556
        }
 
1557
        c = pn[0];
 
1558
        /* Keep going until we've checked the entire name. */
 
1559
        while (pn[0] != '\0' && (pn[0] != '/' || pn[1] != '\0')) {
 
1560
                /* Skip the next path element. */
 
1561
                while (*pn != '\0' && *pn != '/')
 
1562
                        ++pn;
 
1563
                c = pn[0];
 
1564
                pn[0] = '\0';
 
1565
                /* Check that we haven't hit a symlink. */
 
1566
                r = lstat(a->name, &st);
 
1567
                if (r != 0) {
 
1568
                        /* We've hit a dir that doesn't exist; stop now. */
 
1569
                        if (errno == ENOENT)
 
1570
                                break;
 
1571
                } else if (S_ISLNK(st.st_mode)) {
 
1572
                        if (c == '\0') {
 
1573
                                /*
 
1574
                                 * Last element is symlink; remove it
 
1575
                                 * so we can overwrite it with the
 
1576
                                 * item being extracted.
 
1577
                                 */
 
1578
                                if (unlink(a->name)) {
 
1579
                                        archive_set_error(&a->archive, errno,
 
1580
                                            "Could not remove symlink %s",
 
1581
                                            a->name);
 
1582
                                        pn[0] = c;
 
1583
                                        return (ARCHIVE_FAILED);
 
1584
                                }
 
1585
                                a->pst = NULL;
 
1586
                                /*
 
1587
                                 * Even if we did remove it, a warning
 
1588
                                 * is in order.  The warning is silly,
 
1589
                                 * though, if we're just replacing one
 
1590
                                 * symlink with another symlink.
 
1591
                                 */
 
1592
                                if (!S_ISLNK(a->mode)) {
 
1593
                                        archive_set_error(&a->archive, 0,
 
1594
                                            "Removing symlink %s",
 
1595
                                            a->name);
 
1596
                                }
 
1597
                                /* Symlink gone.  No more problem! */
 
1598
                                pn[0] = c;
 
1599
                                return (0);
 
1600
                        } else if (a->flags & ARCHIVE_EXTRACT_UNLINK) {
 
1601
                                /* User asked us to remove problems. */
 
1602
                                if (unlink(a->name) != 0) {
 
1603
                                        archive_set_error(&a->archive, 0,
 
1604
                                            "Cannot remove intervening symlink %s",
 
1605
                                            a->name);
 
1606
                                        pn[0] = c;
 
1607
                                        return (ARCHIVE_FAILED);
 
1608
                                }
 
1609
                                a->pst = NULL;
 
1610
                        } else {
 
1611
                                archive_set_error(&a->archive, 0,
 
1612
                                    "Cannot extract through symlink %s",
 
1613
                                    a->name);
 
1614
                                pn[0] = c;
 
1615
                                return (ARCHIVE_FAILED);
 
1616
                        }
 
1617
                }
 
1618
        }
 
1619
        pn[0] = c;
 
1620
        /* We've checked and/or cleaned the whole path, so remember it. */
 
1621
        archive_strcpy(&a->path_safe, a->name);
 
1622
        return (ARCHIVE_OK);
 
1623
#endif
 
1624
}
 
1625
 
 
1626
#if defined(__CYGWIN__)
 
1627
/*
 
1628
 * 1. Convert a path separator from '\' to '/' .
 
1629
 *    We shouldn't check multibyte character directly because some
 
1630
 *    character-set have been using the '\' character for a part of
 
1631
 *    its multibyte character code.
 
1632
 * 2. Replace unusable characters in Windows with underscore('_').
 
1633
 * See also : http://msdn.microsoft.com/en-us/library/aa365247.aspx
 
1634
 */
 
1635
static void
 
1636
cleanup_pathname_win(struct archive_write_disk *a)
 
1637
{
 
1638
        wchar_t wc;
 
1639
        char *p;
 
1640
        size_t alen, l;
 
1641
        int mb, complete, utf8;
 
1642
 
 
1643
        alen = 0;
 
1644
        mb = 0;
 
1645
        complete = 1;
 
1646
        utf8 = (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)? 1: 0;
 
1647
        for (p = a->name; *p != '\0'; p++) {
 
1648
                ++alen;
 
1649
                if (*p == '\\') {
 
1650
                        /* If previous byte is smaller than 128,
 
1651
                         * this is not second byte of multibyte characters,
 
1652
                         * so we can replace '\' with '/'. */
 
1653
                        if (utf8 || !mb)
 
1654
                                *p = '/';
 
1655
                        else
 
1656
                                complete = 0;/* uncompleted. */
 
1657
                } else if (*(unsigned char *)p > 127)
 
1658
                        mb = 1;
 
1659
                else
 
1660
                        mb = 0;
 
1661
                /* Rewrite the path name if its next character is unusable. */
 
1662
                if (*p == ':' || *p == '*' || *p == '?' || *p == '"' ||
 
1663
                    *p == '<' || *p == '>' || *p == '|')
 
1664
                        *p = '_';
 
1665
        }
 
1666
        if (complete)
 
1667
                return;
 
1668
 
 
1669
        /*
 
1670
         * Convert path separator in wide-character.
 
1671
         */
 
1672
        p = a->name;
 
1673
        while (*p != '\0' && alen) {
 
1674
                l = mbtowc(&wc, p, alen);
 
1675
                if (l == -1) {
 
1676
                        while (*p != '\0') {
 
1677
                                if (*p == '\\')
 
1678
                                        *p = '/';
 
1679
                                ++p;
 
1680
                        }
 
1681
                        break;
 
1682
                }
 
1683
                if (l == 1 && wc == L'\\')
 
1684
                        *p = '/';
 
1685
                p += l;
 
1686
                alen -= l;
 
1687
        }
 
1688
}
 
1689
#endif
 
1690
 
 
1691
/*
 
1692
 * Canonicalize the pathname.  In particular, this strips duplicate
 
1693
 * '/' characters, '.' elements, and trailing '/'.  It also raises an
 
1694
 * error for an empty path, a trailing '..' or (if _SECURE_NODOTDOT is
 
1695
 * set) any '..' in the path.
 
1696
 */
 
1697
static int
 
1698
cleanup_pathname(struct archive_write_disk *a)
 
1699
{
 
1700
        char *dest, *src;
 
1701
        char separator = '\0';
 
1702
 
 
1703
        dest = src = a->name;
 
1704
        if (*src == '\0') {
 
1705
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
 
1706
                    "Invalid empty pathname");
 
1707
                return (ARCHIVE_FAILED);
 
1708
        }
 
1709
 
 
1710
#if defined(__CYGWIN__)
 
1711
        cleanup_pathname_win(a);
 
1712
#endif
 
1713
        /* Skip leading '/'. */
 
1714
        if (*src == '/')
 
1715
                separator = *src++;
 
1716
 
 
1717
        /* Scan the pathname one element at a time. */
 
1718
        for (;;) {
 
1719
                /* src points to first char after '/' */
 
1720
                if (src[0] == '\0') {
 
1721
                        break;
 
1722
                } else if (src[0] == '/') {
 
1723
                        /* Found '//', ignore second one. */
 
1724
                        src++;
 
1725
                        continue;
 
1726
                } else if (src[0] == '.') {
 
1727
                        if (src[1] == '\0') {
 
1728
                                /* Ignore trailing '.' */
 
1729
                                break;
 
1730
                        } else if (src[1] == '/') {
 
1731
                                /* Skip './'. */
 
1732
                                src += 2;
 
1733
                                continue;
 
1734
                        } else if (src[1] == '.') {
 
1735
                                if (src[2] == '/' || src[2] == '\0') {
 
1736
                                        /* Conditionally warn about '..' */
 
1737
                                        if (a->flags & ARCHIVE_EXTRACT_SECURE_NODOTDOT) {
 
1738
                                                archive_set_error(&a->archive,
 
1739
                                                    ARCHIVE_ERRNO_MISC,
 
1740
                                                    "Path contains '..'");
 
1741
                                                return (ARCHIVE_FAILED);
 
1742
                                        }
 
1743
                                }
 
1744
                                /*
 
1745
                                 * Note: Under no circumstances do we
 
1746
                                 * remove '..' elements.  In
 
1747
                                 * particular, restoring
 
1748
                                 * '/foo/../bar/' should create the
 
1749
                                 * 'foo' dir as a side-effect.
 
1750
                                 */
 
1751
                        }
 
1752
                }
 
1753
 
 
1754
                /* Copy current element, including leading '/'. */
 
1755
                if (separator)
 
1756
                        *dest++ = '/';
 
1757
                while (*src != '\0' && *src != '/') {
 
1758
                        *dest++ = *src++;
 
1759
                }
 
1760
 
 
1761
                if (*src == '\0')
 
1762
                        break;
 
1763
 
 
1764
                /* Skip '/' separator. */
 
1765
                separator = *src++;
 
1766
        }
 
1767
        /*
 
1768
         * We've just copied zero or more path elements, not including the
 
1769
         * final '/'.
 
1770
         */
 
1771
        if (dest == a->name) {
 
1772
                /*
 
1773
                 * Nothing got copied.  The path must have been something
 
1774
                 * like '.' or '/' or './' or '/././././/./'.
 
1775
                 */
 
1776
                if (separator)
 
1777
                        *dest++ = '/';
 
1778
                else
 
1779
                        *dest++ = '.';
 
1780
        }
 
1781
        /* Terminate the result. */
 
1782
        *dest = '\0';
 
1783
        return (ARCHIVE_OK);
 
1784
}
 
1785
 
 
1786
/*
 
1787
 * Create the parent directory of the specified path, assuming path
 
1788
 * is already in mutable storage.
 
1789
 */
 
1790
static int
 
1791
create_parent_dir(struct archive_write_disk *a, char *path)
 
1792
{
 
1793
        char *slash;
 
1794
        int r;
 
1795
 
 
1796
        /* Remove tail element to obtain parent name. */
 
1797
        slash = strrchr(path, '/');
 
1798
        if (slash == NULL)
 
1799
                return (ARCHIVE_OK);
 
1800
        *slash = '\0';
 
1801
        r = create_dir(a, path);
 
1802
        *slash = '/';
 
1803
        return (r);
 
1804
}
 
1805
 
 
1806
/*
 
1807
 * Create the specified dir, recursing to create parents as necessary.
 
1808
 *
 
1809
 * Returns ARCHIVE_OK if the path exists when we're done here.
 
1810
 * Otherwise, returns ARCHIVE_FAILED.
 
1811
 * Assumes path is in mutable storage; path is unchanged on exit.
 
1812
 */
 
1813
static int
 
1814
create_dir(struct archive_write_disk *a, char *path)
 
1815
{
 
1816
        struct stat st;
 
1817
        struct fixup_entry *le;
 
1818
        char *slash, *base;
 
1819
        mode_t mode_final, mode;
 
1820
        int r;
 
1821
 
 
1822
        /* Check for special names and just skip them. */
 
1823
        slash = strrchr(path, '/');
 
1824
        if (slash == NULL)
 
1825
                base = path;
 
1826
        else
 
1827
                base = slash + 1;
 
1828
 
 
1829
        if (base[0] == '\0' ||
 
1830
            (base[0] == '.' && base[1] == '\0') ||
 
1831
            (base[0] == '.' && base[1] == '.' && base[2] == '\0')) {
 
1832
                /* Don't bother trying to create null path, '.', or '..'. */
 
1833
                if (slash != NULL) {
 
1834
                        *slash = '\0';
 
1835
                        r = create_dir(a, path);
 
1836
                        *slash = '/';
 
1837
                        return (r);
 
1838
                }
 
1839
                return (ARCHIVE_OK);
 
1840
        }
 
1841
 
 
1842
        /*
 
1843
         * Yes, this should be stat() and not lstat().  Using lstat()
 
1844
         * here loses the ability to extract through symlinks.  Also note
 
1845
         * that this should not use the a->st cache.
 
1846
         */
 
1847
        if (stat(path, &st) == 0) {
 
1848
                if (S_ISDIR(st.st_mode))
 
1849
                        return (ARCHIVE_OK);
 
1850
                if ((a->flags & ARCHIVE_EXTRACT_NO_OVERWRITE)) {
 
1851
                        archive_set_error(&a->archive, EEXIST,
 
1852
                            "Can't create directory '%s'", path);
 
1853
                        return (ARCHIVE_FAILED);
 
1854
                }
 
1855
                if (unlink(path) != 0) {
 
1856
                        archive_set_error(&a->archive, errno,
 
1857
                            "Can't create directory '%s': "
 
1858
                            "Conflicting file cannot be removed",
 
1859
                            path);
 
1860
                        return (ARCHIVE_FAILED);
 
1861
                }
 
1862
        } else if (errno != ENOENT && errno != ENOTDIR) {
 
1863
                /* Stat failed? */
 
1864
                archive_set_error(&a->archive, errno, "Can't test directory '%s'", path);
 
1865
                return (ARCHIVE_FAILED);
 
1866
        } else if (slash != NULL) {
 
1867
                *slash = '\0';
 
1868
                r = create_dir(a, path);
 
1869
                *slash = '/';
 
1870
                if (r != ARCHIVE_OK)
 
1871
                        return (r);
 
1872
        }
 
1873
 
 
1874
        /*
 
1875
         * Mode we want for the final restored directory.  Per POSIX,
 
1876
         * implicitly-created dirs must be created obeying the umask.
 
1877
         * There's no mention whether this is different for privileged
 
1878
         * restores (which the rest of this code handles by pretending
 
1879
         * umask=0).  I've chosen here to always obey the user's umask for
 
1880
         * implicit dirs, even if _EXTRACT_PERM was specified.
 
1881
         */
 
1882
        mode_final = DEFAULT_DIR_MODE & ~a->user_umask;
 
1883
        /* Mode we want on disk during the restore process. */
 
1884
        mode = mode_final;
 
1885
        mode |= MINIMUM_DIR_MODE;
 
1886
        mode &= MAXIMUM_DIR_MODE;
 
1887
        if (mkdir(path, mode) == 0) {
 
1888
                if (mode != mode_final) {
 
1889
                        le = new_fixup(a, path);
 
1890
                        le->fixup |=TODO_MODE_BASE;
 
1891
                        le->mode = mode_final;
 
1892
                }
 
1893
                return (ARCHIVE_OK);
 
1894
        }
 
1895
 
 
1896
        /*
 
1897
         * Without the following check, a/b/../b/c/d fails at the
 
1898
         * second visit to 'b', so 'd' can't be created.  Note that we
 
1899
         * don't add it to the fixup list here, as it's already been
 
1900
         * added.
 
1901
         */
 
1902
        if (stat(path, &st) == 0 && S_ISDIR(st.st_mode))
 
1903
                return (ARCHIVE_OK);
 
1904
 
 
1905
        archive_set_error(&a->archive, errno, "Failed to create dir '%s'",
 
1906
            path);
 
1907
        return (ARCHIVE_FAILED);
 
1908
}
 
1909
 
 
1910
/*
 
1911
 * Note: Although we can skip setting the user id if the desired user
 
1912
 * id matches the current user, we cannot skip setting the group, as
 
1913
 * many systems set the gid based on the containing directory.  So
 
1914
 * we have to perform a chown syscall if we want to set the SGID
 
1915
 * bit.  (The alternative is to stat() and then possibly chown(); it's
 
1916
 * more efficient to skip the stat() and just always chown().)  Note
 
1917
 * that a successful chown() here clears the TODO_SGID_CHECK bit, which
 
1918
 * allows set_mode to skip the stat() check for the GID.
 
1919
 */
 
1920
static int
 
1921
set_ownership(struct archive_write_disk *a)
 
1922
{
 
1923
#ifndef __CYGWIN__
 
1924
/* unfortunately, on win32 there is no 'root' user with uid 0,
 
1925
   so we just have to try the chown and see if it works */
 
1926
 
 
1927
        /* If we know we can't change it, don't bother trying. */
 
1928
        if (a->user_uid != 0  &&  a->user_uid != a->uid) {
 
1929
                archive_set_error(&a->archive, errno,
 
1930
                    "Can't set UID=%jd", (intmax_t)a->uid);
 
1931
                return (ARCHIVE_WARN);
 
1932
        }
 
1933
#endif
 
1934
 
 
1935
#ifdef HAVE_FCHOWN
 
1936
        /* If we have an fd, we can avoid a race. */
 
1937
        if (a->fd >= 0 && fchown(a->fd, a->uid, a->gid) == 0) {
 
1938
                /* We've set owner and know uid/gid are correct. */
 
1939
                a->todo &= ~(TODO_OWNER | TODO_SGID_CHECK | TODO_SUID_CHECK);
 
1940
                return (ARCHIVE_OK);
 
1941
        }
 
1942
#endif
 
1943
 
 
1944
        /* We prefer lchown() but will use chown() if that's all we have. */
 
1945
        /* Of course, if we have neither, this will always fail. */
 
1946
#ifdef HAVE_LCHOWN
 
1947
        if (lchown(a->name, a->uid, a->gid) == 0) {
 
1948
                /* We've set owner and know uid/gid are correct. */
 
1949
                a->todo &= ~(TODO_OWNER | TODO_SGID_CHECK | TODO_SUID_CHECK);
 
1950
                return (ARCHIVE_OK);
 
1951
        }
 
1952
#elif HAVE_CHOWN
 
1953
        if (!S_ISLNK(a->mode) && chown(a->name, a->uid, a->gid) == 0) {
 
1954
                /* We've set owner and know uid/gid are correct. */
 
1955
                a->todo &= ~(TODO_OWNER | TODO_SGID_CHECK | TODO_SUID_CHECK);
 
1956
                return (ARCHIVE_OK);
 
1957
        }
 
1958
#endif
 
1959
 
 
1960
        archive_set_error(&a->archive, errno,
 
1961
            "Can't set user=%jd/group=%jd for %s",
 
1962
            (intmax_t)a->uid, (intmax_t)a->gid, a->name);
 
1963
        return (ARCHIVE_WARN);
 
1964
}
 
1965
 
 
1966
/*
 
1967
 * Note: Returns 0 on success, non-zero on failure.
 
1968
 */
 
1969
static int
 
1970
set_time(int fd, int mode, const char *name,
 
1971
    time_t atime, long atime_nsec,
 
1972
    time_t mtime, long mtime_nsec)
 
1973
{
 
1974
        /* Select the best implementation for this platform. */
 
1975
#if defined(HAVE_UTIMENSAT) && defined(HAVE_FUTIMENS)
 
1976
        /*
 
1977
         * utimensat() and futimens() are defined in
 
1978
         * POSIX.1-2008. They support ns resolution and setting times
 
1979
         * on fds and symlinks.
 
1980
         */
 
1981
        struct timespec ts[2];
 
1982
        ts[0].tv_sec = atime;
 
1983
        ts[0].tv_nsec = atime_nsec;
 
1984
        ts[1].tv_sec = mtime;
 
1985
        ts[1].tv_nsec = mtime_nsec;
 
1986
        if (fd >= 0)
 
1987
                return futimens(fd, ts);
 
1988
        return utimensat(AT_FDCWD, name, ts, AT_SYMLINK_NOFOLLOW);
 
1989
 
 
1990
#elif HAVE_UTIMES
 
1991
        /*
 
1992
         * The utimes()-family functions support µs-resolution and
 
1993
         * setting times fds and symlinks.  utimes() is documented as
 
1994
         * LEGACY by POSIX, futimes() and lutimes() are not described
 
1995
         * in POSIX.
 
1996
         */
 
1997
        struct timeval times[2];
 
1998
 
 
1999
        times[0].tv_sec = atime;
 
2000
        times[0].tv_usec = atime_nsec / 1000;
 
2001
        times[1].tv_sec = mtime;
 
2002
        times[1].tv_usec = mtime_nsec / 1000;
 
2003
 
 
2004
#ifdef HAVE_FUTIMES
 
2005
        if (fd >= 0)
 
2006
                return (futimes(fd, times));
 
2007
#else
 
2008
        (void)fd; /* UNUSED */
 
2009
#endif
 
2010
#ifdef HAVE_LUTIMES
 
2011
        (void)mode; /* UNUSED */
 
2012
        return (lutimes(name, times));
 
2013
#else
 
2014
        if (S_ISLNK(mode))
 
2015
                return (0);
 
2016
        return (utimes(name, times));
 
2017
#endif
 
2018
 
 
2019
#elif defined(HAVE_UTIME)
 
2020
        /*
 
2021
         * utime() is POSIX-standard but only supports 1s resolution and
 
2022
         * does not support fds or symlinks.
 
2023
         */
 
2024
        struct utimbuf times;
 
2025
        (void)fd; /* UNUSED */
 
2026
        (void)name; /* UNUSED */
 
2027
        (void)atime_nsec; /* UNUSED */
 
2028
        (void)mtime_nsec; /* UNUSED */
 
2029
        times.actime = atime;
 
2030
        times.modtime = mtime;
 
2031
        if (S_ISLNK(mode))
 
2032
                return (ARCHIVE_OK);
 
2033
        return (utime(name, &times));
 
2034
 
 
2035
#else
 
2036
        /*
 
2037
         * We don't know how to set the time on this platform.
 
2038
         */
 
2039
        return (ARCHIVE_WARN);
 
2040
#endif
 
2041
}
 
2042
 
 
2043
#ifdef F_SETTIMES /* Tru64 */
 
2044
static int
 
2045
set_time_tru64(int fd, int mode, const char *name,
 
2046
    time_t atime, long atime_nsec,
 
2047
    time_t mtime, long mtime_nsec,
 
2048
    time_t ctime, long ctime_nsec)
 
2049
{
 
2050
        struct attr_timbuf tstamp;
 
2051
        struct timeval times[3];
 
2052
        times[0].tv_sec = atime;
 
2053
        times[0].tv_usec = atime_nsec / 1000;
 
2054
        times[1].tv_sec = mtime;
 
2055
        times[1].tv_usec = mtime_nsec / 1000;
 
2056
        times[2].tv_sec = ctime;
 
2057
        times[2].tv_usec = ctime_nsec / 1000;
 
2058
        tstamp.atime = times[0];
 
2059
        tstamp.mtime = times[1];
 
2060
        tstamp.ctime = times[2];
 
2061
        return (fcntl(fd,F_SETTIMES,&tstamp));
 
2062
}
 
2063
#endif /* Tru64 */
 
2064
 
 
2065
static int
 
2066
set_times(struct archive_write_disk *a,
 
2067
    int fd, int mode, const char *name,
 
2068
    time_t atime, long atime_nanos,
 
2069
    time_t birthtime, long birthtime_nanos,
 
2070
    time_t mtime, long mtime_nanos,
 
2071
    time_t ctime, long ctime_nanos)
 
2072
{
 
2073
        /* Note: set_time doesn't use libarchive return conventions!
 
2074
         * It uses syscall conventions.  So 0 here instead of ARCHIVE_OK. */
 
2075
        int r1 = 0, r2 = 0;
 
2076
 
 
2077
#ifdef F_SETTIMES
 
2078
         /*
 
2079
         * on Tru64 try own fcntl first which can restore even the
 
2080
         * ctime, fall back to default code path below if it fails
 
2081
         * or if we are not running as root
 
2082
         */
 
2083
        if (a->user_uid == 0 &&
 
2084
            set_time_tru64(fd, mode, name,
 
2085
                           atime, atime_nanos, mtime,
 
2086
                           mtime_nanos, ctime, ctime_nanos) == 0) {
 
2087
                return (ARCHIVE_OK);
 
2088
        }
 
2089
#endif /* Tru64 */
 
2090
 
 
2091
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
 
2092
        /*
 
2093
         * If you have struct stat.st_birthtime, we assume BSD
 
2094
         * birthtime semantics, in which {f,l,}utimes() updates
 
2095
         * birthtime to earliest mtime.  So we set the time twice,
 
2096
         * first using the birthtime, then using the mtime.  If
 
2097
         * birthtime == mtime, this isn't necessary, so we skip it.
 
2098
         * If birthtime > mtime, then this won't work, so we skip it.
 
2099
         */
 
2100
        if (birthtime < mtime
 
2101
            || (birthtime == mtime && birthtime_nanos < mtime_nanos))
 
2102
                r1 = set_time(fd, mode, name,
 
2103
                              atime, atime_nanos,
 
2104
                              birthtime, birthtime_nanos);
 
2105
#endif
 
2106
        r2 = set_time(fd, mode, name,
 
2107
                      atime, atime_nanos,
 
2108
                      mtime, mtime_nanos);
 
2109
        if (r1 != 0 || r2 != 0) {
 
2110
                archive_set_error(&a->archive, errno,
 
2111
                                  "Can't restore time");
 
2112
                return (ARCHIVE_WARN);
 
2113
        }
 
2114
        return (ARCHIVE_OK);
 
2115
}
 
2116
 
 
2117
static int
 
2118
set_times_from_entry(struct archive_write_disk *a)
 
2119
{
 
2120
        time_t atime, birthtime, mtime, ctime;
 
2121
        long atime_nsec, birthtime_nsec, mtime_nsec, ctime_nsec;
 
2122
 
 
2123
        /* Suitable defaults. */
 
2124
        atime = birthtime = mtime = ctime = a->start_time;
 
2125
        atime_nsec = birthtime_nsec = mtime_nsec = ctime_nsec = 0;
 
2126
 
 
2127
        /* If no time was provided, we're done. */
 
2128
        if (!archive_entry_atime_is_set(a->entry)
 
2129
#if HAVE_STRUCT_STAT_ST_BIRTHTIME
 
2130
            && !archive_entry_birthtime_is_set(a->entry)
 
2131
#endif
 
2132
            && !archive_entry_mtime_is_set(a->entry))
 
2133
                return (ARCHIVE_OK);
 
2134
 
 
2135
        if (archive_entry_atime_is_set(a->entry)) {
 
2136
                atime = archive_entry_atime(a->entry);
 
2137
                atime_nsec = archive_entry_atime_nsec(a->entry);
 
2138
        }
 
2139
        if (archive_entry_birthtime_is_set(a->entry)) {
 
2140
                birthtime = archive_entry_birthtime(a->entry);
 
2141
                birthtime_nsec = archive_entry_birthtime_nsec(a->entry);
 
2142
        }
 
2143
        if (archive_entry_mtime_is_set(a->entry)) {
 
2144
                mtime = archive_entry_mtime(a->entry);
 
2145
                mtime_nsec = archive_entry_mtime_nsec(a->entry);
 
2146
        }
 
2147
        if (archive_entry_ctime_is_set(a->entry)) {
 
2148
                ctime = archive_entry_ctime(a->entry);
 
2149
                ctime_nsec = archive_entry_ctime_nsec(a->entry);
 
2150
        }
 
2151
 
 
2152
        return set_times(a, a->fd, a->mode, a->name,
 
2153
                         atime, atime_nsec,
 
2154
                         birthtime, birthtime_nsec,
 
2155
                         mtime, mtime_nsec,
 
2156
                         ctime, ctime_nsec);
 
2157
}
 
2158
 
 
2159
static int
 
2160
set_mode(struct archive_write_disk *a, int mode)
 
2161
{
 
2162
        int r = ARCHIVE_OK;
 
2163
        mode &= 07777; /* Strip off file type bits. */
 
2164
 
 
2165
        if (a->todo & TODO_SGID_CHECK) {
 
2166
                /*
 
2167
                 * If we don't know the GID is right, we must stat()
 
2168
                 * to verify it.  We can't just check the GID of this
 
2169
                 * process, since systems sometimes set GID from
 
2170
                 * the enclosing dir or based on ACLs.
 
2171
                 */
 
2172
                if ((r = lazy_stat(a)) != ARCHIVE_OK)
 
2173
                        return (r);
 
2174
                if (a->pst->st_gid != a->gid) {
 
2175
                        mode &= ~ S_ISGID;
 
2176
                        if (a->flags & ARCHIVE_EXTRACT_OWNER) {
 
2177
                                /*
 
2178
                                 * This is only an error if you
 
2179
                                 * requested owner restore.  If you
 
2180
                                 * didn't, we'll try to restore
 
2181
                                 * sgid/suid, but won't consider it a
 
2182
                                 * problem if we can't.
 
2183
                                 */
 
2184
                                archive_set_error(&a->archive, -1,
 
2185
                                    "Can't restore SGID bit");
 
2186
                                r = ARCHIVE_WARN;
 
2187
                        }
 
2188
                }
 
2189
                /* While we're here, double-check the UID. */
 
2190
                if (a->pst->st_uid != a->uid
 
2191
                    && (a->todo & TODO_SUID)) {
 
2192
                        mode &= ~ S_ISUID;
 
2193
                        if (a->flags & ARCHIVE_EXTRACT_OWNER) {
 
2194
                                archive_set_error(&a->archive, -1,
 
2195
                                    "Can't restore SUID bit");
 
2196
                                r = ARCHIVE_WARN;
 
2197
                        }
 
2198
                }
 
2199
                a->todo &= ~TODO_SGID_CHECK;
 
2200
                a->todo &= ~TODO_SUID_CHECK;
 
2201
        } else if (a->todo & TODO_SUID_CHECK) {
 
2202
                /*
 
2203
                 * If we don't know the UID is right, we can just check
 
2204
                 * the user, since all systems set the file UID from
 
2205
                 * the process UID.
 
2206
                 */
 
2207
                if (a->user_uid != a->uid) {
 
2208
                        mode &= ~ S_ISUID;
 
2209
                        if (a->flags & ARCHIVE_EXTRACT_OWNER) {
 
2210
                                archive_set_error(&a->archive, -1,
 
2211
                                    "Can't make file SUID");
 
2212
                                r = ARCHIVE_WARN;
 
2213
                        }
 
2214
                }
 
2215
                a->todo &= ~TODO_SUID_CHECK;
 
2216
        }
 
2217
 
 
2218
        if (S_ISLNK(a->mode)) {
 
2219
#ifdef HAVE_LCHMOD
 
2220
                /*
 
2221
                 * If this is a symlink, use lchmod().  If the
 
2222
                 * platform doesn't support lchmod(), just skip it.  A
 
2223
                 * platform that doesn't provide a way to set
 
2224
                 * permissions on symlinks probably ignores
 
2225
                 * permissions on symlinks, so a failure here has no
 
2226
                 * impact.
 
2227
                 */
 
2228
                if (lchmod(a->name, mode) != 0) {
 
2229
                        archive_set_error(&a->archive, errno,
 
2230
                            "Can't set permissions to 0%o", (int)mode);
 
2231
                        r = ARCHIVE_WARN;
 
2232
                }
 
2233
#endif
 
2234
        } else if (!S_ISDIR(a->mode)) {
 
2235
                /*
 
2236
                 * If it's not a symlink and not a dir, then use
 
2237
                 * fchmod() or chmod(), depending on whether we have
 
2238
                 * an fd.  Dirs get their perms set during the
 
2239
                 * post-extract fixup, which is handled elsewhere.
 
2240
                 */
 
2241
#ifdef HAVE_FCHMOD
 
2242
                if (a->fd >= 0) {
 
2243
                        if (fchmod(a->fd, mode) != 0) {
 
2244
                                archive_set_error(&a->archive, errno,
 
2245
                                    "Can't set permissions to 0%o", (int)mode);
 
2246
                                r = ARCHIVE_WARN;
 
2247
                        }
 
2248
                } else
 
2249
#endif
 
2250
                        /* If this platform lacks fchmod(), then
 
2251
                         * we'll just use chmod(). */
 
2252
                        if (chmod(a->name, mode) != 0) {
 
2253
                                archive_set_error(&a->archive, errno,
 
2254
                                    "Can't set permissions to 0%o", (int)mode);
 
2255
                                r = ARCHIVE_WARN;
 
2256
                        }
 
2257
        }
 
2258
        return (r);
 
2259
}
 
2260
 
 
2261
static int
 
2262
set_fflags(struct archive_write_disk *a)
 
2263
{
 
2264
        struct fixup_entry *le;
 
2265
        unsigned long   set, clear;
 
2266
        int             r;
 
2267
        int             critical_flags;
 
2268
        mode_t          mode = archive_entry_mode(a->entry);
 
2269
 
 
2270
        /*
 
2271
         * Make 'critical_flags' hold all file flags that can't be
 
2272
         * immediately restored.  For example, on BSD systems,
 
2273
         * SF_IMMUTABLE prevents hardlinks from being created, so
 
2274
         * should not be set until after any hardlinks are created.  To
 
2275
         * preserve some semblance of portability, this uses #ifdef
 
2276
         * extensively.  Ugly, but it works.
 
2277
         *
 
2278
         * Yes, Virginia, this does create a security race.  It's mitigated
 
2279
         * somewhat by the practice of creating dirs 0700 until the extract
 
2280
         * is done, but it would be nice if we could do more than that.
 
2281
         * People restoring critical file systems should be wary of
 
2282
         * other programs that might try to muck with files as they're
 
2283
         * being restored.
 
2284
         */
 
2285
        /* Hopefully, the compiler will optimize this mess into a constant. */
 
2286
        critical_flags = 0;
 
2287
#ifdef SF_IMMUTABLE
 
2288
        critical_flags |= SF_IMMUTABLE;
 
2289
#endif
 
2290
#ifdef UF_IMMUTABLE
 
2291
        critical_flags |= UF_IMMUTABLE;
 
2292
#endif
 
2293
#ifdef SF_APPEND
 
2294
        critical_flags |= SF_APPEND;
 
2295
#endif
 
2296
#ifdef UF_APPEND
 
2297
        critical_flags |= UF_APPEND;
 
2298
#endif
 
2299
#ifdef EXT2_APPEND_FL
 
2300
        critical_flags |= EXT2_APPEND_FL;
 
2301
#endif
 
2302
#ifdef EXT2_IMMUTABLE_FL
 
2303
        critical_flags |= EXT2_IMMUTABLE_FL;
 
2304
#endif
 
2305
 
 
2306
        if (a->todo & TODO_FFLAGS) {
 
2307
                archive_entry_fflags(a->entry, &set, &clear);
 
2308
 
 
2309
                /*
 
2310
                 * The first test encourages the compiler to eliminate
 
2311
                 * all of this if it's not necessary.
 
2312
                 */
 
2313
                if ((critical_flags != 0)  &&  (set & critical_flags)) {
 
2314
                        le = current_fixup(a, a->name);
 
2315
                        le->fixup |= TODO_FFLAGS;
 
2316
                        le->fflags_set = set;
 
2317
                        /* Store the mode if it's not already there. */
 
2318
                        if ((le->fixup & TODO_MODE) == 0)
 
2319
                                le->mode = mode;
 
2320
                } else {
 
2321
                        r = set_fflags_platform(a, a->fd,
 
2322
                            a->name, mode, set, clear);
 
2323
                        if (r != ARCHIVE_OK)
 
2324
                                return (r);
 
2325
                }
 
2326
        }
 
2327
        return (ARCHIVE_OK);
 
2328
}
 
2329
 
 
2330
 
 
2331
#if ( defined(HAVE_LCHFLAGS) || defined(HAVE_CHFLAGS) || defined(HAVE_FCHFLAGS) ) && defined(HAVE_STRUCT_STAT_ST_FLAGS)
 
2332
/*
 
2333
 * BSD reads flags using stat() and sets them with one of {f,l,}chflags()
 
2334
 */
 
2335
static int
 
2336
set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
 
2337
    mode_t mode, unsigned long set, unsigned long clear)
 
2338
{
 
2339
        int r;
 
2340
 
 
2341
        (void)mode; /* UNUSED */
 
2342
        if (set == 0  && clear == 0)
 
2343
                return (ARCHIVE_OK);
 
2344
 
 
2345
        /*
 
2346
         * XXX Is the stat here really necessary?  Or can I just use
 
2347
         * the 'set' flags directly?  In particular, I'm not sure
 
2348
         * about the correct approach if we're overwriting an existing
 
2349
         * file that already has flags on it. XXX
 
2350
         */
 
2351
        if ((r = lazy_stat(a)) != ARCHIVE_OK)
 
2352
                return (r);
 
2353
 
 
2354
        a->st.st_flags &= ~clear;
 
2355
        a->st.st_flags |= set;
 
2356
#ifdef HAVE_FCHFLAGS
 
2357
        /* If platform has fchflags() and we were given an fd, use it. */
 
2358
        if (fd >= 0 && fchflags(fd, a->st.st_flags) == 0)
 
2359
                return (ARCHIVE_OK);
 
2360
#endif
 
2361
        /*
 
2362
         * If we can't use the fd to set the flags, we'll use the
 
2363
         * pathname to set flags.  We prefer lchflags() but will use
 
2364
         * chflags() if we must.
 
2365
         */
 
2366
#ifdef HAVE_LCHFLAGS
 
2367
        if (lchflags(name, a->st.st_flags) == 0)
 
2368
                return (ARCHIVE_OK);
 
2369
#elif defined(HAVE_CHFLAGS)
 
2370
        if (S_ISLNK(a->st.st_mode)) {
 
2371
                archive_set_error(&a->archive, errno,
 
2372
                    "Can't set file flags on symlink.");
 
2373
                return (ARCHIVE_WARN);
 
2374
        }
 
2375
        if (chflags(name, a->st.st_flags) == 0)
 
2376
                return (ARCHIVE_OK);
 
2377
#endif
 
2378
        archive_set_error(&a->archive, errno,
 
2379
            "Failed to set file flags");
 
2380
        return (ARCHIVE_WARN);
 
2381
}
 
2382
 
 
2383
#elif defined(EXT2_IOC_GETFLAGS) && defined(EXT2_IOC_SETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)
 
2384
/*
 
2385
 * Linux uses ioctl() to read and write file flags.
 
2386
 */
 
2387
static int
 
2388
set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
 
2389
    mode_t mode, unsigned long set, unsigned long clear)
 
2390
{
 
2391
        int              ret;
 
2392
        int              myfd = fd;
 
2393
        unsigned long newflags, oldflags;
 
2394
        unsigned long sf_mask = 0;
 
2395
 
 
2396
        if (set == 0  && clear == 0)
 
2397
                return (ARCHIVE_OK);
 
2398
        /* Only regular files and dirs can have flags. */
 
2399
        if (!S_ISREG(mode) && !S_ISDIR(mode))
 
2400
                return (ARCHIVE_OK);
 
2401
 
 
2402
        /* If we weren't given an fd, open it ourselves. */
 
2403
        if (myfd < 0)
 
2404
                myfd = open(name, O_RDONLY | O_NONBLOCK | O_BINARY);
 
2405
        if (myfd < 0)
 
2406
                return (ARCHIVE_OK);
 
2407
 
 
2408
        /*
 
2409
         * Linux has no define for the flags that are only settable by
 
2410
         * the root user.  This code may seem a little complex, but
 
2411
         * there seem to be some Linux systems that lack these
 
2412
         * defines. (?)  The code below degrades reasonably gracefully
 
2413
         * if sf_mask is incomplete.
 
2414
         */
 
2415
#ifdef EXT2_IMMUTABLE_FL
 
2416
        sf_mask |= EXT2_IMMUTABLE_FL;
 
2417
#endif
 
2418
#ifdef EXT2_APPEND_FL
 
2419
        sf_mask |= EXT2_APPEND_FL;
 
2420
#endif
 
2421
        /*
 
2422
         * XXX As above, this would be way simpler if we didn't have
 
2423
         * to read the current flags from disk. XXX
 
2424
         */
 
2425
        ret = ARCHIVE_OK;
 
2426
 
 
2427
        /* Read the current file flags. */
 
2428
        if (ioctl(myfd, EXT2_IOC_GETFLAGS, &oldflags) < 0)
 
2429
                goto fail;
 
2430
 
 
2431
        /* Try setting the flags as given. */
 
2432
        newflags = (oldflags & ~clear) | set;
 
2433
        if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
 
2434
                goto cleanup;
 
2435
        if (errno != EPERM)
 
2436
                goto fail;
 
2437
 
 
2438
        /* If we couldn't set all the flags, try again with a subset. */
 
2439
        newflags &= ~sf_mask;
 
2440
        oldflags &= sf_mask;
 
2441
        newflags |= oldflags;
 
2442
        if (ioctl(myfd, EXT2_IOC_SETFLAGS, &newflags) >= 0)
 
2443
                goto cleanup;
 
2444
 
 
2445
        /* We couldn't set the flags, so report the failure. */
 
2446
fail:
 
2447
        archive_set_error(&a->archive, errno,
 
2448
            "Failed to set file flags");
 
2449
        ret = ARCHIVE_WARN;
 
2450
cleanup:
 
2451
        if (fd < 0)
 
2452
                close(myfd);
 
2453
        return (ret);
 
2454
}
 
2455
 
 
2456
#else
 
2457
 
 
2458
/*
 
2459
 * Of course, some systems have neither BSD chflags() nor Linux' flags
 
2460
 * support through ioctl().
 
2461
 */
 
2462
static int
 
2463
set_fflags_platform(struct archive_write_disk *a, int fd, const char *name,
 
2464
    mode_t mode, unsigned long set, unsigned long clear)
 
2465
{
 
2466
        (void)a; /* UNUSED */
 
2467
        (void)fd; /* UNUSED */
 
2468
        (void)name; /* UNUSED */
 
2469
        (void)mode; /* UNUSED */
 
2470
        (void)set; /* UNUSED */
 
2471
        (void)clear; /* UNUSED */
 
2472
        return (ARCHIVE_OK);
 
2473
}
 
2474
 
 
2475
#endif /* __linux */
 
2476
 
 
2477
#ifndef HAVE_COPYFILE_H
 
2478
/* Default is to simply drop Mac extended metadata. */
 
2479
static int
 
2480
set_mac_metadata(struct archive_write_disk *a, const char *pathname,
 
2481
                 const void *metadata, size_t metadata_size)
 
2482
{
 
2483
        (void)a; /* UNUSED */
 
2484
        (void)pathname; /* UNUSED */
 
2485
        (void)metadata; /* UNUSED */
 
2486
        (void)metadata_size; /* UNUSED */
 
2487
        return (ARCHIVE_OK);
 
2488
}
 
2489
#else
 
2490
 
 
2491
/*
 
2492
 * On Mac OS, we use copyfile() to unpack the metadata and
 
2493
 * apply it to the target file.
 
2494
 */
 
2495
static int
 
2496
set_mac_metadata(struct archive_write_disk *a, const char *pathname,
 
2497
                 const void *metadata, size_t metadata_size)
 
2498
{
 
2499
        struct archive_string tmp;
 
2500
        ssize_t written;
 
2501
        int fd;
 
2502
        int ret = ARCHIVE_OK;
 
2503
 
 
2504
        /* This would be simpler if copyfile() could just accept the
 
2505
         * metadata as a block of memory; then we could sidestep this
 
2506
         * silly dance of writing the data to disk just so that
 
2507
         * copyfile() can read it back in again. */
 
2508
        archive_string_init(&tmp);
 
2509
        archive_strcpy(&tmp, pathname);
 
2510
        archive_strcat(&tmp, ".XXXXXX");
 
2511
        fd = mkstemp(tmp.s);
 
2512
 
 
2513
        if (fd < 0) {
 
2514
                archive_set_error(&a->archive, errno,
 
2515
                                  "Failed to restore metadata");
 
2516
                return (ARCHIVE_WARN);
 
2517
        }
 
2518
        written = write(fd, metadata, metadata_size);
 
2519
        close(fd);
 
2520
        if (written != metadata_size
 
2521
            || copyfile(tmp.s, pathname, 0,
 
2522
                        COPYFILE_UNPACK | COPYFILE_NOFOLLOW
 
2523
                        | COPYFILE_ACL | COPYFILE_XATTR)) {
 
2524
                archive_set_error(&a->archive, errno,
 
2525
                                  "Failed to restore metadata");
 
2526
                ret = ARCHIVE_WARN;
 
2527
        }
 
2528
        unlink(tmp.s);
 
2529
        return (ret);
 
2530
}
 
2531
#endif
 
2532
 
 
2533
#ifndef HAVE_POSIX_ACL
 
2534
/* Default empty function body to satisfy mainline code. */
 
2535
static int
 
2536
set_acls(struct archive_write_disk *a, int fd, const char *name,
 
2537
         struct archive_acl *acl)
 
2538
{
 
2539
        (void)a; /* UNUSED */
 
2540
        (void)fd; /* UNUSED */
 
2541
        (void)name; /* UNUSED */
 
2542
        (void)acl; /* UNUSED */
 
2543
        return (ARCHIVE_OK);
 
2544
}
 
2545
 
 
2546
#else
 
2547
 
 
2548
/*
 
2549
 * XXX TODO: What about ACL types other than ACCESS and DEFAULT?
 
2550
 */
 
2551
static int
 
2552
set_acls(struct archive_write_disk *a, int fd, const char *name,
 
2553
         struct archive_acl *abstract_acl)
 
2554
{
 
2555
        int              ret;
 
2556
 
 
2557
        ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_ACCESS,
 
2558
            ARCHIVE_ENTRY_ACL_TYPE_ACCESS, "access");
 
2559
        if (ret != ARCHIVE_OK)
 
2560
                return (ret);
 
2561
        ret = set_acl(a, fd, name, abstract_acl, ACL_TYPE_DEFAULT,
 
2562
            ARCHIVE_ENTRY_ACL_TYPE_DEFAULT, "default");
 
2563
        return (ret);
 
2564
}
 
2565
 
 
2566
 
 
2567
static int
 
2568
set_acl(struct archive_write_disk *a, int fd, const char *name,
 
2569
    struct archive_acl *abstract_acl,
 
2570
    acl_type_t acl_type, int ae_requested_type, const char *tname)
 
2571
{
 
2572
        acl_t            acl;
 
2573
        acl_entry_t      acl_entry;
 
2574
        acl_permset_t    acl_permset;
 
2575
        int              ret;
 
2576
        int              ae_type, ae_permset, ae_tag, ae_id;
 
2577
        uid_t            ae_uid;
 
2578
        gid_t            ae_gid;
 
2579
        const char      *ae_name;
 
2580
        int              entries;
 
2581
 
 
2582
        ret = ARCHIVE_OK;
 
2583
        entries = archive_acl_reset(abstract_acl, ae_requested_type);
 
2584
        if (entries == 0)
 
2585
                return (ARCHIVE_OK);
 
2586
        acl = acl_init(entries);
 
2587
        while (archive_acl_next(&a->archive, abstract_acl,
 
2588
            ae_requested_type, &ae_type, &ae_permset, &ae_tag, &ae_id,
 
2589
            &ae_name) == ARCHIVE_OK) {
 
2590
                acl_create_entry(&acl, &acl_entry);
 
2591
 
 
2592
                switch (ae_tag) {
 
2593
                case ARCHIVE_ENTRY_ACL_USER:
 
2594
                        acl_set_tag_type(acl_entry, ACL_USER);
 
2595
                        ae_uid = archive_write_disk_uid(&a->archive,
 
2596
                            ae_name, ae_id);
 
2597
                        acl_set_qualifier(acl_entry, &ae_uid);
 
2598
                        break;
 
2599
                case ARCHIVE_ENTRY_ACL_GROUP:
 
2600
                        acl_set_tag_type(acl_entry, ACL_GROUP);
 
2601
                        ae_gid = archive_write_disk_gid(&a->archive,
 
2602
                            ae_name, ae_id);
 
2603
                        acl_set_qualifier(acl_entry, &ae_gid);
 
2604
                        break;
 
2605
                case ARCHIVE_ENTRY_ACL_USER_OBJ:
 
2606
                        acl_set_tag_type(acl_entry, ACL_USER_OBJ);
 
2607
                        break;
 
2608
                case ARCHIVE_ENTRY_ACL_GROUP_OBJ:
 
2609
                        acl_set_tag_type(acl_entry, ACL_GROUP_OBJ);
 
2610
                        break;
 
2611
                case ARCHIVE_ENTRY_ACL_MASK:
 
2612
                        acl_set_tag_type(acl_entry, ACL_MASK);
 
2613
                        break;
 
2614
                case ARCHIVE_ENTRY_ACL_OTHER:
 
2615
                        acl_set_tag_type(acl_entry, ACL_OTHER);
 
2616
                        break;
 
2617
                default:
 
2618
                        /* XXX */
 
2619
                        break;
 
2620
                }
 
2621
 
 
2622
                acl_get_permset(acl_entry, &acl_permset);
 
2623
                acl_clear_perms(acl_permset);
 
2624
                if (ae_permset & ARCHIVE_ENTRY_ACL_EXECUTE)
 
2625
                        acl_add_perm(acl_permset, ACL_EXECUTE);
 
2626
                if (ae_permset & ARCHIVE_ENTRY_ACL_WRITE)
 
2627
                        acl_add_perm(acl_permset, ACL_WRITE);
 
2628
                if (ae_permset & ARCHIVE_ENTRY_ACL_READ)
 
2629
                        acl_add_perm(acl_permset, ACL_READ);
 
2630
        }
 
2631
 
 
2632
        /* Try restoring the ACL through 'fd' if we can. */
 
2633
#if HAVE_ACL_SET_FD
 
2634
        if (fd >= 0 && acl_type == ACL_TYPE_ACCESS && acl_set_fd(fd, acl) == 0)
 
2635
                ret = ARCHIVE_OK;
 
2636
        else
 
2637
#else
 
2638
#if HAVE_ACL_SET_FD_NP
 
2639
        if (fd >= 0 && acl_set_fd_np(fd, acl, acl_type) == 0)
 
2640
                ret = ARCHIVE_OK;
 
2641
        else
 
2642
#endif
 
2643
#endif
 
2644
        if (acl_set_file(name, acl_type, acl) != 0) {
 
2645
                archive_set_error(&a->archive, errno, "Failed to set %s acl", tname);
 
2646
                ret = ARCHIVE_WARN;
 
2647
        }
 
2648
        acl_free(acl);
 
2649
        return (ret);
 
2650
}
 
2651
#endif
 
2652
 
 
2653
#if HAVE_LSETXATTR || HAVE_LSETEA
 
2654
/*
 
2655
 * Restore extended attributes -  Linux and AIX implementations:
 
2656
 * AIX' ea interface is syntaxwise identical to the Linux xattr interface.
 
2657
 */
 
2658
static int
 
2659
set_xattrs(struct archive_write_disk *a)
 
2660
{
 
2661
        struct archive_entry *entry = a->entry;
 
2662
        static int warning_done = 0;
 
2663
        int ret = ARCHIVE_OK;
 
2664
        int i = archive_entry_xattr_reset(entry);
 
2665
 
 
2666
        while (i--) {
 
2667
                const char *name;
 
2668
                const void *value;
 
2669
                size_t size;
 
2670
                archive_entry_xattr_next(entry, &name, &value, &size);
 
2671
                if (name != NULL &&
 
2672
                                strncmp(name, "xfsroot.", 8) != 0 &&
 
2673
                                strncmp(name, "system.", 7) != 0) {
 
2674
                        int e;
 
2675
#if HAVE_FSETXATTR
 
2676
                        if (a->fd >= 0)
 
2677
                                e = fsetxattr(a->fd, name, value, size, 0);
 
2678
                        else
 
2679
#elif HAVE_FSETEA
 
2680
                        if (a->fd >= 0)
 
2681
                                e = fsetea(a->fd, name, value, size, 0);
 
2682
                        else
 
2683
#endif
 
2684
                        {
 
2685
#if HAVE_LSETXATTR
 
2686
                                e = lsetxattr(archive_entry_pathname(entry),
 
2687
                                    name, value, size, 0);
 
2688
#elif HAVE_LSETEA
 
2689
                                e = lsetea(archive_entry_pathname(entry),
 
2690
                                    name, value, size, 0);
 
2691
#endif
 
2692
                        }
 
2693
                        if (e == -1) {
 
2694
                                if (errno == ENOTSUP || errno == ENOSYS) {
 
2695
                                        if (!warning_done) {
 
2696
                                                warning_done = 1;
 
2697
                                                archive_set_error(&a->archive, errno,
 
2698
                                                    "Cannot restore extended "
 
2699
                                                    "attributes on this file "
 
2700
                                                    "system");
 
2701
                                        }
 
2702
                                } else
 
2703
                                        archive_set_error(&a->archive, errno,
 
2704
                                            "Failed to set extended attribute");
 
2705
                                ret = ARCHIVE_WARN;
 
2706
                        }
 
2707
                } else {
 
2708
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 
2709
                            "Invalid extended attribute encountered");
 
2710
                        ret = ARCHIVE_WARN;
 
2711
                }
 
2712
        }
 
2713
        return (ret);
 
2714
}
 
2715
#elif HAVE_EXTATTR_SET_FILE && HAVE_DECL_EXTATTR_NAMESPACE_USER
 
2716
/*
 
2717
 * Restore extended attributes -  FreeBSD implementation
 
2718
 */
 
2719
static int
 
2720
set_xattrs(struct archive_write_disk *a)
 
2721
{
 
2722
        struct archive_entry *entry = a->entry;
 
2723
        static int warning_done = 0;
 
2724
        int ret = ARCHIVE_OK;
 
2725
        int i = archive_entry_xattr_reset(entry);
 
2726
 
 
2727
        while (i--) {
 
2728
                const char *name;
 
2729
                const void *value;
 
2730
                size_t size;
 
2731
                archive_entry_xattr_next(entry, &name, &value, &size);
 
2732
                if (name != NULL) {
 
2733
                        int e;
 
2734
                        int namespace;
 
2735
 
 
2736
                        if (strncmp(name, "user.", 5) == 0) {
 
2737
                                /* "user." attributes go to user namespace */
 
2738
                                name += 5;
 
2739
                                namespace = EXTATTR_NAMESPACE_USER;
 
2740
                        } else {
 
2741
                                /* Warn about other extended attributes. */
 
2742
                                archive_set_error(&a->archive,
 
2743
                                    ARCHIVE_ERRNO_FILE_FORMAT,
 
2744
                                    "Can't restore extended attribute ``%s''",
 
2745
                                    name);
 
2746
                                ret = ARCHIVE_WARN;
 
2747
                                continue;
 
2748
                        }
 
2749
                        errno = 0;
 
2750
#if HAVE_EXTATTR_SET_FD
 
2751
                        if (a->fd >= 0)
 
2752
                                e = extattr_set_fd(a->fd, namespace, name, value, size);
 
2753
                        else
 
2754
#endif
 
2755
                        /* TODO: should we use extattr_set_link() instead? */
 
2756
                        {
 
2757
                                e = extattr_set_file(archive_entry_pathname(entry),
 
2758
                                    namespace, name, value, size);
 
2759
                        }
 
2760
                        if (e != (int)size) {
 
2761
                                if (errno == ENOTSUP || errno == ENOSYS) {
 
2762
                                        if (!warning_done) {
 
2763
                                                warning_done = 1;
 
2764
                                                archive_set_error(&a->archive, errno,
 
2765
                                                    "Cannot restore extended "
 
2766
                                                    "attributes on this file "
 
2767
                                                    "system");
 
2768
                                        }
 
2769
                                } else {
 
2770
                                        archive_set_error(&a->archive, errno,
 
2771
                                            "Failed to set extended attribute");
 
2772
                                }
 
2773
 
 
2774
                                ret = ARCHIVE_WARN;
 
2775
                        }
 
2776
                }
 
2777
        }
 
2778
        return (ret);
 
2779
}
 
2780
#else
 
2781
/*
 
2782
 * Restore extended attributes - stub implementation for unsupported systems
 
2783
 */
 
2784
static int
 
2785
set_xattrs(struct archive_write_disk *a)
 
2786
{
 
2787
        static int warning_done = 0;
 
2788
 
 
2789
        /* If there aren't any extended attributes, then it's okay not
 
2790
         * to extract them, otherwise, issue a single warning. */
 
2791
        if (archive_entry_xattr_count(a->entry) != 0 && !warning_done) {
 
2792
                warning_done = 1;
 
2793
                archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
 
2794
                    "Cannot restore extended attributes on this system");
 
2795
                return (ARCHIVE_WARN);
 
2796
        }
 
2797
        /* Warning was already emitted; suppress further warnings. */
 
2798
        return (ARCHIVE_OK);
 
2799
}
 
2800
#endif
 
2801
 
 
2802
/*
 
2803
 * Test if file on disk is older than entry.
 
2804
 */
 
2805
static int
 
2806
older(struct stat *st, struct archive_entry *entry)
 
2807
{
 
2808
        /* First, test the seconds and return if we have a definite answer. */
 
2809
        /* Definitely older. */
 
2810
        if (st->st_mtime < archive_entry_mtime(entry))
 
2811
                return (1);
 
2812
        /* Definitely younger. */
 
2813
        if (st->st_mtime > archive_entry_mtime(entry))
 
2814
                return (0);
 
2815
        /* If this platform supports fractional seconds, try those. */
 
2816
#if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
 
2817
        /* Definitely older. */
 
2818
        if (st->st_mtimespec.tv_nsec < archive_entry_mtime_nsec(entry))
 
2819
                return (1);
 
2820
#elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
 
2821
        /* Definitely older. */
 
2822
        if (st->st_mtim.tv_nsec < archive_entry_mtime_nsec(entry))
 
2823
                return (1);
 
2824
#elif HAVE_STRUCT_STAT_ST_MTIME_N
 
2825
        /* older. */
 
2826
        if (st->st_mtime_n < archive_entry_mtime_nsec(entry))
 
2827
                return (1);
 
2828
#elif HAVE_STRUCT_STAT_ST_UMTIME
 
2829
        /* older. */
 
2830
        if (st->st_umtime * 1000 < archive_entry_mtime_nsec(entry))
 
2831
                return (1);
 
2832
#elif HAVE_STRUCT_STAT_ST_MTIME_USEC
 
2833
        /* older. */
 
2834
        if (st->st_mtime_usec * 1000 < archive_entry_mtime_nsec(entry))
 
2835
                return (1);
 
2836
#else
 
2837
        /* This system doesn't have high-res timestamps. */
 
2838
#endif
 
2839
        /* Same age or newer, so not older. */
 
2840
        return (0);
 
2841
}
 
2842
 
 
2843
#endif /* !_WIN32 || __CYGWIN__ */
 
2844