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