]> Dogcows Code - chaz/tar/blob - src/extract.c
tar: --dereference consistency
[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 non-zero if a directory
482 was created. */
483 static int
484 make_directories (char *file_name)
485 {
486 char *cursor0 = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);
487 char *cursor; /* points into the file name */
488 int did_something = 0; /* did we do anything yet? */
489 int status;
490
491 for (cursor = cursor0; *cursor; cursor++)
492 {
493 mode_t mode;
494 mode_t desired_mode;
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 did_something = 1;
528
529 *cursor = '/';
530 continue;
531 }
532
533 *cursor = '/';
534
535 if (errno == EEXIST)
536 continue; /* Directory already exists. */
537 else if ((errno == ENOSYS /* Automounted dirs on Solaris return
538 this. Reported by Warren Hyde
539 <Warren.Hyde@motorola.com> */
540 || ERRNO_IS_EACCES) /* Turbo C mkdir gives a funny errno. */
541 && faccessat (chdir_fd, file_name, W_OK, AT_EACCESS) == 0)
542 continue;
543
544 /* Some other error in the mkdir. We return to the caller. */
545 break;
546 }
547
548 return did_something; /* tell them to retry if we made one */
549 }
550
551 /* Return true if FILE_NAME (with status *STP, if STP) is not a
552 directory, and has a time stamp newer than (or equal to) that of
553 TAR_STAT. */
554 static bool
555 file_newer_p (const char *file_name, struct stat const *stp,
556 struct tar_stat_info *tar_stat)
557 {
558 struct stat st;
559
560 if (!stp)
561 {
562 if (deref_stat (file_name, &st) != 0)
563 {
564 if (errno != ENOENT)
565 {
566 stat_warn (file_name);
567 /* Be safer: if the file exists, assume it is newer. */
568 return true;
569 }
570 return false;
571 }
572 stp = &st;
573 }
574
575 return (! S_ISDIR (stp->st_mode)
576 && tar_timespec_cmp (tar_stat->mtime, get_stat_mtime (stp)) <= 0);
577 }
578
579 #define RECOVER_NO 0
580 #define RECOVER_OK 1
581 #define RECOVER_SKIP 2
582
583 /* Attempt repairing what went wrong with the extraction. Delete an
584 already existing file or create missing intermediate directories.
585 Return RECOVER_OK if we somewhat increased our chances at a successful
586 extraction, RECOVER_NO if there are no chances, and RECOVER_SKIP if the
587 caller should skip extraction of that member. The value of errno is
588 properly restored on returning RECOVER_NO.
589
590 If REGULAR, the caller was trying to extract onto a regular file.
591
592 Set *INTERDIR_MADE if an intermediate directory is made as part of
593 the recovery process. */
594
595 static int
596 maybe_recoverable (char *file_name, bool regular, bool *interdir_made)
597 {
598 int e = errno;
599 struct stat st;
600 struct stat const *stp = 0;
601
602 if (*interdir_made)
603 return RECOVER_NO;
604
605 switch (e)
606 {
607 case ELOOP:
608 if (! regular
609 || old_files_option != OVERWRITE_OLD_FILES || dereference_option)
610 break;
611 if (strchr (file_name, '/'))
612 {
613 if (deref_stat (file_name, &st) != 0)
614 break;
615 stp = &st;
616 }
617
618 /* The caller tried to open a symbolic link with O_NOFOLLOW.
619 Fall through, treating it as an already-existing file. */
620
621 case EEXIST:
622 /* Remove an old file, if the options allow this. */
623
624 switch (old_files_option)
625 {
626 case KEEP_OLD_FILES:
627 return RECOVER_SKIP;
628
629 case KEEP_NEWER_FILES:
630 if (file_newer_p (file_name, stp, &current_stat_info))
631 break;
632 /* FALL THROUGH */
633
634 case DEFAULT_OLD_FILES:
635 case NO_OVERWRITE_DIR_OLD_FILES:
636 case OVERWRITE_OLD_FILES:
637 if (0 < remove_any_file (file_name, ORDINARY_REMOVE_OPTION))
638 return RECOVER_OK;
639 break;
640
641 case UNLINK_FIRST_OLD_FILES:
642 break;
643 }
644
645 case ENOENT:
646 /* Attempt creating missing intermediate directories. */
647 if (make_directories (file_name))
648 {
649 *interdir_made = true;
650 return RECOVER_OK;
651 }
652 break;
653
654 default:
655 /* Just say we can't do anything about it... */
656 break;
657 }
658
659 errno = e;
660 return RECOVER_NO;
661 }
662
663 /* Fix the statuses of all directories whose statuses need fixing, and
664 which are not ancestors of FILE_NAME. If AFTER_LINKS is
665 nonzero, do this for all such directories; otherwise, stop at the
666 first directory that is marked to be fixed up only after delayed
667 links are applied. */
668 static void
669 apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
670 {
671 size_t file_name_len = strlen (file_name);
672 bool check_for_renamed_directories = 0;
673
674 while (delayed_set_stat_head)
675 {
676 struct delayed_set_stat *data = delayed_set_stat_head;
677 bool skip_this_one = 0;
678 struct stat st;
679 mode_t current_mode = data->current_mode;
680 mode_t current_mode_mask = data->current_mode_mask;
681
682 check_for_renamed_directories |= data->after_links;
683
684 if (after_links < data->after_links
685 || (data->file_name_len < file_name_len
686 && file_name[data->file_name_len]
687 && (ISSLASH (file_name[data->file_name_len])
688 || ISSLASH (file_name[data->file_name_len - 1]))
689 && memcmp (file_name, data->file_name, data->file_name_len) == 0))
690 break;
691
692 chdir_do (data->change_dir);
693
694 if (check_for_renamed_directories)
695 {
696 if (fstatat (chdir_fd, data->file_name, &st, data->atflag) != 0)
697 {
698 stat_error (data->file_name);
699 skip_this_one = 1;
700 }
701 else
702 {
703 current_mode = st.st_mode;
704 current_mode_mask = ALL_MODE_BITS;
705 if (! (st.st_dev == data->dev && st.st_ino == data->ino))
706 {
707 ERROR ((0, 0,
708 _("%s: Directory renamed before its status could be extracted"),
709 quotearg_colon (data->file_name)));
710 skip_this_one = 1;
711 }
712 }
713 }
714
715 if (! skip_this_one)
716 {
717 struct tar_stat_info sb;
718 sb.stat.st_mode = data->mode;
719 sb.stat.st_uid = data->uid;
720 sb.stat.st_gid = data->gid;
721 sb.atime = data->atime;
722 sb.mtime = data->mtime;
723 set_stat (data->file_name, &sb,
724 -1, current_mode, current_mode_mask,
725 DIRTYPE, data->interdir, data->atflag);
726 }
727
728 delayed_set_stat_head = data->next;
729 free (data);
730 }
731 }
732
733 \f
734
735 /* Extractor functions for various member types */
736
737 static int
738 extract_dir (char *file_name, int typeflag)
739 {
740 int status;
741 mode_t mode;
742 mode_t current_mode = 0;
743 mode_t current_mode_mask = 0;
744 int atflag = 0;
745 bool interdir_made = false;
746
747 /* Save 'root device' to avoid purging mount points. */
748 if (one_file_system_option && root_device == 0)
749 {
750 struct stat st;
751
752 if (fstatat (chdir_fd, ".", &st, 0) != 0)
753 stat_diag (".");
754 else
755 root_device = st.st_dev;
756 }
757
758 if (incremental_option)
759 /* Read the entry and delete files that aren't listed in the archive. */
760 purge_directory (file_name);
761 else if (typeflag == GNUTYPE_DUMPDIR)
762 skip_member ();
763
764 /* If ownership or permissions will be restored later, create the
765 directory with restrictive permissions at first, so that in the
766 meantime processes owned by other users do not inadvertently
767 create files under this directory that inherit the wrong owner,
768 group, or permissions from the directory. If not root, though,
769 make the directory writeable and searchable at first, so that
770 files can be created under it. */
771 mode = ((current_stat_info.stat.st_mode
772 & (0 < same_owner_option || 0 < same_permissions_option
773 ? S_IRWXU
774 : MODE_RWX))
775 | (we_are_root ? 0 : MODE_WXUSR));
776
777 for (;;)
778 {
779 status = mkdir (file_name, mode);
780 if (status == 0)
781 {
782 current_mode = mode & ~ current_umask;
783 current_mode_mask = MODE_RWX;
784 atflag = AT_SYMLINK_NOFOLLOW;
785 break;
786 }
787
788 if (errno == EEXIST
789 && (interdir_made
790 || old_files_option == DEFAULT_OLD_FILES
791 || old_files_option == OVERWRITE_OLD_FILES))
792 {
793 struct stat st;
794 if (deref_stat (file_name, &st) == 0)
795 {
796 current_mode = st.st_mode;
797 current_mode_mask = ALL_MODE_BITS;
798
799 if (S_ISDIR (current_mode))
800 {
801 if (interdir_made)
802 {
803 repair_delayed_set_stat (file_name, &st);
804 return 0;
805 }
806 break;
807 }
808 }
809 errno = EEXIST;
810 }
811
812 switch (maybe_recoverable (file_name, false, &interdir_made))
813 {
814 case RECOVER_OK:
815 continue;
816
817 case RECOVER_SKIP:
818 break;
819
820 case RECOVER_NO:
821 if (errno != EEXIST)
822 {
823 mkdir_error (file_name);
824 return 1;
825 }
826 break;
827 }
828 break;
829 }
830
831 if (status == 0
832 || old_files_option == DEFAULT_OLD_FILES
833 || old_files_option == OVERWRITE_OLD_FILES)
834 delay_set_stat (file_name, &current_stat_info,
835 current_mode, current_mode_mask,
836 current_stat_info.stat.st_mode, atflag);
837 return status;
838 }
839
840
841
842 static int
843 open_output_file (char const *file_name, int typeflag, mode_t mode,
844 mode_t *current_mode, mode_t *current_mode_mask)
845 {
846 int fd;
847 bool overwriting_old_files = old_files_option == OVERWRITE_OLD_FILES;
848 int openflag = (O_WRONLY | O_BINARY | O_CLOEXEC | O_NOCTTY | O_NONBLOCK
849 | O_CREAT
850 | (overwriting_old_files
851 ? O_TRUNC | (dereference_option ? 0 : O_NOFOLLOW)
852 : O_EXCL));
853
854 if (typeflag == CONTTYPE)
855 {
856 static int conttype_diagnosed;
857
858 if (!conttype_diagnosed)
859 {
860 conttype_diagnosed = 1;
861 WARNOPT (WARN_CONTIGUOUS_CAST,
862 (0, 0, _("Extracting contiguous files as regular files")));
863 }
864 }
865
866 fd = openat (chdir_fd, file_name, openflag, mode);
867 if (0 <= fd)
868 {
869 if (overwriting_old_files)
870 {
871 struct stat st;
872 if (fstat (fd, &st) != 0)
873 {
874 int e = errno;
875 close (fd);
876 errno = e;
877 return -1;
878 }
879 if (! S_ISREG (st.st_mode))
880 {
881 close (fd);
882 errno = EEXIST;
883 return -1;
884 }
885 *current_mode = st.st_mode;
886 *current_mode_mask = ALL_MODE_BITS;
887 }
888 else
889 {
890 *current_mode = mode & ~ current_umask;
891 *current_mode_mask = MODE_RWX;
892 }
893 }
894
895 return fd;
896 }
897
898 static int
899 extract_file (char *file_name, int typeflag)
900 {
901 int fd;
902 off_t size;
903 union block *data_block;
904 int status;
905 size_t count;
906 size_t written;
907 bool interdir_made = false;
908 mode_t mode = (current_stat_info.stat.st_mode & MODE_RWX
909 & ~ (0 < same_owner_option ? S_IRWXG | S_IRWXO : 0));
910 mode_t current_mode = 0;
911 mode_t current_mode_mask = 0;
912
913 if (to_stdout_option)
914 fd = STDOUT_FILENO;
915 else if (to_command_option)
916 {
917 fd = sys_exec_command (file_name, 'f', &current_stat_info);
918 if (fd < 0)
919 {
920 skip_member ();
921 return 0;
922 }
923 }
924 else
925 {
926 while ((fd = open_output_file (file_name, typeflag, mode,
927 &current_mode, &current_mode_mask))
928 < 0)
929 {
930 int recover = maybe_recoverable (file_name, true, &interdir_made);
931 if (recover != RECOVER_OK)
932 {
933 skip_member ();
934 if (recover == RECOVER_SKIP)
935 return 0;
936 open_error (file_name);
937 return 1;
938 }
939 }
940 }
941
942 mv_begin_read (&current_stat_info);
943 if (current_stat_info.is_sparse)
944 sparse_extract_file (fd, &current_stat_info, &size);
945 else
946 for (size = current_stat_info.stat.st_size; size > 0; )
947 {
948 mv_size_left (size);
949
950 /* Locate data, determine max length writeable, write it,
951 block that we have used the data, then check if the write
952 worked. */
953
954 data_block = find_next_block ();
955 if (! data_block)
956 {
957 ERROR ((0, 0, _("Unexpected EOF in archive")));
958 break; /* FIXME: What happens, then? */
959 }
960
961 written = available_space_after (data_block);
962
963 if (written > size)
964 written = size;
965 errno = 0;
966 count = full_write (fd, data_block->buffer, written);
967 size -= written;
968
969 set_next_block_after ((union block *)
970 (data_block->buffer + written - 1));
971 if (count != written)
972 {
973 if (!to_command_option)
974 write_error_details (file_name, count, written);
975 /* FIXME: shouldn't we restore from backup? */
976 break;
977 }
978 }
979
980 skip_file (size);
981
982 mv_end ();
983
984 /* If writing to stdout, don't try to do anything to the filename;
985 it doesn't exist, or we don't want to touch it anyway. */
986
987 if (to_stdout_option)
988 return 0;
989
990 if (! to_command_option)
991 set_stat (file_name, &current_stat_info, fd,
992 current_mode, current_mode_mask, typeflag, false,
993 (old_files_option == OVERWRITE_OLD_FILES
994 ? 0 : AT_SYMLINK_NOFOLLOW));
995
996 status = close (fd);
997 if (status < 0)
998 close_error (file_name);
999
1000 if (to_command_option)
1001 sys_wait_command ();
1002
1003 return status;
1004 }
1005
1006 /* Create a placeholder file with name FILE_NAME, which will be
1007 replaced after other extraction is done by a symbolic link if
1008 IS_SYMLINK is true, and by a hard link otherwise. Set
1009 *INTERDIR_MADE if an intermediate directory is made in the
1010 process. */
1011
1012 static int
1013 create_placeholder_file (char *file_name, bool is_symlink, bool *interdir_made)
1014 {
1015 int fd;
1016 struct stat st;
1017
1018 while ((fd = openat (chdir_fd, file_name, O_WRONLY | O_CREAT | O_EXCL, 0)) < 0)
1019 {
1020 switch (maybe_recoverable (file_name, false, interdir_made))
1021 {
1022 case RECOVER_OK:
1023 continue;
1024
1025 case RECOVER_SKIP:
1026 return 0;
1027
1028 case RECOVER_NO:
1029 open_error (file_name);
1030 return -1;
1031 }
1032 }
1033
1034 if (fstat (fd, &st) != 0)
1035 {
1036 stat_error (file_name);
1037 close (fd);
1038 }
1039 else if (close (fd) != 0)
1040 close_error (file_name);
1041 else
1042 {
1043 struct delayed_set_stat *h;
1044 struct delayed_link *p =
1045 xmalloc (offsetof (struct delayed_link, target)
1046 + strlen (current_stat_info.link_name)
1047 + 1);
1048 p->next = delayed_link_head;
1049 delayed_link_head = p;
1050 p->dev = st.st_dev;
1051 p->ino = st.st_ino;
1052 p->ctime = get_stat_ctime (&st);
1053 p->is_symlink = is_symlink;
1054 if (is_symlink)
1055 {
1056 p->mode = current_stat_info.stat.st_mode;
1057 p->uid = current_stat_info.stat.st_uid;
1058 p->gid = current_stat_info.stat.st_gid;
1059 p->atime = current_stat_info.atime;
1060 p->mtime = current_stat_info.mtime;
1061 }
1062 p->change_dir = chdir_current;
1063 p->sources = xmalloc (offsetof (struct string_list, string)
1064 + strlen (file_name) + 1);
1065 p->sources->next = 0;
1066 strcpy (p->sources->string, file_name);
1067 strcpy (p->target, current_stat_info.link_name);
1068
1069 h = delayed_set_stat_head;
1070 if (h && ! h->after_links
1071 && strncmp (file_name, h->file_name, h->file_name_len) == 0
1072 && ISSLASH (file_name[h->file_name_len])
1073 && (last_component (file_name) == file_name + h->file_name_len + 1))
1074 mark_after_links (h);
1075
1076 return 0;
1077 }
1078
1079 return -1;
1080 }
1081
1082 static int
1083 extract_link (char *file_name, int typeflag)
1084 {
1085 bool interdir_made = false;
1086 char const *link_name;
1087 int rc;
1088
1089 link_name = current_stat_info.link_name;
1090
1091 if (! absolute_names_option && contains_dot_dot (link_name))
1092 return create_placeholder_file (file_name, false, &interdir_made);
1093
1094 do
1095 {
1096 struct stat st1, st2;
1097 int e;
1098 int status = linkat (chdir_fd, link_name, chdir_fd, file_name, 0);
1099 e = errno;
1100
1101 if (status == 0)
1102 {
1103 struct delayed_link *ds = delayed_link_head;
1104 if (ds
1105 && fstatat (chdir_fd, link_name, &st1, AT_SYMLINK_NOFOLLOW) == 0)
1106 for (; ds; ds = ds->next)
1107 if (ds->change_dir == chdir_current
1108 && ds->dev == st1.st_dev
1109 && ds->ino == st1.st_ino
1110 && timespec_cmp (ds->ctime, get_stat_ctime (&st1)) == 0)
1111 {
1112 struct string_list *p = xmalloc (offsetof (struct string_list, string)
1113 + strlen (file_name) + 1);
1114 strcpy (p->string, file_name);
1115 p->next = ds->sources;
1116 ds->sources = p;
1117 break;
1118 }
1119 return 0;
1120 }
1121 else if ((e == EEXIST && strcmp (link_name, file_name) == 0)
1122 || ((fstatat (chdir_fd, link_name, &st1, AT_SYMLINK_NOFOLLOW)
1123 == 0)
1124 && (fstatat (chdir_fd, file_name, &st2, AT_SYMLINK_NOFOLLOW)
1125 == 0)
1126 && st1.st_dev == st2.st_dev
1127 && st1.st_ino == st2.st_ino))
1128 return 0;
1129
1130 errno = e;
1131 }
1132 while ((rc = maybe_recoverable (file_name, false, &interdir_made))
1133 == RECOVER_OK);
1134
1135 if (rc == RECOVER_SKIP)
1136 return 0;
1137 if (!(incremental_option && errno == EEXIST))
1138 {
1139 link_error (link_name, file_name);
1140 return 1;
1141 }
1142 return 0;
1143 }
1144
1145 static int
1146 extract_symlink (char *file_name, int typeflag)
1147 {
1148 #ifdef HAVE_SYMLINK
1149 bool interdir_made = false;
1150
1151 if (! absolute_names_option
1152 && (IS_ABSOLUTE_FILE_NAME (current_stat_info.link_name)
1153 || contains_dot_dot (current_stat_info.link_name)))
1154 return create_placeholder_file (file_name, true, &interdir_made);
1155
1156 while (symlinkat (current_stat_info.link_name, chdir_fd, file_name) != 0)
1157 switch (maybe_recoverable (file_name, false, &interdir_made))
1158 {
1159 case RECOVER_OK:
1160 continue;
1161
1162 case RECOVER_SKIP:
1163 return 0;
1164
1165 case RECOVER_NO:
1166 symlink_error (current_stat_info.link_name, file_name);
1167 return -1;
1168 }
1169
1170 set_stat (file_name, &current_stat_info, -1, 0, 0,
1171 SYMTYPE, false, AT_SYMLINK_NOFOLLOW);
1172 return 0;
1173
1174 #else
1175 static int warned_once;
1176
1177 if (!warned_once)
1178 {
1179 warned_once = 1;
1180 WARNOPT (WARN_SYMBOLIC_CAST,
1181 (0, 0,
1182 _("Attempting extraction of symbolic links as hard links")));
1183 }
1184 return extract_link (file_name, typeflag);
1185 #endif
1186 }
1187
1188 #if S_IFCHR || S_IFBLK
1189 static int
1190 extract_node (char *file_name, int typeflag)
1191 {
1192 bool interdir_made = false;
1193 mode_t mode = (current_stat_info.stat.st_mode & MODE_RWX
1194 & ~ (0 < same_owner_option ? S_IRWXG | S_IRWXO : 0));
1195
1196 while (mknodat (chdir_fd, file_name, mode, current_stat_info.stat.st_rdev)
1197 != 0)
1198 switch (maybe_recoverable (file_name, false, &interdir_made))
1199 {
1200 case RECOVER_OK:
1201 continue;
1202
1203 case RECOVER_SKIP:
1204 return 0;
1205
1206 case RECOVER_NO:
1207 mknod_error (file_name);
1208 return -1;
1209 }
1210
1211 set_stat (file_name, &current_stat_info, -1,
1212 mode & ~ current_umask, MODE_RWX,
1213 typeflag, false, AT_SYMLINK_NOFOLLOW);
1214 return 0;
1215 }
1216 #endif
1217
1218 #if HAVE_MKFIFO || defined mkfifo
1219 static int
1220 extract_fifo (char *file_name, int typeflag)
1221 {
1222 bool interdir_made = false;
1223 mode_t mode = (current_stat_info.stat.st_mode & MODE_RWX
1224 & ~ (0 < same_owner_option ? S_IRWXG | S_IRWXO : 0));
1225
1226 while (mkfifoat (chdir_fd, file_name, mode) != 0)
1227 switch (maybe_recoverable (file_name, false, &interdir_made))
1228 {
1229 case RECOVER_OK:
1230 continue;
1231
1232 case RECOVER_SKIP:
1233 return 0;
1234
1235 case RECOVER_NO:
1236 mkfifo_error (file_name);
1237 return -1;
1238 }
1239
1240 set_stat (file_name, &current_stat_info, -1,
1241 mode & ~ current_umask, MODE_RWX,
1242 typeflag, false, AT_SYMLINK_NOFOLLOW);
1243 return 0;
1244 }
1245 #endif
1246
1247 static int
1248 extract_volhdr (char *file_name, int typeflag)
1249 {
1250 skip_member ();
1251 return 0;
1252 }
1253
1254 static int
1255 extract_failure (char *file_name, int typeflag)
1256 {
1257 return 1;
1258 }
1259
1260 typedef int (*tar_extractor_t) (char *file_name, int typeflag);
1261
1262 \f
1263
1264 /* Prepare to extract a file. Find extractor function.
1265 Return zero if extraction should not proceed. */
1266
1267 static int
1268 prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
1269 {
1270 int rc = 1;
1271
1272 if (EXTRACT_OVER_PIPE)
1273 rc = 0;
1274
1275 /* Select the extractor */
1276 switch (typeflag)
1277 {
1278 case GNUTYPE_SPARSE:
1279 *fun = extract_file;
1280 rc = 1;
1281 break;
1282
1283 case AREGTYPE:
1284 case REGTYPE:
1285 case CONTTYPE:
1286 /* Appears to be a file. But BSD tar uses the convention that a slash
1287 suffix means a directory. */
1288 if (current_stat_info.had_trailing_slash)
1289 *fun = extract_dir;
1290 else
1291 {
1292 *fun = extract_file;
1293 rc = 1;
1294 }
1295 break;
1296
1297 case SYMTYPE:
1298 *fun = extract_symlink;
1299 break;
1300
1301 case LNKTYPE:
1302 *fun = extract_link;
1303 break;
1304
1305 #if S_IFCHR
1306 case CHRTYPE:
1307 current_stat_info.stat.st_mode |= S_IFCHR;
1308 *fun = extract_node;
1309 break;
1310 #endif
1311
1312 #if S_IFBLK
1313 case BLKTYPE:
1314 current_stat_info.stat.st_mode |= S_IFBLK;
1315 *fun = extract_node;
1316 break;
1317 #endif
1318
1319 #if HAVE_MKFIFO || defined mkfifo
1320 case FIFOTYPE:
1321 *fun = extract_fifo;
1322 break;
1323 #endif
1324
1325 case DIRTYPE:
1326 case GNUTYPE_DUMPDIR:
1327 *fun = extract_dir;
1328 if (current_stat_info.is_dumpdir)
1329 delay_directory_restore_option = true;
1330 break;
1331
1332 case GNUTYPE_VOLHDR:
1333 *fun = extract_volhdr;
1334 break;
1335
1336 case GNUTYPE_MULTIVOL:
1337 ERROR ((0, 0,
1338 _("%s: Cannot extract -- file is continued from another volume"),
1339 quotearg_colon (current_stat_info.file_name)));
1340 *fun = extract_failure;
1341 break;
1342
1343 case GNUTYPE_LONGNAME:
1344 case GNUTYPE_LONGLINK:
1345 ERROR ((0, 0, _("Unexpected long name header")));
1346 *fun = extract_failure;
1347 break;
1348
1349 default:
1350 WARNOPT (WARN_UNKNOWN_CAST,
1351 (0, 0,
1352 _("%s: Unknown file type `%c', extracted as normal file"),
1353 quotearg_colon (file_name), typeflag));
1354 *fun = extract_file;
1355 }
1356
1357 /* Determine whether the extraction should proceed */
1358 if (rc == 0)
1359 return 0;
1360
1361 switch (old_files_option)
1362 {
1363 case UNLINK_FIRST_OLD_FILES:
1364 if (!remove_any_file (file_name,
1365 recursive_unlink_option ? RECURSIVE_REMOVE_OPTION
1366 : ORDINARY_REMOVE_OPTION)
1367 && errno && errno != ENOENT)
1368 {
1369 unlink_error (file_name);
1370 return 0;
1371 }
1372 break;
1373
1374 case KEEP_NEWER_FILES:
1375 if (file_newer_p (file_name, 0, &current_stat_info))
1376 {
1377 WARNOPT (WARN_IGNORE_NEWER,
1378 (0, 0, _("Current %s is newer or same age"),
1379 quote (file_name)));
1380 return 0;
1381 }
1382 break;
1383
1384 default:
1385 break;
1386 }
1387
1388 return 1;
1389 }
1390
1391 /* Extract a file from the archive. */
1392 void
1393 extract_archive (void)
1394 {
1395 char typeflag;
1396 tar_extractor_t fun;
1397
1398 fatal_exit_hook = extract_finish;
1399
1400 set_next_block_after (current_header);
1401
1402 if (!current_stat_info.file_name[0]
1403 || (interactive_option
1404 && !confirm ("extract", current_stat_info.file_name)))
1405 {
1406 skip_member ();
1407 return;
1408 }
1409
1410 /* Print the block from current_header and current_stat. */
1411 if (verbose_option)
1412 print_header (&current_stat_info, current_header, -1);
1413
1414 /* Restore stats for all non-ancestor directories, unless
1415 it is an incremental archive.
1416 (see NOTICE in the comment to delay_set_stat above) */
1417 if (!delay_directory_restore_option)
1418 {
1419 int dir = chdir_current;
1420 apply_nonancestor_delayed_set_stat (current_stat_info.file_name, 0);
1421 chdir_do (dir);
1422 }
1423
1424 /* Take a safety backup of a previously existing file. */
1425
1426 if (backup_option)
1427 if (!maybe_backup_file (current_stat_info.file_name, 0))
1428 {
1429 int e = errno;
1430 ERROR ((0, e, _("%s: Was unable to backup this file"),
1431 quotearg_colon (current_stat_info.file_name)));
1432 skip_member ();
1433 return;
1434 }
1435
1436 /* Extract the archive entry according to its type. */
1437 /* KLUDGE */
1438 typeflag = sparse_member_p (&current_stat_info) ?
1439 GNUTYPE_SPARSE : current_header->header.typeflag;
1440
1441 if (prepare_to_extract (current_stat_info.file_name, typeflag, &fun))
1442 {
1443 if (fun && (*fun) (current_stat_info.file_name, typeflag)
1444 && backup_option)
1445 undo_last_backup ();
1446 }
1447 else
1448 skip_member ();
1449
1450 }
1451
1452 /* Extract the links whose final extraction were delayed. */
1453 static void
1454 apply_delayed_links (void)
1455 {
1456 struct delayed_link *ds;
1457
1458 for (ds = delayed_link_head; ds; )
1459 {
1460 struct string_list *sources = ds->sources;
1461 char const *valid_source = 0;
1462
1463 chdir_do (ds->change_dir);
1464
1465 for (sources = ds->sources; sources; sources = sources->next)
1466 {
1467 char const *source = sources->string;
1468 struct stat st;
1469
1470 /* Make sure the placeholder file is still there. If not,
1471 don't create a link, as the placeholder was probably
1472 removed by a later extraction. */
1473 if (fstatat (chdir_fd, source, &st, AT_SYMLINK_NOFOLLOW) == 0
1474 && st.st_dev == ds->dev
1475 && st.st_ino == ds->ino
1476 && timespec_cmp (get_stat_ctime (&st), ds->ctime) == 0)
1477 {
1478 /* Unlink the placeholder, then create a hard link if possible,
1479 a symbolic link otherwise. */
1480 if (unlinkat (chdir_fd, source, 0) != 0)
1481 unlink_error (source);
1482 else if (valid_source
1483 && (linkat (chdir_fd, valid_source, chdir_fd, source, 0)
1484 == 0))
1485 ;
1486 else if (!ds->is_symlink)
1487 {
1488 if (linkat (chdir_fd, ds->target, chdir_fd, source, 0) != 0)
1489 link_error (ds->target, source);
1490 }
1491 else if (symlinkat (ds->target, chdir_fd, source) != 0)
1492 symlink_error (ds->target, source);
1493 else
1494 {
1495 struct tar_stat_info st1;
1496 st1.stat.st_mode = ds->mode;
1497 st1.stat.st_uid = ds->uid;
1498 st1.stat.st_gid = ds->gid;
1499 st1.atime = ds->atime;
1500 st1.mtime = ds->mtime;
1501 set_stat (source, &st1, -1, 0, 0, SYMTYPE,
1502 false, AT_SYMLINK_NOFOLLOW);
1503 valid_source = source;
1504 }
1505 }
1506 }
1507
1508 for (sources = ds->sources; sources; )
1509 {
1510 struct string_list *next = sources->next;
1511 free (sources);
1512 sources = next;
1513 }
1514
1515 {
1516 struct delayed_link *next = ds->next;
1517 free (ds);
1518 ds = next;
1519 }
1520 }
1521
1522 delayed_link_head = 0;
1523 }
1524
1525 /* Finish the extraction of an archive. */
1526 void
1527 extract_finish (void)
1528 {
1529 /* First, fix the status of ordinary directories that need fixing. */
1530 apply_nonancestor_delayed_set_stat ("", 0);
1531
1532 /* Then, apply delayed links, so that they don't affect delayed
1533 directory status-setting for ordinary directories. */
1534 apply_delayed_links ();
1535
1536 /* Finally, fix the status of directories that are ancestors
1537 of delayed links. */
1538 apply_nonancestor_delayed_set_stat ("", 1);
1539 }
1540
1541 bool
1542 rename_directory (char *src, char *dst)
1543 {
1544 if (renameat (chdir_fd, src, chdir_fd, dst) != 0)
1545 {
1546 int e = errno;
1547
1548 switch (e)
1549 {
1550 case ENOENT:
1551 if (make_directories (dst))
1552 {
1553 if (renameat (chdir_fd, src, chdir_fd, dst) == 0)
1554 return true;
1555 e = errno;
1556 }
1557 break;
1558
1559 case EXDEV:
1560 /* FIXME: Fall back to recursive copying */
1561
1562 default:
1563 break;
1564 }
1565
1566 ERROR ((0, e, _("Cannot rename %s to %s"),
1567 quote_n (0, src),
1568 quote_n (1, dst)));
1569 return false;
1570 }
1571 return true;
1572 }
This page took 0.109561 seconds and 5 git commands to generate.