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