]> Dogcows Code - chaz/tar/blob - src/extract.c
tar: fix -x --overwrite bug (no --dereference, ! O_NOFOLLOW)
[chaz/tar] / src / extract.c
1 /* Extract files from a tar archive.
2
3 Copyright (C) 1988, 1992, 1993, 1994, 1996, 1997, 1998, 1999, 2000,
4 2001, 2003, 2004, 2005, 2006, 2007, 2010 Free Software Foundation, Inc.
5
6 Written by John Gilmore, on 1985-11-19.
7
8 This program is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 3, or (at your option) any later
11 version.
12
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
16 Public License for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */
21
22 #include <system.h>
23 #include <quotearg.h>
24 #include <errno.h>
25 #include <priv-set.h>
26 #include <utimens.h>
27
28 #include "common.h"
29
30 static bool we_are_root; /* true if our effective uid == 0 */
31 static mode_t newdir_umask; /* umask when creating new directories */
32 static mode_t current_umask; /* current umask (which is set to 0 if -p) */
33
34 #define ALL_MODE_BITS ((mode_t) ~ (mode_t) 0)
35
36 #if ! HAVE_FCHMOD && ! defined fchmod
37 # define fchmod(fd, mode) (errno = ENOSYS, -1)
38 #endif
39 #if ! HAVE_FCHOWN && ! defined fchown
40 # define fchown(fd, uid, gid) (errno = ENOSYS, -1)
41 #endif
42
43 /* Return true if an error number ERR means the system call is
44 supported in this case. */
45 static bool
46 implemented (int err)
47 {
48 return ! (err == ENOSYS
49 || err == ENOTSUP
50 || (EOPNOTSUPP != ENOTSUP && err == EOPNOTSUPP));
51 }
52
53 /* List of directories whose statuses we need to extract after we've
54 finished extracting their subsidiary files. If you consider each
55 contiguous subsequence of elements of the form [D]?[^D]*, where [D]
56 represents an element where AFTER_LINKS is nonzero and [^D]
57 represents an element where AFTER_LINKS is zero, then the head
58 of the subsequence has the longest name, and each non-head element
59 in the prefix is an ancestor (in the directory hierarchy) of the
60 preceding element. */
61
62 struct delayed_set_stat
63 {
64 /* Next directory in list. */
65 struct delayed_set_stat *next;
66
67 /* Metadata for this directory. */
68 dev_t dev;
69 ino_t ino;
70 mode_t mode; /* The desired mode is MODE & ~ current_umask. */
71 uid_t uid;
72 gid_t gid;
73 struct timespec atime;
74 struct timespec mtime;
75
76 /* An estimate of the directory's current mode, along with a mask
77 specifying which bits of this estimate are known to be correct.
78 If CURRENT_MODE_MASK is zero, CURRENT_MODE's value doesn't
79 matter. */
80 mode_t current_mode;
81 mode_t current_mode_mask;
82
83 /* This directory is an intermediate directory that was created
84 as an ancestor of some other directory; it was not mentioned
85 in the archive, so do not set its uid, gid, atime, or mtime,
86 and don't alter its mode outside of MODE_RWX. */
87 bool interdir;
88
89 /* Whether symbolic links should be followed when accessing the
90 directory. */
91 int atflag;
92
93 /* Do not set the status of this directory until after delayed
94 links are created. */
95 bool after_links;
96
97 /* Directory that the name is relative to. */
98 int change_dir;
99
100 /* Length and contents of name. */
101 size_t file_name_len;
102 char file_name[1];
103 };
104
105 static struct delayed_set_stat *delayed_set_stat_head;
106
107 /* List of links whose creation we have delayed. */
108 struct delayed_link
109 {
110 /* The next delayed link in the list. */
111 struct delayed_link *next;
112
113 /* The device, inode number and ctime of the placeholder. Use
114 ctime, not mtime, to make false matches less likely if some
115 other process removes the placeholder. */
116 dev_t dev;
117 ino_t ino;
118 struct timespec ctime;
119
120 /* True if the link is symbolic. */
121 bool is_symlink;
122
123 /* The desired metadata, valid only the link is symbolic. */
124 mode_t mode;
125 uid_t uid;
126 gid_t gid;
127 struct timespec atime;
128 struct timespec mtime;
129
130 /* The directory that the sources and target are relative to. */
131 int change_dir;
132
133 /* A list of sources for this link. The sources are all to be
134 hard-linked together. */
135 struct string_list *sources;
136
137 /* The desired target of the desired link. */
138 char target[1];
139 };
140
141 static struct delayed_link *delayed_link_head;
142
143 struct string_list
144 {
145 struct string_list *next;
146 char string[1];
147 };
148
149 /* Set up to extract files. */
150 void
151 extr_init (void)
152 {
153 we_are_root = geteuid () == 0;
154 same_permissions_option += we_are_root;
155 same_owner_option += we_are_root;
156
157 /* Option -p clears the kernel umask, so it does not affect proper
158 restoration of file permissions. New intermediate directories will
159 comply with umask at start of program. */
160
161 newdir_umask = umask (0);
162 if (0 < same_permissions_option)
163 current_umask = 0;
164 else
165 {
166 umask (newdir_umask); /* restore the kernel umask */
167 current_umask = newdir_umask;
168 }
169 }
170
171 /* Use fchmod if possible, fchmodat otherwise. */
172 static int
173 fd_chmod (int fd, char const *file, mode_t mode, int atflag)
174 {
175 if (0 <= fd)
176 {
177 int result = fchmod (fd, mode);
178 if (result == 0 || implemented (errno))
179 return result;
180 }
181 return fchmodat (chdir_fd, file, mode, atflag);
182 }
183
184 /* Use fchown if possible, fchownat otherwise. */
185 static int
186 fd_chown (int fd, char const *file, uid_t uid, gid_t gid, int atflag)
187 {
188 if (0 <= fd)
189 {
190 int result = fchown (fd, uid, gid);
191 if (result == 0 || implemented (errno))
192 return result;
193 }
194 return fchownat (chdir_fd, file, uid, gid, atflag);
195 }
196
197 /* Use fstat if possible, fstatat otherwise. */
198 static int
199 fd_stat (int fd, char const *file, struct stat *st, int atflag)
200 {
201 return (0 <= fd
202 ? fstat (fd, st)
203 : fstatat (chdir_fd, file, st, atflag));
204 }
205
206 /* Set the mode for FILE_NAME to MODE.
207 MODE_MASK specifies the bits of MODE that we care about;
208 thus if MODE_MASK is zero, do nothing.
209 If FD is nonnegative, it is a file descriptor for the file.
210 CURRENT_MODE and CURRENT_MODE_MASK specify information known about
211 the file's current mode, using the style of struct delayed_set_stat.
212 TYPEFLAG specifies the type of the file.
213 ATFLAG specifies the flag to use when statting the file. */
214 static void
215 set_mode (char const *file_name,
216 mode_t mode, mode_t mode_mask, int fd,
217 mode_t current_mode, mode_t current_mode_mask,
218 char typeflag, int atflag)
219 {
220 if (((current_mode ^ mode) | ~ current_mode_mask) & mode_mask)
221 {
222 if (MODE_ALL & ~ mode_mask & ~ current_mode_mask)
223 {
224 struct stat st;
225 if (fd_stat (fd, file_name, &st, atflag) != 0)
226 {
227 stat_error (file_name);
228 return;
229 }
230 current_mode = st.st_mode;
231 }
232
233 current_mode &= MODE_ALL;
234 mode = (current_mode & ~ mode_mask) | (mode & mode_mask);
235
236 if (current_mode != mode)
237 {
238 int chmod_errno =
239 fd_chmod (fd, file_name, mode, atflag) == 0 ? 0 : errno;
240
241 /* On Solaris, chmod may fail if we don't have PRIV_ALL, because
242 setuid-root files would otherwise be a backdoor. See
243 http://opensolaris.org/jive/thread.jspa?threadID=95826
244 (2009-09-03). */
245 if (chmod_errno == EPERM && (mode & S_ISUID)
246 && priv_set_restore_linkdir () == 0)
247 {
248 chmod_errno =
249 fd_chmod (fd, file_name, mode, atflag) == 0 ? 0 : errno;
250 priv_set_remove_linkdir ();
251 }
252
253 /* Linux fchmodat does not support AT_SYMLINK_NOFOLLOW, and
254 returns ENOTSUP even when operating on non-symlinks, try
255 again with the flag disabled if it does not appear to be
256 supported and if the file is not a symlink. This
257 introduces a race, alas. */
258 if (atflag && typeflag != SYMTYPE && ! implemented (chmod_errno))
259 chmod_errno = fd_chmod (fd, file_name, mode, 0) == 0 ? 0 : errno;
260
261 if (chmod_errno
262 && (typeflag != SYMTYPE || implemented (chmod_errno)))
263 {
264 errno = chmod_errno;
265 chmod_error_details (file_name, mode);
266 }
267 }
268 }
269 }
270
271 /* Check time after successfully setting FILE_NAME's time stamp to T. */
272 static void
273 check_time (char const *file_name, struct timespec t)
274 {
275 if (t.tv_sec <= 0)
276 WARNOPT (WARN_TIMESTAMP,
277 (0, 0, _("%s: implausibly old time stamp %s"),
278 file_name, tartime (t, true)));
279 else if (timespec_cmp (volume_start_time, t) < 0)
280 {
281 struct timespec now;
282 gettime (&now);
283 if (timespec_cmp (now, t) < 0)
284 {
285 char buf[TIMESPEC_STRSIZE_BOUND];
286 struct timespec diff;
287 diff.tv_sec = t.tv_sec - now.tv_sec;
288 diff.tv_nsec = t.tv_nsec - now.tv_nsec;
289 if (diff.tv_nsec < 0)
290 {
291 diff.tv_nsec += BILLION;
292 diff.tv_sec--;
293 }
294 WARNOPT (WARN_TIMESTAMP,
295 (0, 0, _("%s: time stamp %s is %s s in the future"),
296 file_name, tartime (t, true), code_timespec (diff, buf)));
297 }
298 }
299 }
300
301 /* Restore stat attributes (owner, group, mode and times) for
302 FILE_NAME, using information given in *ST.
303 If FD is nonnegative, it is a file descriptor for the file.
304 CURRENT_MODE and CURRENT_MODE_MASK specify information known about
305 the file's current mode, using the style of struct delayed_set_stat.
306 TYPEFLAG specifies the type of the file.
307 If INTERDIR, this is an intermediate directory.
308 ATFLAG specifies the flag to use when statting the file. */
309
310 static void
311 set_stat (char const *file_name,
312 struct tar_stat_info const *st,
313 int fd, mode_t current_mode, mode_t current_mode_mask,
314 char typeflag, bool interdir, int atflag)
315 {
316 /* Do the utime before the chmod because some versions of utime are
317 broken and trash the modes of the file. */
318
319 if (! touch_option && ! interdir)
320 {
321 struct timespec ts[2];
322 if (incremental_option)
323 ts[0] = st->atime;
324 else
325 ts[0].tv_nsec = UTIME_OMIT;
326 ts[1] = st->mtime;
327
328 if (fdutimensat (fd, chdir_fd, file_name, ts, atflag) == 0)
329 {
330 if (incremental_option)
331 check_time (file_name, ts[0]);
332 check_time (file_name, ts[1]);
333 }
334 else if (typeflag != SYMTYPE || implemented (errno))
335 utime_error (file_name);
336 }
337
338 if (0 < same_owner_option && ! interdir)
339 {
340 /* Some systems allow non-root users to give files away. Once this
341 done, it is not possible anymore to change file permissions.
342 However, setting file permissions now would be incorrect, since
343 they would apply to the wrong user, and there would be a race
344 condition. So, don't use systems that allow non-root users to
345 give files away. */
346 uid_t uid = st->stat.st_uid;
347 gid_t gid = st->stat.st_gid;
348
349 if (fd_chown (fd, file_name, uid, gid, atflag) == 0)
350 {
351 /* Changing the owner can clear st_mode bits in some cases. */
352 if ((current_mode | ~ current_mode_mask) & S_IXUGO)
353 current_mode_mask &= ~ (current_mode & (S_ISUID | S_ISGID));
354 }
355 else if (typeflag != SYMTYPE || implemented (errno))
356 chown_error_details (file_name, uid, gid);
357 }
358
359 set_mode (file_name,
360 st->stat.st_mode & ~ current_umask,
361 0 < same_permissions_option && ! interdir ? MODE_ALL : MODE_RWX,
362 fd, current_mode, current_mode_mask, typeflag, atflag);
363 }
364
365 /* For each entry H in the leading prefix of entries in HEAD that do
366 not have after_links marked, mark H and fill in its dev and ino
367 members. Assume HEAD && ! HEAD->after_links. */
368 static void
369 mark_after_links (struct delayed_set_stat *head)
370 {
371 struct delayed_set_stat *h = head;
372
373 do
374 {
375 struct stat st;
376 h->after_links = 1;
377
378 if (deref_stat (h->file_name, &st) != 0)
379 stat_error (h->file_name);
380 else
381 {
382 h->dev = st.st_dev;
383 h->ino = st.st_ino;
384 }
385 }
386 while ((h = h->next) && ! h->after_links);
387 }
388
389 /* Remember to restore stat attributes (owner, group, mode and times)
390 for the directory FILE_NAME, using information given in *ST,
391 once we stop extracting files into that directory.
392
393 If ST is null, merely create a placeholder node for an intermediate
394 directory that was created by make_directories.
395
396 NOTICE: this works only if the archive has usual member order, i.e.
397 directory, then the files in that directory. Incremental archive have
398 somewhat reversed order: first go subdirectories, then all other
399 members. To help cope with this case the variable
400 delay_directory_restore_option is set by prepare_to_extract.
401
402 If an archive was explicitely created so that its member order is
403 reversed, some directory timestamps can be restored incorrectly,
404 e.g.:
405 tar --no-recursion -cf archive dir dir/file1 foo dir/file2
406 */
407 static void
408 delay_set_stat (char const *file_name, struct tar_stat_info const *st,
409 mode_t current_mode, mode_t current_mode_mask,
410 mode_t mode, int atflag)
411 {
412 size_t file_name_len = strlen (file_name);
413 struct delayed_set_stat *data =
414 xmalloc (offsetof (struct delayed_set_stat, file_name)
415 + file_name_len + 1);
416 data->next = delayed_set_stat_head;
417 data->mode = mode;
418 if (st)
419 {
420 data->dev = st->stat.st_dev;
421 data->ino = st->stat.st_ino;
422 data->uid = st->stat.st_uid;
423 data->gid = st->stat.st_gid;
424 data->atime = st->atime;
425 data->mtime = st->mtime;
426 }
427 data->file_name_len = file_name_len;
428 data->current_mode = current_mode;
429 data->current_mode_mask = current_mode_mask;
430 data->interdir = ! st;
431 data->atflag = atflag;
432 data->after_links = 0;
433 data->change_dir = chdir_current;
434 strcpy (data->file_name, file_name);
435 delayed_set_stat_head = data;
436 if (must_be_dot_or_slash (file_name))
437 mark_after_links (data);
438 }
439
440 /* Update the delayed_set_stat info for an intermediate directory
441 created within the file name of DIR. The intermediate directory turned
442 out to be the same as this directory, e.g. due to ".." or symbolic
443 links. *DIR_STAT_INFO is the status of the directory. */
444 static void
445 repair_delayed_set_stat (char const *dir,
446 struct stat const *dir_stat_info)
447 {
448 struct delayed_set_stat *data;
449 for (data = delayed_set_stat_head; data; data = data->next)
450 {
451 struct stat st;
452 if (fstatat (chdir_fd, data->file_name, &st, data->atflag) != 0)
453 {
454 stat_error (data->file_name);
455 return;
456 }
457
458 if (st.st_dev == dir_stat_info->st_dev
459 && st.st_ino == dir_stat_info->st_ino)
460 {
461 data->dev = current_stat_info.stat.st_dev;
462 data->ino = current_stat_info.stat.st_ino;
463 data->mode = current_stat_info.stat.st_mode;
464 data->uid = current_stat_info.stat.st_uid;
465 data->gid = current_stat_info.stat.st_gid;
466 data->atime = current_stat_info.atime;
467 data->mtime = current_stat_info.mtime;
468 data->current_mode = st.st_mode;
469 data->current_mode_mask = ALL_MODE_BITS;
470 data->interdir = false;
471 return;
472 }
473 }
474
475 ERROR ((0, 0, _("%s: Unexpected inconsistency when making directory"),
476 quotearg_colon (dir)));
477 }
478
479 /* After a file/link/directory creation has failed, see if
480 it's because some required directory was not present, and if so,
481 create all required directories. Return zero if all the required
482 directories were created, nonzero (issuing a diagnostic) otherwise.
483 Set *INTERDIR_MADE if at least one directory was created. */
484 static int
485 make_directories (char *file_name, bool *interdir_made)
486 {
487 char *cursor0 = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);
488 char *cursor; /* points into the file name */
489
490 for (cursor = cursor0; *cursor; cursor++)
491 {
492 mode_t mode;
493 mode_t desired_mode;
494 int status;
495
496 if (! ISSLASH (*cursor))
497 continue;
498
499 /* Avoid mkdir of empty string, if leading or double '/'. */
500
501 if (cursor == cursor0 || ISSLASH (cursor[-1]))
502 continue;
503
504 /* Avoid mkdir where last part of file name is "." or "..". */
505
506 if (cursor[-1] == '.'
507 && (cursor == cursor0 + 1 || ISSLASH (cursor[-2])
508 || (cursor[-2] == '.'
509 && (cursor == cursor0 + 2 || ISSLASH (cursor[-3])))))
510 continue;
511
512 *cursor = '\0'; /* truncate the name there */
513 desired_mode = MODE_RWX & ~ newdir_umask;
514 mode = desired_mode | (we_are_root ? 0 : MODE_WXUSR);
515 status = mkdirat (chdir_fd, file_name, mode);
516
517 if (status == 0)
518 {
519 /* Create a struct delayed_set_stat even if
520 mode == desired_mode, because
521 repair_delayed_set_stat may need to update the struct. */
522 delay_set_stat (file_name,
523 0, mode & ~ current_umask, MODE_RWX,
524 desired_mode, AT_SYMLINK_NOFOLLOW);
525
526 print_for_mkdir (file_name, cursor - file_name, desired_mode);
527 *interdir_made = true;
528 }
529 else if (errno == EEXIST)
530 status = 0;
531 else
532 {
533 /* Check whether the desired file exists. Even when the
534 file exists, mkdir can fail with some errno value E other
535 than EEXIST, so long as E describes an error condition
536 that also applies. */
537 int e = errno;
538 struct stat st;
539 status = fstatat (chdir_fd, file_name, &st, 0);
540 if (status)
541 {
542 errno = e;
543 mkdir_error (file_name);
544 }
545 }
546
547 *cursor = '/';
548 if (status)
549 return status;
550 }
551
552 return 0;
553 }
554
555 /* Return true if FILE_NAME (with status *STP, if STP) is not a
556 directory, and has a time stamp newer than (or equal to) that of
557 TAR_STAT. */
558 static bool
559 file_newer_p (const char *file_name, struct stat const *stp,
560 struct tar_stat_info *tar_stat)
561 {
562 struct stat st;
563
564 if (!stp)
565 {
566 if (deref_stat (file_name, &st) != 0)
567 {
568 if (errno != ENOENT)
569 {
570 stat_warn (file_name);
571 /* Be safer: if the file exists, assume it is newer. */
572 return true;
573 }
574 return false;
575 }
576 stp = &st;
577 }
578
579 return (! S_ISDIR (stp->st_mode)
580 && tar_timespec_cmp (tar_stat->mtime, get_stat_mtime (stp)) <= 0);
581 }
582
583 #define RECOVER_NO 0
584 #define RECOVER_OK 1
585 #define RECOVER_SKIP 2
586
587 /* Attempt repairing what went wrong with the extraction. Delete an
588 already existing file or create missing intermediate directories.
589 Return RECOVER_OK if we somewhat increased our chances at a successful
590 extraction, RECOVER_NO if there are no chances, and RECOVER_SKIP if the
591 caller should skip extraction of that member. The value of errno is
592 properly restored on returning RECOVER_NO.
593
594 If REGULAR, the caller was trying to extract onto a regular file.
595
596 Set *INTERDIR_MADE if an intermediate directory is made as part of
597 the recovery process. */
598
599 static int
600 maybe_recoverable (char *file_name, bool regular, bool *interdir_made)
601 {
602 int e = errno;
603 struct stat st;
604 struct stat const *stp = 0;
605
606 if (*interdir_made)
607 return RECOVER_NO;
608
609 switch (e)
610 {
611 case ELOOP:
612 if (! regular
613 || old_files_option != OVERWRITE_OLD_FILES || dereference_option)
614 break;
615 if (strchr (file_name, '/'))
616 {
617 if (deref_stat (file_name, &st) != 0)
618 break;
619 stp = &st;
620 }
621
622 /* The caller tried to open a symbolic link with O_NOFOLLOW.
623 Fall through, treating it as an already-existing file. */
624
625 case EEXIST:
626 /* Remove an old file, if the options allow this. */
627
628 switch (old_files_option)
629 {
630 case KEEP_OLD_FILES:
631 return RECOVER_SKIP;
632
633 case KEEP_NEWER_FILES:
634 if (file_newer_p (file_name, stp, &current_stat_info))
635 break;
636 /* FALL THROUGH */
637
638 case DEFAULT_OLD_FILES:
639 case NO_OVERWRITE_DIR_OLD_FILES:
640 case OVERWRITE_OLD_FILES:
641 if (0 < remove_any_file (file_name, ORDINARY_REMOVE_OPTION))
642 return RECOVER_OK;
643 break;
644
645 case UNLINK_FIRST_OLD_FILES:
646 break;
647 }
648
649 case ENOENT:
650 /* Attempt creating missing intermediate directories. */
651 if (make_directories (file_name, interdir_made) == 0 && *interdir_made)
652 return RECOVER_OK;
653 break;
654
655 default:
656 /* Just say we can't do anything about it... */
657 break;
658 }
659
660 errno = e;
661 return RECOVER_NO;
662 }
663
664 /* Fix the statuses of all directories whose statuses need fixing, and
665 which are not ancestors of FILE_NAME. If AFTER_LINKS is
666 nonzero, do this for all such directories; otherwise, stop at the
667 first directory that is marked to be fixed up only after delayed
668 links are applied. */
669 static void
670 apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
671 {
672 size_t file_name_len = strlen (file_name);
673 bool check_for_renamed_directories = 0;
674
675 while (delayed_set_stat_head)
676 {
677 struct delayed_set_stat *data = delayed_set_stat_head;
678 bool skip_this_one = 0;
679 struct stat st;
680 mode_t current_mode = data->current_mode;
681 mode_t current_mode_mask = data->current_mode_mask;
682
683 check_for_renamed_directories |= data->after_links;
684
685 if (after_links < data->after_links
686 || (data->file_name_len < file_name_len
687 && file_name[data->file_name_len]
688 && (ISSLASH (file_name[data->file_name_len])
689 || ISSLASH (file_name[data->file_name_len - 1]))
690 && memcmp (file_name, data->file_name, data->file_name_len) == 0))
691 break;
692
693 chdir_do (data->change_dir);
694
695 if (check_for_renamed_directories)
696 {
697 if (fstatat (chdir_fd, data->file_name, &st, data->atflag) != 0)
698 {
699 stat_error (data->file_name);
700 skip_this_one = 1;
701 }
702 else
703 {
704 current_mode = st.st_mode;
705 current_mode_mask = ALL_MODE_BITS;
706 if (! (st.st_dev == data->dev && st.st_ino == data->ino))
707 {
708 ERROR ((0, 0,
709 _("%s: Directory renamed before its status could be extracted"),
710 quotearg_colon (data->file_name)));
711 skip_this_one = 1;
712 }
713 }
714 }
715
716 if (! skip_this_one)
717 {
718 struct tar_stat_info sb;
719 sb.stat.st_mode = data->mode;
720 sb.stat.st_uid = data->uid;
721 sb.stat.st_gid = data->gid;
722 sb.atime = data->atime;
723 sb.mtime = data->mtime;
724 set_stat (data->file_name, &sb,
725 -1, current_mode, current_mode_mask,
726 DIRTYPE, data->interdir, data->atflag);
727 }
728
729 delayed_set_stat_head = data->next;
730 free (data);
731 }
732 }
733
734 \f
735
736 /* Extractor functions for various member types */
737
738 static int
739 extract_dir (char *file_name, int typeflag)
740 {
741 int status;
742 mode_t mode;
743 mode_t current_mode = 0;
744 mode_t current_mode_mask = 0;
745 int atflag = 0;
746 bool interdir_made = false;
747
748 /* Save 'root device' to avoid purging mount points. */
749 if (one_file_system_option && root_device == 0)
750 {
751 struct stat st;
752
753 if (fstatat (chdir_fd, ".", &st, 0) != 0)
754 stat_diag (".");
755 else
756 root_device = st.st_dev;
757 }
758
759 if (incremental_option)
760 /* Read the entry and delete files that aren't listed in the archive. */
761 purge_directory (file_name);
762 else if (typeflag == GNUTYPE_DUMPDIR)
763 skip_member ();
764
765 /* If ownership or permissions will be restored later, create the
766 directory with restrictive permissions at first, so that in the
767 meantime processes owned by other users do not inadvertently
768 create files under this directory that inherit the wrong owner,
769 group, or permissions from the directory. If not root, though,
770 make the directory writeable and searchable at first, so that
771 files can be created under it. */
772 mode = ((current_stat_info.stat.st_mode
773 & (0 < same_owner_option || 0 < same_permissions_option
774 ? S_IRWXU
775 : MODE_RWX))
776 | (we_are_root ? 0 : MODE_WXUSR));
777
778 for (;;)
779 {
780 status = mkdirat (chdir_fd, file_name, mode);
781 if (status == 0)
782 {
783 current_mode = mode & ~ current_umask;
784 current_mode_mask = MODE_RWX;
785 atflag = AT_SYMLINK_NOFOLLOW;
786 break;
787 }
788
789 if (errno == EEXIST
790 && (interdir_made
791 || old_files_option == DEFAULT_OLD_FILES
792 || old_files_option == OVERWRITE_OLD_FILES))
793 {
794 struct stat st;
795 if (deref_stat (file_name, &st) == 0)
796 {
797 current_mode = st.st_mode;
798 current_mode_mask = ALL_MODE_BITS;
799
800 if (S_ISDIR (current_mode))
801 {
802 if (interdir_made)
803 {
804 repair_delayed_set_stat (file_name, &st);
805 return 0;
806 }
807 break;
808 }
809 }
810 errno = EEXIST;
811 }
812
813 switch (maybe_recoverable (file_name, false, &interdir_made))
814 {
815 case RECOVER_OK:
816 continue;
817
818 case RECOVER_SKIP:
819 break;
820
821 case RECOVER_NO:
822 if (errno != EEXIST)
823 {
824 mkdir_error (file_name);
825 return 1;
826 }
827 break;
828 }
829 break;
830 }
831
832 if (status == 0
833 || old_files_option == DEFAULT_OLD_FILES
834 || old_files_option == OVERWRITE_OLD_FILES)
835 delay_set_stat (file_name, &current_stat_info,
836 current_mode, current_mode_mask,
837 current_stat_info.stat.st_mode, atflag);
838 return status;
839 }
840
841
842
843 static int
844 open_output_file (char const *file_name, int typeflag, mode_t mode,
845 mode_t *current_mode, mode_t *current_mode_mask)
846 {
847 int fd;
848 bool overwriting_old_files = old_files_option == OVERWRITE_OLD_FILES;
849 int openflag = (O_WRONLY | O_BINARY | O_CLOEXEC | O_NOCTTY | O_NONBLOCK
850 | O_CREAT
851 | (overwriting_old_files
852 ? O_TRUNC | (dereference_option ? 0 : O_NOFOLLOW)
853 : O_EXCL));
854
855 if (typeflag == CONTTYPE)
856 {
857 static int conttype_diagnosed;
858
859 if (!conttype_diagnosed)
860 {
861 conttype_diagnosed = 1;
862 WARNOPT (WARN_CONTIGUOUS_CAST,
863 (0, 0, _("Extracting contiguous files as regular files")));
864 }
865 }
866
867 /* If O_NOFOLLOW is needed but does not work, check for a symlink
868 separately. There's a race condition, but that cannot be avoided
869 on hosts lacking O_NOFOLLOW. */
870 if (! O_NOFOLLOW && overwriting_old_files && ! dereference_option)
871 {
872 struct stat st;
873 if (fstatat (chdir_fd, file_name, &st, AT_SYMLINK_NOFOLLOW) == 0
874 && S_ISLNK (st.st_mode))
875 {
876 errno = ELOOP;
877 return -1;
878 }
879 }
880
881 fd = openat (chdir_fd, file_name, openflag, mode);
882 if (0 <= fd)
883 {
884 if (overwriting_old_files)
885 {
886 struct stat st;
887 if (fstat (fd, &st) != 0)
888 {
889 int e = errno;
890 close (fd);
891 errno = e;
892 return -1;
893 }
894 if (! S_ISREG (st.st_mode))
895 {
896 close (fd);
897 errno = EEXIST;
898 return -1;
899 }
900 *current_mode = st.st_mode;
901 *current_mode_mask = ALL_MODE_BITS;
902 }
903 else
904 {
905 *current_mode = mode & ~ current_umask;
906 *current_mode_mask = MODE_RWX;
907 }
908 }
909
910 return fd;
911 }
912
913 static int
914 extract_file (char *file_name, int typeflag)
915 {
916 int fd;
917 off_t size;
918 union block *data_block;
919 int status;
920 size_t count;
921 size_t written;
922 bool interdir_made = false;
923 mode_t mode = (current_stat_info.stat.st_mode & MODE_RWX
924 & ~ (0 < same_owner_option ? S_IRWXG | S_IRWXO : 0));
925 mode_t current_mode = 0;
926 mode_t current_mode_mask = 0;
927
928 if (to_stdout_option)
929 fd = STDOUT_FILENO;
930 else if (to_command_option)
931 {
932 fd = sys_exec_command (file_name, 'f', &current_stat_info);
933 if (fd < 0)
934 {
935 skip_member ();
936 return 0;
937 }
938 }
939 else
940 {
941 while ((fd = open_output_file (file_name, typeflag, mode,
942 &current_mode, &current_mode_mask))
943 < 0)
944 {
945 int recover = maybe_recoverable (file_name, true, &interdir_made);
946 if (recover != RECOVER_OK)
947 {
948 skip_member ();
949 if (recover == RECOVER_SKIP)
950 return 0;
951 open_error (file_name);
952 return 1;
953 }
954 }
955 }
956
957 mv_begin_read (&current_stat_info);
958 if (current_stat_info.is_sparse)
959 sparse_extract_file (fd, &current_stat_info, &size);
960 else
961 for (size = current_stat_info.stat.st_size; size > 0; )
962 {
963 mv_size_left (size);
964
965 /* Locate data, determine max length writeable, write it,
966 block that we have used the data, then check if the write
967 worked. */
968
969 data_block = find_next_block ();
970 if (! data_block)
971 {
972 ERROR ((0, 0, _("Unexpected EOF in archive")));
973 break; /* FIXME: What happens, then? */
974 }
975
976 written = available_space_after (data_block);
977
978 if (written > size)
979 written = size;
980 errno = 0;
981 count = full_write (fd, data_block->buffer, written);
982 size -= written;
983
984 set_next_block_after ((union block *)
985 (data_block->buffer + written - 1));
986 if (count != written)
987 {
988 if (!to_command_option)
989 write_error_details (file_name, count, written);
990 /* FIXME: shouldn't we restore from backup? */
991 break;
992 }
993 }
994
995 skip_file (size);
996
997 mv_end ();
998
999 /* If writing to stdout, don't try to do anything to the filename;
1000 it doesn't exist, or we don't want to touch it anyway. */
1001
1002 if (to_stdout_option)
1003 return 0;
1004
1005 if (! to_command_option)
1006 set_stat (file_name, &current_stat_info, fd,
1007 current_mode, current_mode_mask, typeflag, false,
1008 (old_files_option == OVERWRITE_OLD_FILES
1009 ? 0 : AT_SYMLINK_NOFOLLOW));
1010
1011 status = close (fd);
1012 if (status < 0)
1013 close_error (file_name);
1014
1015 if (to_command_option)
1016 sys_wait_command ();
1017
1018 return status;
1019 }
1020
1021 /* Create a placeholder file with name FILE_NAME, which will be
1022 replaced after other extraction is done by a symbolic link if
1023 IS_SYMLINK is true, and by a hard link otherwise. Set
1024 *INTERDIR_MADE if an intermediate directory is made in the
1025 process. */
1026
1027 static int
1028 create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
1029 {
1030 int fd;
1031 struct stat st;
1032
1033 while ((fd = openat (chdir_fd, file_name, O_WRONLY | O_CREAT | O_EXCL, 0)) < 0)
1034 {
1035 switch (maybe_recoverable (file_name, false, interdir_made))
1036 {
1037 case RECOVER_OK:
1038 continue;
1039
1040 case RECOVER_SKIP:
1041 return 0;
1042
1043 case RECOVER_NO:
1044 open_error (file_name);
1045 return -1;
1046 }
1047 }
1048
1049 if (fstat (fd, &st) != 0)
1050 {
1051 stat_error (file_name);
1052 close (fd);
1053 }
1054 else if (close (fd) != 0)
1055 close_error (file_name);
1056 else
1057 {
1058 struct delayed_set_stat *h;
1059 struct delayed_link *p =
1060 xmalloc (offsetof (struct delayed_link, target)
1061 + strlen (current_stat_info.link_name)
1062 + 1);
1063 p->next = delayed_link_head;
1064 delayed_link_head = p;
1065 p->dev = st.st_dev;
1066 p->ino = st.st_ino;
1067 p->ctime = get_stat_ctime (&st);
1068 p->is_symlink = is_symlink;
1069 if (is_symlink)
1070 {
1071 p->mode = current_stat_info.stat.st_mode;
1072 p->uid = current_stat_info.stat.st_uid;
1073 p->gid = current_stat_info.stat.st_gid;
1074 p->atime = current_stat_info.atime;
1075 p->mtime = current_stat_info.mtime;
1076 }
1077 p->change_dir = chdir_current;
1078 p->sources = xmalloc (offsetof (struct string_list, string)
1079 + strlen (file_name) + 1);
1080 p->sources->next = 0;
1081 strcpy (p->sources->string, file_name);
1082 strcpy (p->target, current_stat_info.link_name);
1083
1084 h = delayed_set_stat_head;
1085 if (h && ! h->after_links
1086 && strncmp (file_name, h->file_name, h->file_name_len) == 0
1087 && ISSLASH (file_name[h->file_name_len])
1088 && (last_component (file_name) == file_name + h->file_name_len + 1))
1089 mark_after_links (h);
1090
1091 return 0;
1092 }
1093
1094 return -1;
1095 }
1096
1097 static int
1098 extract_link (char *file_name, int typeflag)
1099 {
1100 bool interdir_made = false;
1101 char const *link_name;
1102 int rc;
1103
1104 link_name = current_stat_info.link_name;
1105
1106 if (! absolute_names_option && contains_dot_dot (link_name))
1107 return create_placeholder_file (file_name, false, &interdir_made);
1108
1109 do
1110 {
1111 struct stat st1, st2;
1112 int e;
1113 int status = linkat (chdir_fd, link_name, chdir_fd, file_name, 0);
1114 e = errno;
1115
1116 if (status == 0)
1117 {
1118 struct delayed_link *ds = delayed_link_head;
1119 if (ds
1120 && fstatat (chdir_fd, link_name, &st1, AT_SYMLINK_NOFOLLOW) == 0)
1121 for (; ds; ds = ds->next)
1122 if (ds->change_dir == chdir_current
1123 && ds->dev == st1.st_dev
1124 && ds->ino == st1.st_ino
1125 && timespec_cmp (ds->ctime, get_stat_ctime (&st1)) == 0)
1126 {
1127 struct string_list *p = xmalloc (offsetof (struct string_list, string)
1128 + strlen (file_name) + 1);
1129 strcpy (p->string, file_name);
1130 p->next = ds->sources;
1131 ds->sources = p;
1132 break;
1133 }
1134 return 0;
1135 }
1136 else if ((e == EEXIST && strcmp (link_name, file_name) == 0)
1137 || ((fstatat (chdir_fd, link_name, &st1, AT_SYMLINK_NOFOLLOW)
1138 == 0)
1139 && (fstatat (chdir_fd, file_name, &st2, AT_SYMLINK_NOFOLLOW)
1140 == 0)
1141 && st1.st_dev == st2.st_dev
1142 && st1.st_ino == st2.st_ino))
1143 return 0;
1144
1145 errno = e;
1146 }
1147 while ((rc = maybe_recoverable (file_name, false, &interdir_made))
1148 == RECOVER_OK);
1149
1150 if (rc == RECOVER_SKIP)
1151 return 0;
1152 if (!(incremental_option && errno == EEXIST))
1153 {
1154 link_error (link_name, file_name);
1155 return 1;
1156 }
1157 return 0;
1158 }
1159
1160 static int
1161 extract_symlink (char *file_name, int typeflag)
1162 {
1163 #ifdef HAVE_SYMLINK
1164 bool interdir_made = false;
1165
1166 if (! absolute_names_option
1167 && (IS_ABSOLUTE_FILE_NAME (current_stat_info.link_name)
1168 || contains_dot_dot (current_stat_info.link_name)))
1169 return create_placeholder_file (file_name, true, &interdir_made);
1170
1171 while (symlinkat (current_stat_info.link_name, chdir_fd, file_name) != 0)
1172 switch (maybe_recoverable (file_name, false, &interdir_made))
1173 {
1174 case RECOVER_OK:
1175 continue;
1176
1177 case RECOVER_SKIP:
1178 return 0;
1179
1180 case RECOVER_NO:
1181 symlink_error (current_stat_info.link_name, file_name);
1182 return -1;
1183 }
1184
1185 set_stat (file_name, &current_stat_info, -1, 0, 0,
1186 SYMTYPE, false, AT_SYMLINK_NOFOLLOW);
1187 return 0;
1188
1189 #else
1190 static int warned_once;
1191
1192 if (!warned_once)
1193 {
1194 warned_once = 1;
1195 WARNOPT (WARN_SYMBOLIC_CAST,
1196 (0, 0,
1197 _("Attempting extraction of symbolic links as hard links")));
1198 }
1199 return extract_link (file_name, typeflag);
1200 #endif
1201 }
1202
1203 #if S_IFCHR || S_IFBLK
1204 static int
1205 extract_node (char *file_name, int typeflag)
1206 {
1207 bool interdir_made = false;
1208 mode_t mode = (current_stat_info.stat.st_mode & MODE_RWX
1209 & ~ (0 < same_owner_option ? S_IRWXG | S_IRWXO : 0));
1210
1211 while (mknodat (chdir_fd, file_name, mode, current_stat_info.stat.st_rdev)
1212 != 0)
1213 switch (maybe_recoverable (file_name, false, &interdir_made))
1214 {
1215 case RECOVER_OK:
1216 continue;
1217
1218 case RECOVER_SKIP:
1219 return 0;
1220
1221 case RECOVER_NO:
1222 mknod_error (file_name);
1223 return -1;
1224 }
1225
1226 set_stat (file_name, &current_stat_info, -1,
1227 mode & ~ current_umask, MODE_RWX,
1228 typeflag, false, AT_SYMLINK_NOFOLLOW);
1229 return 0;
1230 }
1231 #endif
1232
1233 #if HAVE_MKFIFO || defined mkfifo
1234 static int
1235 extract_fifo (char *file_name, int typeflag)
1236 {
1237 bool interdir_made = false;
1238 mode_t mode = (current_stat_info.stat.st_mode & MODE_RWX
1239 & ~ (0 < same_owner_option ? S_IRWXG | S_IRWXO : 0));
1240
1241 while (mkfifoat (chdir_fd, file_name, mode) != 0)
1242 switch (maybe_recoverable (file_name, false, &interdir_made))
1243 {
1244 case RECOVER_OK:
1245 continue;
1246
1247 case RECOVER_SKIP:
1248 return 0;
1249
1250 case RECOVER_NO:
1251 mkfifo_error (file_name);
1252 return -1;
1253 }
1254
1255 set_stat (file_name, &current_stat_info, -1,
1256 mode & ~ current_umask, MODE_RWX,
1257 typeflag, false, AT_SYMLINK_NOFOLLOW);
1258 return 0;
1259 }
1260 #endif
1261
1262 static int
1263 extract_volhdr (char *file_name, int typeflag)
1264 {
1265 skip_member ();
1266 return 0;
1267 }
1268
1269 static int
1270 extract_failure (char *file_name, int typeflag)
1271 {
1272 return 1;
1273 }
1274
1275 typedef int (*tar_extractor_t) (char *file_name, int typeflag);
1276
1277 \f
1278
1279 /* Prepare to extract a file. Find extractor function.
1280 Return zero if extraction should not proceed. */
1281
1282 static int
1283 prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
1284 {
1285 int rc = 1;
1286
1287 if (EXTRACT_OVER_PIPE)
1288 rc = 0;
1289
1290 /* Select the extractor */
1291 switch (typeflag)
1292 {
1293 case GNUTYPE_SPARSE:
1294 *fun = extract_file;
1295 rc = 1;
1296 break;
1297
1298 case AREGTYPE:
1299 case REGTYPE:
1300 case CONTTYPE:
1301 /* Appears to be a file. But BSD tar uses the convention that a slash
1302 suffix means a directory. */
1303 if (current_stat_info.had_trailing_slash)
1304 *fun = extract_dir;
1305 else
1306 {
1307 *fun = extract_file;
1308 rc = 1;
1309 }
1310 break;
1311
1312 case SYMTYPE:
1313 *fun = extract_symlink;
1314 break;
1315
1316 case LNKTYPE:
1317 *fun = extract_link;
1318 break;
1319
1320 #if S_IFCHR
1321 case CHRTYPE:
1322 current_stat_info.stat.st_mode |= S_IFCHR;
1323 *fun = extract_node;
1324 break;
1325 #endif
1326
1327 #if S_IFBLK
1328 case BLKTYPE:
1329 current_stat_info.stat.st_mode |= S_IFBLK;
1330 *fun = extract_node;
1331 break;
1332 #endif
1333
1334 #if HAVE_MKFIFO || defined mkfifo
1335 case FIFOTYPE:
1336 *fun = extract_fifo;
1337 break;
1338 #endif
1339
1340 case DIRTYPE:
1341 case GNUTYPE_DUMPDIR:
1342 *fun = extract_dir;
1343 if (current_stat_info.is_dumpdir)
1344 delay_directory_restore_option = true;
1345 break;
1346
1347 case GNUTYPE_VOLHDR:
1348 *fun = extract_volhdr;
1349 break;
1350
1351 case GNUTYPE_MULTIVOL:
1352 ERROR ((0, 0,
1353 _("%s: Cannot extract -- file is continued from another volume"),
1354 quotearg_colon (current_stat_info.file_name)));
1355 *fun = extract_failure;
1356 break;
1357
1358 case GNUTYPE_LONGNAME:
1359 case GNUTYPE_LONGLINK:
1360 ERROR ((0, 0, _("Unexpected long name header")));
1361 *fun = extract_failure;
1362 break;
1363
1364 default:
1365 WARNOPT (WARN_UNKNOWN_CAST,
1366 (0, 0,
1367 _("%s: Unknown file type `%c', extracted as normal file"),
1368 quotearg_colon (file_name), typeflag));
1369 *fun = extract_file;
1370 }
1371
1372 /* Determine whether the extraction should proceed */
1373 if (rc == 0)
1374 return 0;
1375
1376 switch (old_files_option)
1377 {
1378 case UNLINK_FIRST_OLD_FILES:
1379 if (!remove_any_file (file_name,
1380 recursive_unlink_option ? RECURSIVE_REMOVE_OPTION
1381 : ORDINARY_REMOVE_OPTION)
1382 && errno && errno != ENOENT)
1383 {
1384 unlink_error (file_name);
1385 return 0;
1386 }
1387 break;
1388
1389 case KEEP_NEWER_FILES:
1390 if (file_newer_p (file_name, 0, &current_stat_info))
1391 {
1392 WARNOPT (WARN_IGNORE_NEWER,
1393 (0, 0, _("Current %s is newer or same age"),
1394 quote (file_name)));
1395 return 0;
1396 }
1397 break;
1398
1399 default:
1400 break;
1401 }
1402
1403 return 1;
1404 }
1405
1406 /* Extract a file from the archive. */
1407 void
1408 extract_archive (void)
1409 {
1410 char typeflag;
1411 tar_extractor_t fun;
1412
1413 fatal_exit_hook = extract_finish;
1414
1415 set_next_block_after (current_header);
1416
1417 if (!current_stat_info.file_name[0]
1418 || (interactive_option
1419 && !confirm ("extract", current_stat_info.file_name)))
1420 {
1421 skip_member ();
1422 return;
1423 }
1424
1425 /* Print the block from current_header and current_stat. */
1426 if (verbose_option)
1427 print_header (&current_stat_info, current_header, -1);
1428
1429 /* Restore stats for all non-ancestor directories, unless
1430 it is an incremental archive.
1431 (see NOTICE in the comment to delay_set_stat above) */
1432 if (!delay_directory_restore_option)
1433 {
1434 int dir = chdir_current;
1435 apply_nonancestor_delayed_set_stat (current_stat_info.file_name, 0);
1436 chdir_do (dir);
1437 }
1438
1439 /* Take a safety backup of a previously existing file. */
1440
1441 if (backup_option)
1442 if (!maybe_backup_file (current_stat_info.file_name, 0))
1443 {
1444 int e = errno;
1445 ERROR ((0, e, _("%s: Was unable to backup this file"),
1446 quotearg_colon (current_stat_info.file_name)));
1447 skip_member ();
1448 return;
1449 }
1450
1451 /* Extract the archive entry according to its type. */
1452 /* KLUDGE */
1453 typeflag = sparse_member_p (&current_stat_info) ?
1454 GNUTYPE_SPARSE : current_header->header.typeflag;
1455
1456 if (prepare_to_extract (current_stat_info.file_name, typeflag, &fun))
1457 {
1458 if (fun && (*fun) (current_stat_info.file_name, typeflag)
1459 && backup_option)
1460 undo_last_backup ();
1461 }
1462 else
1463 skip_member ();
1464
1465 }
1466
1467 /* Extract the links whose final extraction were delayed. */
1468 static void
1469 apply_delayed_links (void)
1470 {
1471 struct delayed_link *ds;
1472
1473 for (ds = delayed_link_head; ds; )
1474 {
1475 struct string_list *sources = ds->sources;
1476 char const *valid_source = 0;
1477
1478 chdir_do (ds->change_dir);
1479
1480 for (sources = ds->sources; sources; sources = sources->next)
1481 {
1482 char const *source = sources->string;
1483 struct stat st;
1484
1485 /* Make sure the placeholder file is still there. If not,
1486 don't create a link, as the placeholder was probably
1487 removed by a later extraction. */
1488 if (fstatat (chdir_fd, source, &st, AT_SYMLINK_NOFOLLOW) == 0
1489 && st.st_dev == ds->dev
1490 && st.st_ino == ds->ino
1491 && timespec_cmp (get_stat_ctime (&st), ds->ctime) == 0)
1492 {
1493 /* Unlink the placeholder, then create a hard link if possible,
1494 a symbolic link otherwise. */
1495 if (unlinkat (chdir_fd, source, 0) != 0)
1496 unlink_error (source);
1497 else if (valid_source
1498 && (linkat (chdir_fd, valid_source, chdir_fd, source, 0)
1499 == 0))
1500 ;
1501 else if (!ds->is_symlink)
1502 {
1503 if (linkat (chdir_fd, ds->target, chdir_fd, source, 0) != 0)
1504 link_error (ds->target, source);
1505 }
1506 else if (symlinkat (ds->target, chdir_fd, source) != 0)
1507 symlink_error (ds->target, source);
1508 else
1509 {
1510 struct tar_stat_info st1;
1511 st1.stat.st_mode = ds->mode;
1512 st1.stat.st_uid = ds->uid;
1513 st1.stat.st_gid = ds->gid;
1514 st1.atime = ds->atime;
1515 st1.mtime = ds->mtime;
1516 set_stat (source, &st1, -1, 0, 0, SYMTYPE,
1517 false, AT_SYMLINK_NOFOLLOW);
1518 valid_source = source;
1519 }
1520 }
1521 }
1522
1523 for (sources = ds->sources; sources; )
1524 {
1525 struct string_list *next = sources->next;
1526 free (sources);
1527 sources = next;
1528 }
1529
1530 {
1531 struct delayed_link *next = ds->next;
1532 free (ds);
1533 ds = next;
1534 }
1535 }
1536
1537 delayed_link_head = 0;
1538 }
1539
1540 /* Finish the extraction of an archive. */
1541 void
1542 extract_finish (void)
1543 {
1544 /* First, fix the status of ordinary directories that need fixing. */
1545 apply_nonancestor_delayed_set_stat ("", 0);
1546
1547 /* Then, apply delayed links, so that they don't affect delayed
1548 directory status-setting for ordinary directories. */
1549 apply_delayed_links ();
1550
1551 /* Finally, fix the status of directories that are ancestors
1552 of delayed links. */
1553 apply_nonancestor_delayed_set_stat ("", 1);
1554 }
1555
1556 bool
1557 rename_directory (char *src, char *dst)
1558 {
1559 if (renameat (chdir_fd, src, chdir_fd, dst) != 0)
1560 {
1561 int e = errno;
1562 bool interdir_made;
1563
1564 switch (e)
1565 {
1566 case ENOENT:
1567 if (make_directories (dst, &interdir_made) == 0)
1568 {
1569 if (renameat (chdir_fd, src, chdir_fd, dst) == 0)
1570 return true;
1571 e = errno;
1572 }
1573 break;
1574
1575 case EXDEV:
1576 /* FIXME: Fall back to recursive copying */
1577
1578 default:
1579 break;
1580 }
1581
1582 ERROR ((0, e, _("Cannot rename %s to %s"),
1583 quote_n (0, src),
1584 quote_n (1, dst)));
1585 return false;
1586 }
1587 return true;
1588 }
This page took 0.097734 seconds and 5 git commands to generate.