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