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