]> Dogcows Code - chaz/tar/blob - src/extract.c
Fix restoring of directory timestamps from
[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 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 2, 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 <utimens.h>
25 #include <errno.h>
26 #include <xgetcwd.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 static bool directories_first; /* Directory members precede non-directory
34 ones in the archive. This is detected for
35 incremental archives only. This variable
36 helps correctly restore directory
37 timestamps */
38
39 /* Status of the permissions of a file that we are extracting. */
40 enum permstatus
41 {
42 /* This file may have existed already; its permissions are unknown. */
43 UNKNOWN_PERMSTATUS,
44
45 /* This file was created using the permissions from the archive. */
46 ARCHIVED_PERMSTATUS,
47
48 /* This is an intermediate directory; the archive did not specify
49 its permissions. */
50 INTERDIR_PERMSTATUS
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 struct delayed_set_stat *next;
65 dev_t dev;
66 ino_t ino;
67 mode_t mode;
68 uid_t uid;
69 gid_t gid;
70 struct timespec atime;
71 struct timespec mtime;
72 size_t file_name_len;
73 mode_t invert_permissions;
74 enum permstatus permstatus;
75 bool after_links;
76 char file_name[1];
77 };
78
79 static struct delayed_set_stat *delayed_set_stat_head;
80
81 /* List of links whose creation we have delayed. */
82 struct delayed_link
83 {
84 /* The next delayed link in the list. */
85 struct delayed_link *next;
86
87 /* The device, inode number and last-modified time of the placeholder. */
88 dev_t dev;
89 ino_t ino;
90 struct timespec mtime;
91
92 /* True if the link is symbolic. */
93 bool is_symlink;
94
95 /* The desired owner and group of the link, if it is a symlink. */
96 uid_t uid;
97 gid_t gid;
98
99 /* A list of sources for this link. The sources are all to be
100 hard-linked together. */
101 struct string_list *sources;
102
103 /* The desired target of the desired link. */
104 char target[1];
105 };
106
107 static struct delayed_link *delayed_link_head;
108
109 struct string_list
110 {
111 struct string_list *next;
112 char string[1];
113 };
114
115 /* Set up to extract files. */
116 void
117 extr_init (void)
118 {
119 we_are_root = geteuid () == 0;
120 same_permissions_option += we_are_root;
121 same_owner_option += we_are_root;
122
123 /* Save 'root device' to avoid purging mount points.
124 FIXME: Should the same be done after handling -C option ? */
125 if (one_file_system_option)
126 {
127 struct stat st;
128 char *dir = xgetcwd ();
129
130 if (deref_stat (true, dir, &st))
131 stat_diag (dir);
132 else
133 root_device = st.st_dev;
134 }
135
136 /* Option -p clears the kernel umask, so it does not affect proper
137 restoration of file permissions. New intermediate directories will
138 comply with umask at start of program. */
139
140 newdir_umask = umask (0);
141 if (0 < same_permissions_option)
142 current_umask = 0;
143 else
144 {
145 umask (newdir_umask); /* restore the kernel umask */
146 current_umask = newdir_umask;
147 }
148 }
149
150 /* If restoring permissions, restore the mode for FILE_NAME from
151 information given in *STAT_INFO (where *CUR_INFO gives
152 the current status if CUR_INFO is nonzero); otherwise invert the
153 INVERT_PERMISSIONS bits from the file's current permissions.
154 PERMSTATUS specifies the status of the file's permissions.
155 TYPEFLAG specifies the type of the file. */
156 static void
157 set_mode (char const *file_name,
158 struct stat const *stat_info,
159 struct stat const *cur_info,
160 mode_t invert_permissions, enum permstatus permstatus,
161 char typeflag)
162 {
163 mode_t mode;
164
165 if (0 < same_permissions_option
166 && permstatus != INTERDIR_PERMSTATUS)
167 {
168 mode = stat_info->st_mode;
169
170 /* If we created the file and it has a usual mode, then its mode
171 is normally set correctly already. But on many hosts, some
172 directories inherit the setgid bits from their parents, so we
173 we must set directories' modes explicitly. */
174 if (permstatus == ARCHIVED_PERMSTATUS
175 && ! (mode & ~ MODE_RWX)
176 && typeflag != DIRTYPE
177 && typeflag != GNUTYPE_DUMPDIR)
178 return;
179 }
180 else if (! invert_permissions)
181 return;
182 else
183 {
184 /* We must inspect a directory's current permissions, since the
185 directory may have inherited its setgid bit from its parent.
186
187 INVERT_PERMISSIONS happens to be nonzero only for directories
188 that we created, so there's no point optimizing this code for
189 other cases. */
190 struct stat st;
191 if (! cur_info)
192 {
193 if (stat (file_name, &st) != 0)
194 {
195 stat_error (file_name);
196 return;
197 }
198 cur_info = &st;
199 }
200 mode = cur_info->st_mode ^ invert_permissions;
201 }
202
203 if (chmod (file_name, mode) != 0)
204 chmod_error_details (file_name, mode);
205 }
206
207 /* Check time after successfully setting FILE_NAME's time stamp to T. */
208 static void
209 check_time (char const *file_name, struct timespec t)
210 {
211 if (t.tv_sec <= 0)
212 WARN ((0, 0, _("%s: implausibly old time stamp %s"),
213 file_name, tartime (t, true)));
214 else if (timespec_cmp (start_time, t) < 0)
215 {
216 struct timespec now;
217 gettime (&now);
218 if (timespec_cmp (now, t) < 0)
219 {
220 char buf[TIMESPEC_STRSIZE_BOUND];
221 struct timespec diff;
222 diff.tv_sec = t.tv_sec - now.tv_sec;
223 diff.tv_nsec = t.tv_nsec - now.tv_nsec;
224 if (diff.tv_nsec < 0)
225 {
226 diff.tv_nsec += BILLION;
227 diff.tv_sec--;
228 }
229 WARN ((0, 0, _("%s: time stamp %s is %s s in the future"),
230 file_name, tartime (t, true), code_timespec (diff, buf)));
231 }
232 }
233 }
234
235 /* Restore stat attributes (owner, group, mode and times) for
236 FILE_NAME, using information given in *ST.
237 If CUR_INFO is nonzero, *CUR_INFO is the
238 file's currernt status.
239 If not restoring permissions, invert the
240 INVERT_PERMISSIONS bits from the file's current permissions.
241 PERMSTATUS specifies the status of the file's permissions.
242 TYPEFLAG specifies the type of the file. */
243
244 /* FIXME: About proper restoration of symbolic link attributes, we still do
245 not have it right. Pretesters' reports tell us we need further study and
246 probably more configuration. For now, just use lchown if it exists, and
247 punt for the rest. Sigh! */
248
249 static void
250 set_stat (char const *file_name,
251 struct tar_stat_info const *st,
252 struct stat const *cur_info,
253 mode_t invert_permissions, enum permstatus permstatus,
254 char typeflag)
255 {
256 if (typeflag != SYMTYPE)
257 {
258 /* We do the utime before the chmod because some versions of utime are
259 broken and trash the modes of the file. */
260
261 if (! touch_option && permstatus != INTERDIR_PERMSTATUS)
262 {
263 /* We set the accessed time to `now', which is really the time we
264 started extracting files, unless incremental_option is used, in
265 which case .st_atime is used. */
266
267 /* FIXME: incremental_option should set ctime too, but how? */
268
269 struct timespec ts[2];
270 if (incremental_option)
271 ts[0] = st->atime;
272 else
273 ts[0] = start_time;
274 ts[1] = st->mtime;
275
276 if (utimens (file_name, ts) != 0)
277 utime_error (file_name);
278 else
279 {
280 check_time (file_name, ts[0]);
281 check_time (file_name, ts[1]);
282 }
283 }
284
285 /* Some systems allow non-root users to give files away. Once this
286 done, it is not possible anymore to change file permissions, so we
287 have to set permissions prior to possibly giving files away. */
288
289 set_mode (file_name, &st->stat, cur_info,
290 invert_permissions, permstatus, typeflag);
291 }
292
293 if (0 < same_owner_option && permstatus != INTERDIR_PERMSTATUS)
294 {
295 /* When lchown exists, it should be used to change the attributes of
296 the symbolic link itself. In this case, a mere chown would change
297 the attributes of the file the symbolic link is pointing to, and
298 should be avoided. */
299
300 if (typeflag == SYMTYPE)
301 {
302 #if HAVE_LCHOWN
303 if (lchown (file_name, st->stat.st_uid, st->stat.st_gid) < 0)
304 chown_error_details (file_name,
305 st->stat.st_uid, st->stat.st_gid);
306 #endif
307 }
308 else
309 {
310 if (chown (file_name, st->stat.st_uid, st->stat.st_gid) < 0)
311 chown_error_details (file_name,
312 st->stat.st_uid, st->stat.st_gid);
313
314 /* On a few systems, and in particular, those allowing to give files
315 away, changing the owner or group destroys the suid or sgid bits.
316 So let's attempt setting these bits once more. */
317 if (st->stat.st_mode & (S_ISUID | S_ISGID | S_ISVTX))
318 set_mode (file_name, &st->stat, 0,
319 invert_permissions, permstatus, typeflag);
320 }
321 }
322 }
323
324 /* Remember to restore stat attributes (owner, group, mode and times)
325 for the directory FILE_NAME, using information given in *ST,
326 once we stop extracting files into that directory.
327 If not restoring permissions, remember to invert the
328 INVERT_PERMISSIONS bits from the file's current permissions.
329 PERMSTATUS specifies the status of the file's permissions.
330
331 NOTICE: this works only if the archive has usual member order, i.e.
332 directory, then the files in that directory. Incremental archive have
333 somewhat reversed order: first go subdirectories, then all other
334 members. To help cope with this case the variable directories_first
335 is set by prepare_to_extract.
336
337 If an archive was explicitely created so that its member order is
338 reversed, some directory timestamps can be restored incorrectly,
339 e.g.:
340 tar --no-recursion -cf archive dir dir/subdir dir/subdir/file
341 */
342 static void
343 delay_set_stat (char const *file_name, struct tar_stat_info const *st,
344 mode_t invert_permissions, enum permstatus permstatus)
345 {
346 size_t file_name_len = strlen (file_name);
347 struct delayed_set_stat *data =
348 xmalloc (offsetof (struct delayed_set_stat, file_name)
349 + file_name_len + 1);
350 data->next = delayed_set_stat_head;
351 data->dev = st->stat.st_dev;
352 data->ino = st->stat.st_ino;
353 data->mode = st->stat.st_mode;
354 data->uid = st->stat.st_uid;
355 data->gid = st->stat.st_gid;
356 data->atime = st->atime;
357 data->mtime = st->mtime;
358 data->file_name_len = file_name_len;
359 data->invert_permissions = invert_permissions;
360 data->permstatus = permstatus;
361 data->after_links = 0;
362 strcpy (data->file_name, file_name);
363 delayed_set_stat_head = data;
364 }
365
366 /* Update the delayed_set_stat info for an intermediate directory
367 created within the file name of DIR. The intermediate directory turned
368 out to be the same as this directory, e.g. due to ".." or symbolic
369 links. *DIR_STAT_INFO is the status of the directory. */
370 static void
371 repair_delayed_set_stat (char const *dir,
372 struct stat const *dir_stat_info)
373 {
374 struct delayed_set_stat *data;
375 for (data = delayed_set_stat_head; data; data = data->next)
376 {
377 struct stat st;
378 if (stat (data->file_name, &st) != 0)
379 {
380 stat_error (data->file_name);
381 return;
382 }
383
384 if (st.st_dev == dir_stat_info->st_dev
385 && st.st_ino == dir_stat_info->st_ino)
386 {
387 data->dev = current_stat_info.stat.st_dev;
388 data->ino = current_stat_info.stat.st_ino;
389 data->mode = current_stat_info.stat.st_mode;
390 data->uid = current_stat_info.stat.st_uid;
391 data->gid = current_stat_info.stat.st_gid;
392 data->atime = current_stat_info.atime;
393 data->mtime = current_stat_info.mtime;
394 data->invert_permissions =
395 (MODE_RWX & (current_stat_info.stat.st_mode ^ st.st_mode));
396 data->permstatus = ARCHIVED_PERMSTATUS;
397 return;
398 }
399 }
400
401 ERROR ((0, 0, _("%s: Unexpected inconsistency when making directory"),
402 quotearg_colon (dir)));
403 }
404
405 /* After a file/link/directory creation has failed, see if
406 it's because some required directory was not present, and if so,
407 create all required directories. Return non-zero if a directory
408 was created. */
409 static int
410 make_directories (char *file_name)
411 {
412 char *cursor0 = file_name + FILE_SYSTEM_PREFIX_LEN (file_name);
413 char *cursor; /* points into the file name */
414 int did_something = 0; /* did we do anything yet? */
415 int mode;
416 int invert_permissions;
417 int status;
418
419
420 for (cursor = cursor0; *cursor; cursor++)
421 {
422 if (! ISSLASH (*cursor))
423 continue;
424
425 /* Avoid mkdir of empty string, if leading or double '/'. */
426
427 if (cursor == cursor0 || ISSLASH (cursor[-1]))
428 continue;
429
430 /* Avoid mkdir where last part of file name is "." or "..". */
431
432 if (cursor[-1] == '.'
433 && (cursor == cursor0 + 1 || ISSLASH (cursor[-2])
434 || (cursor[-2] == '.'
435 && (cursor == cursor0 + 2 || ISSLASH (cursor[-3])))))
436 continue;
437
438 *cursor = '\0'; /* truncate the name there */
439 mode = MODE_RWX & ~ newdir_umask;
440 invert_permissions = we_are_root ? 0 : MODE_WXUSR & ~ mode;
441 status = mkdir (file_name, mode ^ invert_permissions);
442
443 if (status == 0)
444 {
445 /* Create a struct delayed_set_stat even if
446 invert_permissions is zero, because
447 repair_delayed_set_stat may need to update the struct. */
448 delay_set_stat (file_name,
449 &current_stat_info /* ignored */,
450 invert_permissions, INTERDIR_PERMSTATUS);
451
452 print_for_mkdir (file_name, cursor - file_name, mode);
453 did_something = 1;
454
455 *cursor = '/';
456 continue;
457 }
458
459 *cursor = '/';
460
461 if (errno == EEXIST)
462 continue; /* Directory already exists. */
463 else if ((errno == ENOSYS /* Automounted dirs on Solaris return
464 this. Reported by Warren Hyde
465 <Warren.Hyde@motorola.com> */
466 || ERRNO_IS_EACCES) /* Turbo C mkdir gives a funny errno. */
467 && access (file_name, W_OK) == 0)
468 continue;
469
470 /* Some other error in the mkdir. We return to the caller. */
471 break;
472 }
473
474 return did_something; /* tell them to retry if we made one */
475 }
476
477 static bool
478 file_newer_p (const char *file_name, struct tar_stat_info *tar_stat)
479 {
480 struct stat st;
481
482 if (stat (file_name, &st))
483 {
484 stat_warn (file_name);
485 /* Be on the safe side: if the file does exist assume it is newer */
486 return errno != ENOENT;
487 }
488 if (!S_ISDIR (st.st_mode)
489 && tar_timespec_cmp (tar_stat->mtime, get_stat_mtime (&st)) <= 0)
490 {
491 return true;
492 }
493 return false;
494 }
495
496 /* Attempt repairing what went wrong with the extraction. Delete an
497 already existing file or create missing intermediate directories.
498 Return nonzero if we somewhat increased our chances at a successful
499 extraction. errno is properly restored on zero return. */
500 static int
501 maybe_recoverable (char *file_name, int *interdir_made)
502 {
503 int e = errno;
504
505 if (*interdir_made)
506 return 0;
507
508 switch (errno)
509 {
510 case EEXIST:
511 /* Remove an old file, if the options allow this. */
512
513 switch (old_files_option)
514 {
515 case KEEP_OLD_FILES:
516 return 0;
517
518 case KEEP_NEWER_FILES:
519 if (file_newer_p (file_name, &current_stat_info))
520 {
521 errno = e;
522 return 0;
523 }
524 /* FALL THROUGH */
525
526 case DEFAULT_OLD_FILES:
527 case NO_OVERWRITE_DIR_OLD_FILES:
528 case OVERWRITE_OLD_FILES:
529 {
530 int r = remove_any_file (file_name, ORDINARY_REMOVE_OPTION);
531 errno = EEXIST;
532 return r;
533 }
534
535 case UNLINK_FIRST_OLD_FILES:
536 break;
537 }
538
539 case ENOENT:
540 /* Attempt creating missing intermediate directories. */
541 if (! make_directories (file_name))
542 {
543 errno = ENOENT;
544 return 0;
545 }
546 *interdir_made = 1;
547 return 1;
548
549 default:
550 /* Just say we can't do anything about it... */
551
552 return 0;
553 }
554 }
555
556 /* Fix the statuses of all directories whose statuses need fixing, and
557 which are not ancestors of FILE_NAME. If AFTER_LINKS is
558 nonzero, do this for all such directories; otherwise, stop at the
559 first directory that is marked to be fixed up only after delayed
560 links are applied. */
561 static void
562 apply_nonancestor_delayed_set_stat (char const *file_name, bool after_links)
563 {
564 size_t file_name_len = strlen (file_name);
565 bool check_for_renamed_directories = 0;
566
567 while (delayed_set_stat_head)
568 {
569 struct delayed_set_stat *data = delayed_set_stat_head;
570 bool skip_this_one = 0;
571 struct stat st;
572 struct stat const *cur_info = 0;
573
574 check_for_renamed_directories |= data->after_links;
575
576 if (after_links < data->after_links
577 || (data->file_name_len < file_name_len
578 && file_name[data->file_name_len]
579 && (ISSLASH (file_name[data->file_name_len])
580 || ISSLASH (file_name[data->file_name_len - 1]))
581 && memcmp (file_name, data->file_name, data->file_name_len) == 0))
582 break;
583
584 if (check_for_renamed_directories)
585 {
586 cur_info = &st;
587 if (stat (data->file_name, &st) != 0)
588 {
589 stat_error (data->file_name);
590 skip_this_one = 1;
591 }
592 else if (! (st.st_dev == data->dev && st.st_ino == data->ino))
593 {
594 ERROR ((0, 0,
595 _("%s: Directory renamed before its status could be extracted"),
596 quotearg_colon (data->file_name)));
597 skip_this_one = 1;
598 }
599 }
600
601 if (! skip_this_one)
602 {
603 struct tar_stat_info st;
604 st.stat.st_mode = data->mode;
605 st.stat.st_uid = data->uid;
606 st.stat.st_gid = data->gid;
607 st.atime = data->atime;
608 st.mtime = data->mtime;
609 set_stat (data->file_name, &st, cur_info,
610 data->invert_permissions, data->permstatus, DIRTYPE);
611 }
612
613 delayed_set_stat_head = data->next;
614 free (data);
615 }
616 }
617
618 \f
619
620 /* Extractor functions for various member types */
621
622 static int
623 extract_dir (char *file_name, int typeflag)
624 {
625 int status;
626 mode_t mode;
627 int interdir_made = 0;
628
629 if (incremental_option)
630 /* Read the entry and delete files that aren't listed in the archive. */
631 purge_directory (file_name);
632 else if (typeflag == GNUTYPE_DUMPDIR)
633 skip_member ();
634
635 mode = (current_stat_info.stat.st_mode |
636 (we_are_root ? 0 : MODE_WXUSR)) & MODE_RWX;
637
638 while ((status = mkdir (file_name, mode)))
639 {
640 if (errno == EEXIST
641 && (interdir_made
642 || old_files_option == DEFAULT_OLD_FILES
643 || old_files_option == OVERWRITE_OLD_FILES))
644 {
645 struct stat st;
646 if (stat (file_name, &st) == 0)
647 {
648 if (interdir_made)
649 {
650 repair_delayed_set_stat (file_name, &st);
651 return 0;
652 }
653 if (S_ISDIR (st.st_mode))
654 {
655 mode = st.st_mode & ~ current_umask;
656 break;
657 }
658 }
659 errno = EEXIST;
660 }
661
662 if (maybe_recoverable (file_name, &interdir_made))
663 continue;
664
665 if (errno != EEXIST)
666 {
667 mkdir_error (file_name);
668 return 1;
669 }
670 break;
671 }
672
673 if (status == 0
674 || old_files_option == DEFAULT_OLD_FILES
675 || old_files_option == OVERWRITE_OLD_FILES)
676 delay_set_stat (file_name, &current_stat_info,
677 MODE_RWX & (mode ^ current_stat_info.stat.st_mode),
678 (status == 0
679 ? ARCHIVED_PERMSTATUS
680 : UNKNOWN_PERMSTATUS));
681
682 return status;
683 }
684
685
686 static int
687 open_output_file (char *file_name, int typeflag)
688 {
689 int fd;
690 int openflag = (O_WRONLY | O_BINARY | O_CREAT
691 | (old_files_option == OVERWRITE_OLD_FILES
692 ? O_TRUNC
693 : O_EXCL));
694 mode_t mode = current_stat_info.stat.st_mode & MODE_RWX & ~ current_umask;
695
696 #if O_CTG
697 /* Contiguous files (on the Masscomp) have to specify the size in
698 the open call that creates them. */
699
700 if (typeflag == CONTTYPE)
701 fd = open (file_name, openflag | O_CTG, mode, current_stat_info.stat.st_size);
702 else
703 fd = open (file_name, openflag, mode);
704
705 #else /* not O_CTG */
706 if (typeflag == CONTTYPE)
707 {
708 static int conttype_diagnosed;
709
710 if (!conttype_diagnosed)
711 {
712 conttype_diagnosed = 1;
713 WARN ((0, 0, _("Extracting contiguous files as regular files")));
714 }
715 }
716 fd = open (file_name, openflag, mode);
717
718 #endif /* not O_CTG */
719
720 return fd;
721 }
722
723 static int
724 extract_file (char *file_name, int typeflag)
725 {
726 int fd;
727 off_t size;
728 union block *data_block;
729 int status;
730 size_t count;
731 size_t written;
732 int interdir_made = 0;
733
734 /* FIXME: deal with protection issues. */
735
736 if (to_stdout_option)
737 fd = STDOUT_FILENO;
738 else if (to_command_option)
739 {
740 fd = sys_exec_command (file_name, 'f', &current_stat_info);
741 if (fd < 0)
742 {
743 skip_member ();
744 return 0;
745 }
746 }
747 else
748 {
749 do
750 fd = open_output_file (file_name, typeflag);
751 while (fd < 0 && maybe_recoverable (file_name, &interdir_made));
752
753 if (fd < 0)
754 {
755 open_error (file_name);
756 return 1;
757 }
758 }
759
760 mv_begin (&current_stat_info);
761 if (current_stat_info.is_sparse)
762 sparse_extract_file (fd, &current_stat_info, &size);
763 else
764 for (size = current_stat_info.stat.st_size; size > 0; )
765 {
766 mv_size_left (size);
767
768 /* Locate data, determine max length writeable, write it,
769 block that we have used the data, then check if the write
770 worked. */
771
772 data_block = find_next_block ();
773 if (! data_block)
774 {
775 ERROR ((0, 0, _("Unexpected EOF in archive")));
776 break; /* FIXME: What happens, then? */
777 }
778
779 written = available_space_after (data_block);
780
781 if (written > size)
782 written = size;
783 errno = 0;
784 count = full_write (fd, data_block->buffer, written);
785 size -= written;
786
787 set_next_block_after ((union block *)
788 (data_block->buffer + written - 1));
789 if (count != written)
790 {
791 if (!to_command_option)
792 write_error_details (file_name, count, written);
793 /* FIXME: shouldn't we restore from backup? */
794 break;
795 }
796 }
797
798 skip_file (size);
799
800 mv_end ();
801
802 /* If writing to stdout, don't try to do anything to the filename;
803 it doesn't exist, or we don't want to touch it anyway. */
804
805 if (to_stdout_option)
806 return 0;
807
808 status = close (fd);
809 if (status < 0)
810 close_error (file_name);
811
812 if (to_command_option)
813 sys_wait_command ();
814 else
815 set_stat (file_name, &current_stat_info, NULL, 0,
816 (old_files_option == OVERWRITE_OLD_FILES ?
817 UNKNOWN_PERMSTATUS : ARCHIVED_PERMSTATUS),
818 typeflag);
819
820 return status;
821 }
822
823 /* Create a placeholder file with name FILE_NAME, which will be
824 replaced after other extraction is done by a symbolic link if
825 IS_SYMLINK is true, and by a hard link otherwise. Set
826 *INTERDIR_MADE if an intermediate directory is made in the
827 process. */
828
829 static int
830 create_placeholder_file (char *file_name, bool is_symlink, int *interdir_made)
831 {
832 int fd;
833 struct stat st;
834
835 while ((fd = open (file_name, O_WRONLY | O_CREAT | O_EXCL, 0)) < 0)
836 if (! maybe_recoverable (file_name, interdir_made))
837 break;
838
839 if (fd < 0)
840 open_error (file_name);
841 else if (fstat (fd, &st) != 0)
842 {
843 stat_error (file_name);
844 close (fd);
845 }
846 else if (close (fd) != 0)
847 close_error (file_name);
848 else
849 {
850 struct delayed_set_stat *h;
851 struct delayed_link *p =
852 xmalloc (offsetof (struct delayed_link, target)
853 + strlen (current_stat_info.link_name)
854 + 1);
855 p->next = delayed_link_head;
856 delayed_link_head = p;
857 p->dev = st.st_dev;
858 p->ino = st.st_ino;
859 p->mtime = get_stat_mtime (&st);
860 p->is_symlink = is_symlink;
861 if (is_symlink)
862 {
863 p->uid = current_stat_info.stat.st_uid;
864 p->gid = current_stat_info.stat.st_gid;
865 }
866 p->sources = xmalloc (offsetof (struct string_list, string)
867 + strlen (file_name) + 1);
868 p->sources->next = 0;
869 strcpy (p->sources->string, file_name);
870 strcpy (p->target, current_stat_info.link_name);
871
872 h = delayed_set_stat_head;
873 if (h && ! h->after_links
874 && strncmp (file_name, h->file_name, h->file_name_len) == 0
875 && ISSLASH (file_name[h->file_name_len])
876 && (base_name (file_name) == file_name + h->file_name_len + 1))
877 {
878 do
879 {
880 h->after_links = 1;
881
882 if (stat (h->file_name, &st) != 0)
883 stat_error (h->file_name);
884 else
885 {
886 h->dev = st.st_dev;
887 h->ino = st.st_ino;
888 }
889 }
890 while ((h = h->next) && ! h->after_links);
891 }
892
893 return 0;
894 }
895
896 return -1;
897 }
898
899 static int
900 extract_link (char *file_name, int typeflag)
901 {
902 char const *link_name = safer_name_suffix (current_stat_info.link_name,
903 true, absolute_names_option);
904 int interdir_made = 0;
905
906 if (! absolute_names_option && contains_dot_dot (link_name))
907 return create_placeholder_file (file_name, false, &interdir_made);
908
909 do
910 {
911 struct stat st1, st2;
912 int e;
913 int status = link (link_name, file_name);
914 e = errno;
915
916 if (status == 0)
917 {
918 struct delayed_link *ds = delayed_link_head;
919 if (ds && lstat (link_name, &st1) == 0)
920 for (; ds; ds = ds->next)
921 if (ds->dev == st1.st_dev
922 && ds->ino == st1.st_ino
923 && timespec_cmp (ds->mtime, get_stat_mtime (&st1)) == 0)
924 {
925 struct string_list *p = xmalloc (offsetof (struct string_list, string)
926 + strlen (file_name) + 1);
927 strcpy (p->string, file_name);
928 p->next = ds->sources;
929 ds->sources = p;
930 break;
931 }
932 return 0;
933 }
934 else if ((e == EEXIST && strcmp (link_name, file_name) == 0)
935 || (lstat (link_name, &st1) == 0
936 && lstat (file_name, &st2) == 0
937 && st1.st_dev == st2.st_dev
938 && st1.st_ino == st2.st_ino))
939 return 0;
940
941 errno = e;
942 }
943 while (maybe_recoverable (file_name, &interdir_made));
944
945 if (!(incremental_option && errno == EEXIST))
946 {
947 link_error (link_name, file_name);
948 return 1;
949 }
950 return 0;
951 }
952
953 static int
954 extract_symlink (char *file_name, int typeflag)
955 {
956 #ifdef HAVE_SYMLINK
957 int status;
958 int interdir_made = 0;
959
960 if (! absolute_names_option
961 && (IS_ABSOLUTE_FILE_NAME (current_stat_info.link_name)
962 || contains_dot_dot (current_stat_info.link_name)))
963 return create_placeholder_file (file_name, true, &interdir_made);
964
965 while ((status = symlink (current_stat_info.link_name, file_name)))
966 if (!maybe_recoverable (file_name, &interdir_made))
967 break;
968
969 if (status == 0)
970 set_stat (file_name, &current_stat_info, NULL, 0, 0, SYMTYPE);
971 else
972 symlink_error (current_stat_info.link_name, file_name);
973 return status;
974
975 #else
976 static int warned_once;
977
978 if (!warned_once)
979 {
980 warned_once = 1;
981 WARN ((0, 0, _("Attempting extraction of symbolic links as hard links")));
982 }
983 return extract_link (file_name, typeflag);
984 #endif
985 }
986
987 #if S_IFCHR || S_IFBLK
988 static int
989 extract_node (char *file_name, int typeflag)
990 {
991 int status;
992 int interdir_made = 0;
993
994 do
995 status = mknod (file_name, current_stat_info.stat.st_mode,
996 current_stat_info.stat.st_rdev);
997 while (status && maybe_recoverable (file_name, &interdir_made));
998
999 if (status != 0)
1000 mknod_error (file_name);
1001 else
1002 set_stat (file_name, &current_stat_info, NULL, 0,
1003 ARCHIVED_PERMSTATUS, typeflag);
1004 return status;
1005 }
1006 #endif
1007
1008 #if HAVE_MKFIFO || defined mkfifo
1009 static int
1010 extract_fifo (char *file_name, int typeflag)
1011 {
1012 int status;
1013 int interdir_made = 0;
1014
1015 while ((status = mkfifo (file_name, current_stat_info.stat.st_mode)))
1016 if (!maybe_recoverable (file_name, &interdir_made))
1017 break;
1018
1019 if (status == 0)
1020 set_stat (file_name, &current_stat_info, NULL, 0,
1021 ARCHIVED_PERMSTATUS, typeflag);
1022 else
1023 mkfifo_error (file_name);
1024 return status;
1025 }
1026 #endif
1027
1028 static int
1029 extract_mangle_wrapper (char *file_name, int typeflag)
1030 {
1031 extract_mangle ();
1032 return 0;
1033 }
1034
1035
1036 static int
1037 extract_failure (char *file_name, int typeflag)
1038 {
1039 return 1;
1040 }
1041
1042 typedef int (*tar_extractor_t) (char *file_name, int typeflag);
1043
1044 \f
1045
1046 /* Prepare to extract a file. Find extractor function.
1047 Return zero if extraction should not proceed. */
1048
1049 static int
1050 prepare_to_extract (char const *file_name, int typeflag, tar_extractor_t *fun)
1051 {
1052 int rc = 1;
1053
1054 if (EXTRACT_OVER_PIPE)
1055 rc = 0;
1056
1057 /* Select the extractor */
1058 switch (typeflag)
1059 {
1060 case GNUTYPE_SPARSE:
1061 *fun = extract_file;
1062 rc = 1;
1063 break;
1064
1065 case AREGTYPE:
1066 case REGTYPE:
1067 case CONTTYPE:
1068 /* Appears to be a file. But BSD tar uses the convention that a slash
1069 suffix means a directory. */
1070 if (current_stat_info.had_trailing_slash)
1071 *fun = extract_dir;
1072 else
1073 {
1074 *fun = extract_file;
1075 rc = 1;
1076 }
1077 break;
1078
1079 case SYMTYPE:
1080 *fun = extract_symlink;
1081 break;
1082
1083 case LNKTYPE:
1084 *fun = extract_link;
1085 break;
1086
1087 #if S_IFCHR
1088 case CHRTYPE:
1089 current_stat_info.stat.st_mode |= S_IFCHR;
1090 *fun = extract_node;
1091 break;
1092 #endif
1093
1094 #if S_IFBLK
1095 case BLKTYPE:
1096 current_stat_info.stat.st_mode |= S_IFBLK;
1097 *fun = extract_node;
1098 break;
1099 #endif
1100
1101 #if HAVE_MKFIFO || defined mkfifo
1102 case FIFOTYPE:
1103 *fun = extract_fifo;
1104 break;
1105 #endif
1106
1107 case DIRTYPE:
1108 case GNUTYPE_DUMPDIR:
1109 *fun = extract_dir;
1110 if (current_stat_info.dumpdir)
1111 directories_first = true;
1112 break;
1113
1114 case GNUTYPE_VOLHDR:
1115 if (verbose_option)
1116 fprintf (stdlis, _("Reading %s\n"), quote (current_stat_info.file_name));
1117 *fun = NULL;
1118 break;
1119
1120 case GNUTYPE_NAMES:
1121 *fun = extract_mangle_wrapper;
1122 break;
1123
1124 case GNUTYPE_MULTIVOL:
1125 ERROR ((0, 0,
1126 _("%s: Cannot extract -- file is continued from another volume"),
1127 quotearg_colon (current_stat_info.file_name)));
1128 *fun = extract_failure;
1129 break;
1130
1131 case GNUTYPE_LONGNAME:
1132 case GNUTYPE_LONGLINK:
1133 ERROR ((0, 0, _("Unexpected long name header")));
1134 *fun = extract_failure;
1135 break;
1136
1137 default:
1138 WARN ((0, 0,
1139 _("%s: Unknown file type `%c', extracted as normal file"),
1140 quotearg_colon (file_name), typeflag));
1141 *fun = extract_file;
1142 }
1143
1144 /* Determine whether the extraction should proceed */
1145 if (rc == 0)
1146 return 0;
1147
1148 switch (old_files_option)
1149 {
1150 case UNLINK_FIRST_OLD_FILES:
1151 if (!remove_any_file (file_name,
1152 recursive_unlink_option ? RECURSIVE_REMOVE_OPTION
1153 : ORDINARY_REMOVE_OPTION)
1154 && errno && errno != ENOENT)
1155 {
1156 unlink_error (file_name);
1157 return 0;
1158 }
1159 break;
1160
1161 case KEEP_NEWER_FILES:
1162 if (file_newer_p (file_name, &current_stat_info))
1163 {
1164 WARN ((0, 0, _("Current %s is newer or same age"),
1165 quote (file_name)));
1166 return 0;
1167 }
1168 break;
1169
1170 default:
1171 break;
1172 }
1173
1174 return 1;
1175 }
1176
1177 /* Extract a file from the archive. */
1178 void
1179 extract_archive (void)
1180 {
1181 char typeflag;
1182 char *file_name;
1183 tar_extractor_t fun;
1184
1185 set_next_block_after (current_header);
1186 decode_header (current_header, &current_stat_info, &current_format, 1);
1187
1188 if (interactive_option && !confirm ("extract", current_stat_info.file_name))
1189 {
1190 skip_member ();
1191 return;
1192 }
1193
1194 /* Print the block from current_header and current_stat. */
1195
1196 if (verbose_option)
1197 print_header (&current_stat_info, -1);
1198
1199 file_name = safer_name_suffix (current_stat_info.file_name,
1200 false, absolute_names_option);
1201 if (strip_name_components)
1202 {
1203 size_t prefix_len = stripped_prefix_len (file_name,
1204 strip_name_components);
1205 if (prefix_len == (size_t) -1)
1206 {
1207 skip_member ();
1208 return;
1209 }
1210 file_name += prefix_len;
1211 }
1212
1213 /* Restore stats for all non-ancestor directories, unless
1214 it is an incremental archive.
1215 (see NOTICE in the comment to delay_set_stat above) */
1216 if (!directories_first)
1217 apply_nonancestor_delayed_set_stat (file_name, 0);
1218
1219 /* Take a safety backup of a previously existing file. */
1220
1221 if (backup_option)
1222 if (!maybe_backup_file (file_name, 0))
1223 {
1224 int e = errno;
1225 ERROR ((0, e, _("%s: Was unable to backup this file"),
1226 quotearg_colon (file_name)));
1227 skip_member ();
1228 return;
1229 }
1230
1231 /* Extract the archive entry according to its type. */
1232 /* KLUDGE */
1233 typeflag = sparse_member_p (&current_stat_info) ?
1234 GNUTYPE_SPARSE : current_header->header.typeflag;
1235
1236 if (prepare_to_extract (file_name, typeflag, &fun))
1237 {
1238 if (fun && (*fun) (file_name, typeflag) && backup_option)
1239 undo_last_backup ();
1240 }
1241 else
1242 skip_member ();
1243
1244 }
1245
1246 /* Extract the symbolic links whose final extraction were delayed. */
1247 static void
1248 apply_delayed_links (void)
1249 {
1250 struct delayed_link *ds;
1251
1252 for (ds = delayed_link_head; ds; )
1253 {
1254 struct string_list *sources = ds->sources;
1255 char const *valid_source = 0;
1256
1257 for (sources = ds->sources; sources; sources = sources->next)
1258 {
1259 char const *source = sources->string;
1260 struct stat st;
1261
1262 /* Make sure the placeholder file is still there. If not,
1263 don't create a link, as the placeholder was probably
1264 removed by a later extraction. */
1265 if (lstat (source, &st) == 0
1266 && st.st_dev == ds->dev
1267 && st.st_ino == ds->ino
1268 && timespec_cmp (get_stat_mtime (&st), ds->mtime) == 0)
1269 {
1270 /* Unlink the placeholder, then create a hard link if possible,
1271 a symbolic link otherwise. */
1272 if (unlink (source) != 0)
1273 unlink_error (source);
1274 else if (valid_source && link (valid_source, source) == 0)
1275 ;
1276 else if (!ds->is_symlink)
1277 {
1278 if (link (ds->target, source) != 0)
1279 link_error (ds->target, source);
1280 }
1281 else if (symlink (ds->target, source) != 0)
1282 symlink_error (ds->target, source);
1283 else
1284 {
1285 struct tar_stat_info st1;
1286 st1.stat.st_uid = ds->uid;
1287 st1.stat.st_gid = ds->gid;
1288 set_stat (source, &st1, NULL, 0, 0, SYMTYPE);
1289 valid_source = source;
1290 }
1291 }
1292 }
1293
1294 for (sources = ds->sources; sources; )
1295 {
1296 struct string_list *next = sources->next;
1297 free (sources);
1298 sources = next;
1299 }
1300
1301 {
1302 struct delayed_link *next = ds->next;
1303 free (ds);
1304 ds = next;
1305 }
1306 }
1307
1308 delayed_link_head = 0;
1309 }
1310
1311 /* Finish the extraction of an archive. */
1312 void
1313 extract_finish (void)
1314 {
1315 /* First, fix the status of ordinary directories that need fixing. */
1316 apply_nonancestor_delayed_set_stat ("", 0);
1317
1318 /* Then, apply delayed links, so that they don't affect delayed
1319 directory status-setting for ordinary directories. */
1320 apply_delayed_links ();
1321
1322 /* Finally, fix the status of directories that are ancestors
1323 of delayed links. */
1324 apply_nonancestor_delayed_set_stat ("", 1);
1325 }
1326
1327 void
1328 fatal_exit (void)
1329 {
1330 extract_finish ();
1331 error (TAREXIT_FAILURE, 0, _("Error is not recoverable: exiting now"));
1332 abort ();
1333 }
1334
1335 void
1336 xalloc_die (void)
1337 {
1338 error (0, 0, "%s", _("memory exhausted"));
1339 fatal_exit ();
1340 }
This page took 0.097736 seconds and 5 git commands to generate.