]> Dogcows Code - chaz/tar/blob - src/extract.c
58a55886ff92e1581203214b0084ec687a121ac6
[chaz/tar] / src / extract.c
1 /* Extract files from a tar archive.
2 Copyright 1988, 92,93,94,96,97,98, 1999 Free Software Foundation, Inc.
3 Written by John Gilmore, on 1985-11-19.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any later
8 version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19 #include "system.h"
20 #include <quotearg.h>
21
22 #if HAVE_UTIME_H
23 # include <utime.h>
24 #else
25 struct utimbuf
26 {
27 long actime;
28 long modtime;
29 };
30 #endif
31
32 #include "common.h"
33
34 static int we_are_root; /* true if our effective uid == 0 */
35 static mode_t newdir_umask; /* umask when creating new directories */
36 static mode_t current_umask; /* current umask (which is set to 0 if -p) */
37
38 /* Status of the permissions of a file that we are extracting. */
39 enum permstatus
40 {
41 /* This file may have existed already; its permissions are unknown. */
42 UNKNOWN_PERMSTATUS,
43
44 /* This file was created using the permissions from the archive. */
45 ARCHIVED_PERMSTATUS,
46
47 /* This is an intermediate directory; the archive did not specify
48 its permissions. */
49 INTERDIR_PERMSTATUS
50 };
51
52 /* List of directories whose statuses we need to extract after we've
53 finished extracting their subsidiary files. The head of the list
54 has the longest name; each non-head element in the list is an
55 ancestor (in the directory hierarchy) of the preceding element. */
56 struct delayed_set_stat
57 {
58 struct delayed_set_stat *next;
59 struct stat stat_info;
60 size_t file_name_len;
61 mode_t invert_permissions;
62 enum permstatus permstatus;
63 char file_name[1];
64 };
65
66 static struct delayed_set_stat *delayed_set_stat_head;
67
68 /*--------------------------.
69 | Set up to extract files. |
70 `--------------------------*/
71
72 void
73 extr_init (void)
74 {
75 we_are_root = geteuid () == 0;
76 same_permissions_option += we_are_root;
77 same_owner_option += we_are_root;
78 xalloc_fail_func = apply_delayed_set_stat;
79
80 /* Option -p clears the kernel umask, so it does not affect proper
81 restoration of file permissions. New intermediate directories will
82 comply with umask at start of program. */
83
84 newdir_umask = umask (0);
85 if (0 < same_permissions_option)
86 current_umask = 0;
87 else
88 {
89 umask (newdir_umask); /* restore the kernel umask */
90 current_umask = newdir_umask;
91 }
92 }
93
94 /* If restoring permissions, restore the mode for FILE_NAME from
95 information given in *STAT_INFO; otherwise invert the
96 INVERT_PERMISSIONS bits from the file's current permissions.
97 PERMSTATUS specifies the status of the file's permissions.
98 TYPEFLAG specifies the type of the file. */
99 static void
100 set_mode (char *file_name, struct stat *stat_info,
101 mode_t invert_permissions, enum permstatus permstatus,
102 char typeflag)
103 {
104 mode_t mode;
105
106 if (0 < same_permissions_option
107 && permstatus != INTERDIR_PERMSTATUS)
108 {
109 mode = stat_info->st_mode;
110
111 /* If we created the file and it has a usual mode, then its mode
112 is normally set correctly already. But on many hosts, some
113 directories inherit the setgid bits from their parents, so we
114 we must set directories' modes explicitly. */
115 if (permstatus == ARCHIVED_PERMSTATUS
116 && ! (mode & ~ MODE_RWX)
117 && typeflag != DIRTYPE
118 && typeflag != GNUTYPE_DUMPDIR)
119 return;
120 }
121 else if (! invert_permissions)
122 return;
123 else
124 {
125 /* We must inspect a directory's current permissions, since the
126 directory may have inherited its setgid bit from its parent.
127
128 INVERT_PERMISSIONS happens to be nonzero only for directories
129 that we created, so there's no point optimizing this code for
130 other cases. */
131 struct stat st;
132 if (stat (file_name, &st) != 0)
133 {
134 stat_error (file_name);
135 return;
136 }
137 mode = st.st_mode ^ invert_permissions;
138 }
139
140 if (chmod (file_name, mode) != 0)
141 chmod_error_details (file_name, mode);
142 }
143
144 /* Restore stat attributes (owner, group, mode and times) for
145 FILE_NAME, using information given in *STAT_INFO.
146 If not restoring permissions, invert the
147 INVERT_PERMISSIONS bits from the file's current permissions.
148 PERMSTATUS specifies the status of the file's permissions.
149 TYPEFLAG specifies the type of the file. */
150
151 /* FIXME: About proper restoration of symbolic link attributes, we still do
152 not have it right. Pretesters' reports tell us we need further study and
153 probably more configuration. For now, just use lchown if it exists, and
154 punt for the rest. Sigh! */
155
156 static void
157 set_stat (char *file_name, struct stat *stat_info,
158 mode_t invert_permissions, enum permstatus permstatus,
159 char typeflag)
160 {
161 struct utimbuf utimbuf;
162
163 if (typeflag != SYMTYPE)
164 {
165 /* We do the utime before the chmod because some versions of utime are
166 broken and trash the modes of the file. */
167
168 if (! touch_option && permstatus != INTERDIR_PERMSTATUS)
169 {
170 /* We set the accessed time to `now', which is really the time we
171 started extracting files, unless incremental_option is used, in
172 which case .st_atime is used. */
173
174 /* FIXME: incremental_option should set ctime too, but how? */
175
176 if (incremental_option)
177 utimbuf.actime = stat_info->st_atime;
178 else
179 utimbuf.actime = start_time;
180
181 utimbuf.modtime = stat_info->st_mtime;
182
183 if (utime (file_name, &utimbuf) < 0)
184 utime_error (file_name);
185 }
186
187 /* Some systems allow non-root users to give files away. Once this
188 done, it is not possible anymore to change file permissions, so we
189 have to set permissions prior to possibly giving files away. */
190
191 set_mode (file_name, stat_info,
192 invert_permissions, permstatus, typeflag);
193 }
194
195 if (0 < same_owner_option && permstatus != INTERDIR_PERMSTATUS)
196 {
197 /* When lchown exists, it should be used to change the attributes of
198 the symbolic link itself. In this case, a mere chown would change
199 the attributes of the file the symbolic link is pointing to, and
200 should be avoided. */
201
202 if (typeflag == SYMTYPE)
203 {
204 #if HAVE_LCHOWN
205 if (lchown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
206 chown_error_details (file_name,
207 stat_info->st_uid, stat_info->st_gid);
208 #endif
209 }
210 else
211 {
212 if (chown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
213 chown_error_details (file_name,
214 stat_info->st_uid, stat_info->st_gid);
215
216 /* On a few systems, and in particular, those allowing to give files
217 away, changing the owner or group destroys the suid or sgid bits.
218 So let's attempt setting these bits once more. */
219 if (stat_info->st_mode & (S_ISUID | S_ISGID | S_ISVTX))
220 set_mode (file_name, stat_info,
221 invert_permissions, permstatus, typeflag);
222 }
223 }
224 }
225
226 /* Remember to restore stat attributes (owner, group, mode and times)
227 for the directory FILE_NAME, using information given in *STAT_INFO,
228 once we stop extracting files into that directory.
229 If not restoring permissions, remember to invert the
230 INVERT_PERMISSIONS bits from the file's current permissions.
231 PERMSTATUS specifies the status of the file's permissions. */
232 static void
233 delay_set_stat (char const *file_name, struct stat const *stat_info,
234 mode_t invert_permissions, enum permstatus permstatus)
235 {
236 size_t file_name_len = strlen (file_name);
237 struct delayed_set_stat *data = xmalloc (sizeof *data + file_name_len);
238 data->file_name_len = file_name_len;
239 strcpy (data->file_name, file_name);
240 data->invert_permissions = invert_permissions;
241 data->permstatus = permstatus;
242 data->stat_info = *stat_info;
243 data->next = delayed_set_stat_head;
244 delayed_set_stat_head = data;
245 }
246
247 /* Update the delayed_set_stat info for an intermediate directory
248 created on the path to DIR_NAME. The intermediate directory
249 turned out to be the same as this directory, due to ".." or
250 symbolic links. *DIR_STAT_INFO is the status of the directory. */
251 static void
252 repair_delayed_set_stat (char const *dir_name,
253 struct stat const *dir_stat_info)
254 {
255 struct delayed_set_stat *data;
256 for (data = delayed_set_stat_head; data; data = data->next)
257 {
258 struct stat st;
259 if (stat (data->file_name, &st) != 0)
260 {
261 stat_error (data->file_name);
262 return;
263 }
264
265 if (st.st_dev == dir_stat_info->st_dev
266 && st.st_ino == dir_stat_info->st_ino)
267 {
268 data->stat_info = current_stat;
269 data->invert_permissions = (MODE_RWX
270 & (current_stat.st_mode ^ st.st_mode));
271 data->permstatus = ARCHIVED_PERMSTATUS;
272 return;
273 }
274 }
275
276 ERROR ((0, 0, _("%s: Unexpected inconsistency when making directory"),
277 quotearg_colon (dir_name)));
278 }
279
280 /*-----------------------------------------------------------------------.
281 | After a file/link/symlink/directory creation has failed, see if it's |
282 | because some required directory was not present, and if so, create all |
283 | required directories. Return non-zero if a directory was created. |
284 `-----------------------------------------------------------------------*/
285
286 static int
287 make_directories (char *file_name)
288 {
289 char *cursor; /* points into path */
290 int did_something = 0; /* did we do anything yet? */
291 int saved_errno = errno; /* remember caller's errno */
292 int mode;
293 int invert_permissions;
294 int status;
295
296 for (cursor = strchr (file_name, '/');
297 cursor;
298 cursor = strchr (cursor + 1, '/'))
299 {
300 /* Avoid mkdir of empty string, if leading or double '/'. */
301
302 if (cursor == file_name || cursor[-1] == '/')
303 continue;
304
305 /* Avoid mkdir where last part of path is "." or "..". */
306
307 if (cursor[-1] == '.'
308 && (cursor == file_name + 1 || cursor[-2] == '/'
309 || (cursor[-2] == '.'
310 && (cursor == file_name + 2 || cursor[-3] == '/'))))
311 continue;
312
313 *cursor = '\0'; /* truncate the path there */
314 mode = MODE_RWX & ~ newdir_umask;
315 invert_permissions = we_are_root ? 0 : MODE_WXUSR & ~ mode;
316 status = mkdir (file_name, mode ^ invert_permissions);
317
318 if (status == 0)
319 {
320 /* Create a struct delayed_set_stat even if
321 invert_permissions is zero, because
322 repair_delayed_set_stat may need to update the struct. */
323 delay_set_stat (file_name,
324 &current_stat /* ignored */,
325 invert_permissions, INTERDIR_PERMSTATUS);
326
327 print_for_mkdir (file_name, cursor - file_name, mode);
328 did_something = 1;
329
330 *cursor = '/';
331 continue;
332 }
333
334 *cursor = '/';
335
336 if (errno == EEXIST
337 #if MSDOS
338 /* Turbo C mkdir gives a funny errno. */
339 || errno == EACCES
340 #endif
341 )
342 /* Directory already exists. */
343 continue;
344
345 /* Some other error in the mkdir. We return to the caller. */
346 break;
347 }
348
349 errno = saved_errno;
350 return did_something; /* tell them to retry if we made one */
351 }
352
353 /* Prepare to extract a file.
354 Return zero if extraction should not proceed. */
355
356 static int
357 prepare_to_extract (char const *file_name)
358 {
359 if (to_stdout_option)
360 return 0;
361
362 if (old_files_option == UNLINK_FIRST_OLD_FILES
363 && !remove_any_file (file_name, recursive_unlink_option)
364 && errno && errno != ENOENT)
365 {
366 unlink_error (file_name);
367 return 0;
368 }
369
370 return 1;
371 }
372
373 /*--------------------------------------------------------------------.
374 | Attempt repairing what went wrong with the extraction. Delete an |
375 | already existing file or create missing intermediate directories. |
376 | Return nonzero if we somewhat increased our chances at a successful |
377 | extraction. errno is properly restored on zero return. |
378 `--------------------------------------------------------------------*/
379
380 static int
381 maybe_recoverable (char *file_name, int *interdir_made)
382 {
383 if (*interdir_made)
384 return 0;
385
386 switch (errno)
387 {
388 case EEXIST:
389 /* Remove an old file, if the options allow this. */
390
391 switch (old_files_option)
392 {
393 default:
394 return 0;
395
396 case DEFAULT_OLD_FILES:
397 case OVERWRITE_OLD_FILES:
398 {
399 int r = remove_any_file (file_name, 0);
400 errno = EEXIST;
401 return r;
402 }
403 }
404
405 case ENOENT:
406 /* Attempt creating missing intermediate directories. */
407 if (! make_directories (file_name))
408 return 0;
409 *interdir_made = 1;
410 return 1;
411
412 default:
413 /* Just say we can't do anything about it... */
414
415 return 0;
416 }
417 }
418
419 /*---.
420 | ? |
421 `---*/
422
423 static void
424 extract_sparse_file (int fd, off_t *sizeleft, off_t totalsize, char *name)
425 {
426 int sparse_ind = 0;
427 size_t written;
428 ssize_t count;
429
430 /* assuming sizeleft is initially totalsize */
431
432 while (*sizeleft > 0)
433 {
434 union block *data_block = find_next_block ();
435 if (! data_block)
436 {
437 ERROR ((0, 0, _("Unexpected EOF in archive")));
438 return;
439 }
440 if (lseek (fd, sparsearray[sparse_ind].offset, SEEK_SET) < 0)
441 {
442 seek_error_details (name, sparsearray[sparse_ind].offset);
443 return;
444 }
445 written = sparsearray[sparse_ind++].numbytes;
446 while (written > BLOCKSIZE)
447 {
448 count = full_write (fd, data_block->buffer, BLOCKSIZE);
449 if (count < 0)
450 write_error (name);
451 written -= count;
452 *sizeleft -= count;
453 set_next_block_after (data_block);
454 data_block = find_next_block ();
455 if (! data_block)
456 {
457 ERROR ((0, 0, _("Unexpected EOF in archive")));
458 return;
459 }
460 }
461
462 count = full_write (fd, data_block->buffer, written);
463
464 if (count < 0)
465 write_error (name);
466 else if (count != written)
467 {
468 write_error_details (name, count, written);
469 skip_file (*sizeleft);
470 }
471
472 written -= count;
473 *sizeleft -= count;
474 set_next_block_after (data_block);
475 }
476
477 free (sparsearray);
478 }
479
480 /*----------------------------------.
481 | Extract a file from the archive. |
482 `----------------------------------*/
483
484 void
485 extract_archive (void)
486 {
487 union block *data_block;
488 int fd;
489 int status;
490 ssize_t sstatus;
491 size_t name_length;
492 size_t written;
493 int openflag;
494 mode_t mode;
495 off_t size;
496 int skipcrud;
497 int counter;
498 int interdir_made = 0;
499 char typeflag;
500 #if 0
501 int sparse_ind = 0;
502 #endif
503 union block *exhdr;
504
505 #define CURRENT_FILE_NAME (skipcrud + current_file_name)
506
507 set_next_block_after (current_header);
508 decode_header (current_header, &current_stat, &current_format, 1);
509
510 if (interactive_option && !confirm ("extract", current_file_name))
511 {
512 if (current_header->oldgnu_header.isextended)
513 skip_extended_headers ();
514 skip_file (current_stat.st_size);
515 return;
516 }
517
518 /* Print the block from `current_header' and `current_stat'. */
519
520 if (verbose_option)
521 print_header ();
522
523 /* Check for fully specified file names and other atrocities. */
524
525 skipcrud = 0;
526 if (! absolute_names_option)
527 {
528 while (CURRENT_FILE_NAME[0] == '/')
529 {
530 static int warned_once;
531
532 if (!warned_once)
533 {
534 warned_once = 1;
535 WARN ((0, 0, _("Removing leading `/' from member names")));
536 }
537 skipcrud++; /* force relative path */
538 }
539
540 if (contains_dot_dot (CURRENT_FILE_NAME))
541 {
542 ERROR ((0, 0, _("%s: Member name contains `..'"),
543 quotearg_colon (CURRENT_FILE_NAME)));
544 if (current_header->oldgnu_header.isextended)
545 skip_extended_headers ();
546 skip_file (current_stat.st_size);
547 return;
548 }
549 }
550
551 /* Take a safety backup of a previously existing file. */
552
553 if (backup_option && !to_stdout_option)
554 if (!maybe_backup_file (CURRENT_FILE_NAME, 0))
555 {
556 int e = errno;
557 ERROR ((0, e, _("%s: Was unable to backup this file"),
558 quotearg_colon (CURRENT_FILE_NAME)));
559 if (current_header->oldgnu_header.isextended)
560 skip_extended_headers ();
561 skip_file (current_stat.st_size);
562 return;
563 }
564
565 /* Extract the archive entry according to its type. */
566
567 typeflag = current_header->header.typeflag;
568 switch (typeflag)
569 {
570 /* JK - What we want to do if the file is sparse is loop through
571 the array of sparse structures in the header and read in and
572 translate the character strings representing 1) the offset at
573 which to write and 2) how many bytes to write into numbers,
574 which we store into the scratch array, "sparsearray". This
575 array makes our life easier the same way it did in creating the
576 tar file that had to deal with a sparse file.
577
578 After we read in the first five (at most) sparse structures, we
579 check to see if the file has an extended header, i.e., if more
580 sparse structures are needed to describe the contents of the new
581 file. If so, we read in the extended headers and continue to
582 store their contents into the sparsearray. */
583
584 case GNUTYPE_SPARSE:
585 sp_array_size = 10;
586 sparsearray =
587 xmalloc (sp_array_size * sizeof (struct sp_array));
588
589 for (counter = 0; counter < SPARSES_IN_OLDGNU_HEADER; counter++)
590 {
591 struct sparse const *s = &current_header->oldgnu_header.sp[counter];
592 sparsearray[counter].offset = OFF_FROM_HEADER (s->offset);
593 sparsearray[counter].numbytes = SIZE_FROM_HEADER (s->numbytes);
594 if (!sparsearray[counter].numbytes)
595 break;
596 }
597
598 if (current_header->oldgnu_header.isextended)
599 {
600 /* Read in the list of extended headers and translate them
601 into the sparsearray as before. Note that this
602 invalidates current_header. */
603
604 /* static */ int ind = SPARSES_IN_OLDGNU_HEADER;
605
606 while (1)
607 {
608 exhdr = find_next_block ();
609 if (! exhdr)
610 {
611 ERROR ((0, 0, _("Unexpected EOF in archive")));
612 return;
613 }
614 for (counter = 0; counter < SPARSES_IN_SPARSE_HEADER; counter++)
615 {
616 struct sparse const *s = &exhdr->sparse_header.sp[counter];
617 if (counter + ind > sp_array_size - 1)
618 {
619 /* Realloc the scratch area since we've run out of
620 room. */
621
622 sp_array_size *= 2;
623 sparsearray =
624 xrealloc (sparsearray,
625 sp_array_size * sizeof (struct sp_array));
626 }
627 if (s->numbytes[0] == 0)
628 break;
629 sparsearray[counter + ind].offset =
630 OFF_FROM_HEADER (s->offset);
631 sparsearray[counter + ind].numbytes =
632 SIZE_FROM_HEADER (s->numbytes);
633 }
634 if (!exhdr->sparse_header.isextended)
635 break;
636 else
637 {
638 ind += SPARSES_IN_SPARSE_HEADER;
639 set_next_block_after (exhdr);
640 }
641 }
642 set_next_block_after (exhdr);
643 }
644 /* Fall through. */
645
646 case AREGTYPE:
647 case REGTYPE:
648 case CONTTYPE:
649
650 /* Appears to be a file. But BSD tar uses the convention that a slash
651 suffix means a directory. */
652
653 name_length = strlen (CURRENT_FILE_NAME);
654 if (name_length && CURRENT_FILE_NAME[name_length - 1] == '/')
655 goto really_dir;
656
657 /* FIXME: deal with protection issues. */
658
659 again_file:
660 openflag = (O_WRONLY | O_BINARY | O_CREAT
661 | (old_files_option == OVERWRITE_OLD_FILES
662 ? O_TRUNC
663 : O_EXCL));
664 mode = current_stat.st_mode & MODE_RWX & ~ current_umask;
665
666 if (to_stdout_option)
667 {
668 fd = STDOUT_FILENO;
669 goto extract_file;
670 }
671
672 if (! prepare_to_extract (CURRENT_FILE_NAME))
673 {
674 if (current_header->oldgnu_header.isextended)
675 skip_extended_headers ();
676 skip_file (current_stat.st_size);
677 if (backup_option)
678 undo_last_backup ();
679 break;
680 }
681
682 #if O_CTG
683 /* Contiguous files (on the Masscomp) have to specify the size in
684 the open call that creates them. */
685
686 if (typeflag == CONTTYPE)
687 fd = open (CURRENT_FILE_NAME, openflag | O_CTG,
688 mode, current_stat.st_size);
689 else
690 fd = open (CURRENT_FILE_NAME, openflag, mode);
691
692 #else /* not O_CTG */
693 if (typeflag == CONTTYPE)
694 {
695 static int conttype_diagnosed;
696
697 if (!conttype_diagnosed)
698 {
699 conttype_diagnosed = 1;
700 WARN ((0, 0, _("Extracting contiguous files as regular files")));
701 }
702 }
703 fd = open (CURRENT_FILE_NAME, openflag, mode);
704
705 #endif /* not O_CTG */
706
707 if (fd < 0)
708 {
709 if (maybe_recoverable (CURRENT_FILE_NAME, &interdir_made))
710 goto again_file;
711
712 open_error (CURRENT_FILE_NAME);
713 if (current_header->oldgnu_header.isextended)
714 skip_extended_headers ();
715 skip_file (current_stat.st_size);
716 if (backup_option)
717 undo_last_backup ();
718 break;
719 }
720
721 extract_file:
722 if (typeflag == GNUTYPE_SPARSE)
723 {
724 char *name;
725 size_t name_length_bis;
726
727 /* Kludge alert. NAME is assigned to header.name because
728 during the extraction, the space that contains the header
729 will get scribbled on, and the name will get munged, so any
730 error messages that happen to contain the filename will look
731 REAL interesting unless we do this. */
732
733 name_length_bis = strlen (CURRENT_FILE_NAME) + 1;
734 name = xmalloc (name_length_bis);
735 memcpy (name, CURRENT_FILE_NAME, name_length_bis);
736 size = current_stat.st_size;
737 extract_sparse_file (fd, &size, current_stat.st_size, name);
738 }
739 else
740 for (size = current_stat.st_size;
741 size > 0;
742 size -= written)
743 {
744 if (multi_volume_option)
745 {
746 assign_string (&save_name, current_file_name);
747 save_totsize = current_stat.st_size;
748 save_sizeleft = size;
749 }
750
751 /* Locate data, determine max length writeable, write it,
752 block that we have used the data, then check if the write
753 worked. */
754
755 data_block = find_next_block ();
756 if (! data_block)
757 {
758 ERROR ((0, 0, _("Unexpected EOF in archive")));
759 break; /* FIXME: What happens, then? */
760 }
761
762 written = available_space_after (data_block);
763
764 if (written > size)
765 written = size;
766 errno = 0;
767 sstatus = full_write (fd, data_block->buffer, written);
768
769 set_next_block_after ((union block *)
770 (data_block->buffer + written - 1));
771 if (sstatus == written)
772 continue;
773
774 /* Error in writing to file. Print it, skip to next file in
775 archive. */
776
777 write_error_details (CURRENT_FILE_NAME, sstatus, written);
778 skip_file (size - written);
779 break; /* still do the close, mod time, chmod, etc */
780 }
781
782 if (multi_volume_option)
783 assign_string (&save_name, 0);
784
785 /* If writing to stdout, don't try to do anything to the filename;
786 it doesn't exist, or we don't want to touch it anyway. */
787
788 if (to_stdout_option)
789 break;
790
791 status = close (fd);
792 if (status < 0)
793 {
794 close_error (CURRENT_FILE_NAME);
795 if (backup_option)
796 undo_last_backup ();
797 }
798
799 set_stat (CURRENT_FILE_NAME, &current_stat, 0,
800 (old_files_option == OVERWRITE_OLD_FILES
801 ? UNKNOWN_PERMSTATUS
802 : ARCHIVED_PERMSTATUS),
803 typeflag);
804 break;
805
806 case SYMTYPE:
807 #ifdef HAVE_SYMLINK
808 if (! prepare_to_extract (CURRENT_FILE_NAME))
809 break;
810
811 while (status = symlink (current_link_name, CURRENT_FILE_NAME),
812 status != 0)
813 if (!maybe_recoverable (CURRENT_FILE_NAME, &interdir_made))
814 break;
815
816 if (status == 0)
817
818 /* Setting the attributes of symbolic links might, on some systems,
819 change the pointed to file, instead of the symbolic link itself.
820 At least some of these systems have a lchown call, and the
821 set_stat routine knows about this. */
822
823 set_stat (CURRENT_FILE_NAME, &current_stat, 0,
824 ARCHIVED_PERMSTATUS, typeflag);
825
826 else
827 {
828 int e = errno;
829 ERROR ((0, e, _("%s: Cannot create symlink to %s"),
830 quotearg_colon (CURRENT_FILE_NAME),
831 quote (current_link_name)));
832 if (backup_option)
833 undo_last_backup ();
834 }
835 break;
836
837 #else
838 {
839 static int warned_once;
840
841 if (!warned_once)
842 {
843 warned_once = 1;
844 WARN ((0, 0,
845 _("Attempting extraction of symbolic links as hard links")));
846 }
847 }
848 typeflag = LNKTYPE;
849 /* Fall through. */
850 #endif
851
852 case LNKTYPE:
853 if (! prepare_to_extract (CURRENT_FILE_NAME))
854 break;
855
856 again_link:
857 {
858 struct stat st1, st2;
859 int e;
860
861 /* MSDOS does not implement links. However, djgpp's link() actually
862 copies the file. */
863 status = link (current_link_name, CURRENT_FILE_NAME);
864
865 if (status == 0)
866 break;
867 if (maybe_recoverable (CURRENT_FILE_NAME, &interdir_made))
868 goto again_link;
869
870 if (incremental_option && errno == EEXIST)
871 break;
872 e = errno;
873 if (stat (current_link_name, &st1) == 0
874 && stat (CURRENT_FILE_NAME, &st2) == 0
875 && st1.st_dev == st2.st_dev
876 && st1.st_ino == st2.st_ino)
877 break;
878
879 ERROR ((0, e, _("%s: Cannot link to %s"),
880 quotearg_colon (CURRENT_FILE_NAME),
881 quote (current_link_name)));
882 if (backup_option)
883 undo_last_backup ();
884 }
885 break;
886
887 #if S_IFCHR
888 case CHRTYPE:
889 current_stat.st_mode |= S_IFCHR;
890 goto make_node;
891 #endif
892
893 #if S_IFBLK
894 case BLKTYPE:
895 current_stat.st_mode |= S_IFBLK;
896 #endif
897
898 #if S_IFCHR || S_IFBLK
899 make_node:
900 if (! prepare_to_extract (CURRENT_FILE_NAME))
901 break;
902
903 status = mknod (CURRENT_FILE_NAME, current_stat.st_mode,
904 current_stat.st_rdev);
905 if (status != 0)
906 {
907 if (maybe_recoverable (CURRENT_FILE_NAME, &interdir_made))
908 goto make_node;
909 mknod_error (CURRENT_FILE_NAME);
910 if (backup_option)
911 undo_last_backup ();
912 break;
913 };
914 set_stat (CURRENT_FILE_NAME, &current_stat, 0,
915 ARCHIVED_PERMSTATUS, typeflag);
916 break;
917 #endif
918
919 #if HAVE_MKFIFO || defined mkfifo
920 case FIFOTYPE:
921 if (! prepare_to_extract (CURRENT_FILE_NAME))
922 break;
923
924 while (status = mkfifo (CURRENT_FILE_NAME, current_stat.st_mode),
925 status != 0)
926 if (!maybe_recoverable (CURRENT_FILE_NAME, &interdir_made))
927 break;
928
929 if (status == 0)
930 set_stat (CURRENT_FILE_NAME, &current_stat, 0,
931 ARCHIVED_PERMSTATUS, typeflag);
932 else
933 {
934 mkfifo_error (CURRENT_FILE_NAME);
935 if (backup_option)
936 undo_last_backup ();
937 }
938 break;
939 #endif
940
941 case DIRTYPE:
942 case GNUTYPE_DUMPDIR:
943 name_length = strlen (CURRENT_FILE_NAME);
944
945 really_dir:
946 /* Remove trailing "/" and "/.", unless that would result in the
947 empty string. */
948 for (;;)
949 {
950 if (1 < name_length && CURRENT_FILE_NAME[name_length - 1] == '/')
951 CURRENT_FILE_NAME[--name_length] = '\0';
952 else if (2 < name_length
953 && CURRENT_FILE_NAME[name_length - 1] == '.'
954 && CURRENT_FILE_NAME[name_length - 2] == '/')
955 CURRENT_FILE_NAME[name_length -= 2] = '\0';
956 else
957 break;
958 }
959
960 if (incremental_option)
961 {
962 /* Read the entry and delete files that aren't listed in the
963 archive. */
964
965 gnu_restore (skipcrud);
966 }
967 else if (typeflag == GNUTYPE_DUMPDIR)
968 skip_file (current_stat.st_size);
969
970 if (! prepare_to_extract (CURRENT_FILE_NAME))
971 break;
972
973 mode = ((current_stat.st_mode
974 | (we_are_root ? 0 : MODE_WXUSR))
975 & MODE_RWX);
976
977 again_dir:
978 status = mkdir (CURRENT_FILE_NAME, mode);
979 if (status != 0)
980 {
981 if (errno == EEXIST && interdir_made
982 && contains_dot_dot (CURRENT_FILE_NAME))
983 {
984 int e = errno;
985 struct stat st;
986 if (stat (CURRENT_FILE_NAME, &st) == 0)
987 {
988 repair_delayed_set_stat (CURRENT_FILE_NAME, &st);
989 break;
990 }
991 e = errno;
992 }
993
994 if (maybe_recoverable (CURRENT_FILE_NAME, &interdir_made))
995 goto again_dir;
996
997 if (errno != EEXIST || old_files_option == KEEP_OLD_FILES)
998 {
999 mkdir_error (CURRENT_FILE_NAME);
1000 if (backup_option)
1001 undo_last_backup ();
1002 break;
1003 }
1004 }
1005
1006 if (status == 0
1007 || old_files_option == OVERWRITE_OLD_FILES)
1008 delay_set_stat (CURRENT_FILE_NAME, &current_stat,
1009 mode & ~ current_stat.st_mode,
1010 (status == 0
1011 ? ARCHIVED_PERMSTATUS
1012 : UNKNOWN_PERMSTATUS));
1013 break;
1014
1015 case GNUTYPE_VOLHDR:
1016 if (verbose_option)
1017 fprintf (stdlis, _("Reading %s\n"), quote (current_file_name));
1018 break;
1019
1020 case GNUTYPE_NAMES:
1021 extract_mangle ();
1022 break;
1023
1024 case GNUTYPE_MULTIVOL:
1025 ERROR ((0, 0,
1026 _("%s: Cannot extract -- file is continued from another volume"),
1027 quotearg_colon (current_file_name)));
1028 skip_file (current_stat.st_size);
1029 if (backup_option)
1030 undo_last_backup ();
1031 break;
1032
1033 case GNUTYPE_LONGNAME:
1034 case GNUTYPE_LONGLINK:
1035 ERROR ((0, 0, _("Visible long name error")));
1036 skip_file (current_stat.st_size);
1037 if (backup_option)
1038 undo_last_backup ();
1039 break;
1040
1041 default:
1042 WARN ((0, 0,
1043 _("%s: Unknown file type '%c', extracted as normal file"),
1044 quotearg_colon (CURRENT_FILE_NAME), typeflag));
1045 goto again_file;
1046 }
1047
1048 #undef CURRENT_FILE_NAME
1049 }
1050
1051 /* Fix the status of all directories whose statuses need fixing. */
1052 void
1053 apply_delayed_set_stat (void)
1054 {
1055 apply_nonancestor_delayed_set_stat ("");
1056 }
1057
1058 /* Fix the statuses of all directories whose statuses need fixing, and
1059 which are not ancestors of FILE_NAME. */
1060 void
1061 apply_nonancestor_delayed_set_stat (char const *file_name)
1062 {
1063 size_t file_name_len = strlen (file_name);
1064
1065 while (delayed_set_stat_head)
1066 {
1067 struct delayed_set_stat *data = delayed_set_stat_head;
1068 if (data->file_name_len < file_name_len
1069 && file_name[data->file_name_len] == '/'
1070 && memcmp (file_name, data->file_name, data->file_name_len) == 0)
1071 break;
1072 delayed_set_stat_head = data->next;
1073 set_stat (data->file_name, &data->stat_info,
1074 data->invert_permissions, data->permstatus, DIRTYPE);
1075 free (data);
1076 }
1077 }
1078
1079 void
1080 fatal_exit (void)
1081 {
1082 apply_delayed_set_stat ();
1083 error (TAREXIT_FAILURE, 0, _("Error is not recoverable: exiting now"));
1084 abort ();
1085 }
This page took 0.08215 seconds and 4 git commands to generate.