]> Dogcows Code - chaz/tar/blob - src/extract.c
(time): Don't declare if defined.
[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 /* Fix ownership. */
253
254 if (we_are_root)
255 if (chown (file_name, current_stat.st_uid, current_stat.st_gid) < 0)
256 ERROR ((0, errno,
257 _("%s: Cannot change owner to uid %lu, gid %lu"),
258 file_name,
259 (unsigned long) current_stat.st_uid,
260 (unsigned long) current_stat.st_gid));
261
262 print_for_mkdir (file_name, cursor - file_name,
263 ~newdir_umask & MODE_RWX);
264 did_something = 1;
265
266 *cursor = '/';
267 continue;
268 }
269
270 *cursor = '/';
271
272 if (errno == EEXIST
273 #if MSDOS
274 /* Turbo C mkdir gives a funny errno. */
275 || errno == EACCES
276 #endif
277 )
278 /* Directory already exists. */
279 continue;
280
281 /* Some other error in the mkdir. We return to the caller. */
282 break;
283 }
284
285 errno = saved_errno; /* FIXME: errno should be read-only */
286 return did_something; /* tell them to retry if we made one */
287 }
288
289 /*--------------------------------------------------------------------.
290 | Unlink the destination, if we are supposed to do so. |
291 | Return zero if extraction should not proceed. |
292 `--------------------------------------------------------------------*/
293
294 static int
295 unlink_destination (char const *file_name)
296 {
297 if (unlink_first_option
298 && !remove_any_file (file_name, recursive_unlink_option)
299 && errno != ENOENT)
300 {
301 ERROR ((0, errno, _("Cannot remove %s"), file_name));
302 return 0;
303 }
304
305 return 1;
306 }
307
308 /*--------------------------------------------------------------------.
309 | Attempt repairing what went wrong with the extraction. Delete an |
310 | already existing file or create missing intermediate directories. |
311 | Return nonzero if we somewhat increased our chances at a successful |
312 | extraction. errno is properly restored on zero return. |
313 `--------------------------------------------------------------------*/
314
315 static int
316 maybe_recoverable (char *file_name)
317 {
318 switch (errno)
319 {
320 case EEXIST:
321 /* Attempt deleting an existing file. However, with -k or -U, just stay
322 quiet. */
323
324 if (keep_old_files_option || unlink_first_option)
325 return 0;
326
327 return remove_any_file (file_name, 0);
328
329 case ENOENT:
330 /* Attempt creating missing intermediate directories. */
331
332 return make_directories (file_name);
333
334 default:
335 /* Just say we can't do anything about it... */
336
337 return 0;
338 }
339 }
340
341 /*---.
342 | ? |
343 `---*/
344
345 static void
346 extract_sparse_file (int fd, off_t *sizeleft, off_t totalsize, char *name)
347 {
348 int sparse_ind = 0;
349 size_t written;
350 ssize_t count;
351
352 /* assuming sizeleft is initially totalsize */
353
354 while (*sizeleft > 0)
355 {
356 union block *data_block = find_next_block ();
357 if (data_block == NULL)
358 {
359 ERROR ((0, 0, _("Unexpected EOF on archive file")));
360 return;
361 }
362 if (lseek (fd, sparsearray[sparse_ind].offset, SEEK_SET) < 0)
363 {
364 char buf[UINTMAX_STRSIZE_BOUND];
365 ERROR ((0, errno, _("%s: lseek error at byte %s"),
366 STRINGIFY_BIGINT (sparsearray[sparse_ind].offset, buf),
367 name));
368 return;
369 }
370 written = sparsearray[sparse_ind++].numbytes;
371 while (written > BLOCKSIZE)
372 {
373 count = full_write (fd, data_block->buffer, BLOCKSIZE);
374 if (count < 0)
375 ERROR ((0, errno, _("%s: Could not write to file"), name));
376 written -= count;
377 *sizeleft -= count;
378 set_next_block_after (data_block);
379 data_block = find_next_block ();
380 }
381
382 count = full_write (fd, data_block->buffer, written);
383
384 if (count < 0)
385 ERROR ((0, errno, _("%s: Could not write to file"), name));
386 else if (count != written)
387 {
388 char buf1[UINTMAX_STRSIZE_BOUND];
389 char buf2[UINTMAX_STRSIZE_BOUND];
390 ERROR ((0, 0, _("%s: Could only write %s of %s bytes"),
391 name,
392 STRINGIFY_BIGINT (totalsize - *sizeleft, buf1),
393 STRINGIFY_BIGINT (totalsize, buf2)));
394 skip_file (*sizeleft);
395 }
396
397 written -= count;
398 *sizeleft -= count;
399 set_next_block_after (data_block);
400 }
401
402 free (sparsearray);
403 }
404
405 /*----------------------------------.
406 | Extract a file from the archive. |
407 `----------------------------------*/
408
409 void
410 extract_archive (void)
411 {
412 union block *data_block;
413 int fd;
414 int status;
415 ssize_t sstatus;
416 size_t name_length;
417 size_t written;
418 int openflag;
419 off_t size;
420 int skipcrud;
421 int counter;
422 char typeflag;
423 #if 0
424 int sparse_ind = 0;
425 #endif
426 union block *exhdr;
427 struct delayed_set_stat *data;
428
429 #define CURRENT_FILE_NAME (skipcrud + current_file_name)
430
431 set_next_block_after (current_header);
432 decode_header (current_header, &current_stat, &current_format, 1);
433
434 if (interactive_option && !confirm ("extract", current_file_name))
435 {
436 if (current_header->oldgnu_header.isextended)
437 skip_extended_headers ();
438 skip_file (current_stat.st_size);
439 return;
440 }
441
442 /* Print the block from `current_header' and `current_stat'. */
443
444 if (verbose_option)
445 print_header ();
446
447 /* Check for fully specified file names and other atrocities. */
448
449 skipcrud = 0;
450 while (!absolute_names_option && CURRENT_FILE_NAME[0] == '/')
451 {
452 static int warned_once;
453
454 if (!warned_once)
455 {
456 warned_once = 1;
457 WARN ((0, 0, _("Removing leading `/' from archive names")));
458 }
459 skipcrud++; /* force relative path */
460 }
461
462 /* Take a safety backup of a previously existing file. */
463
464 if (backup_option && !to_stdout_option)
465 if (!maybe_backup_file (CURRENT_FILE_NAME, 0))
466 {
467 ERROR ((0, errno, _("%s: Was unable to backup this file"),
468 CURRENT_FILE_NAME));
469 if (current_header->oldgnu_header.isextended)
470 skip_extended_headers ();
471 skip_file (current_stat.st_size);
472 return;
473 }
474
475 /* Extract the archive entry according to its type. */
476
477 typeflag = current_header->header.typeflag;
478 switch (typeflag)
479 {
480 /* JK - What we want to do if the file is sparse is loop through
481 the array of sparse structures in the header and read in and
482 translate the character strings representing 1) the offset at
483 which to write and 2) how many bytes to write into numbers,
484 which we store into the scratch array, "sparsearray". This
485 array makes our life easier the same way it did in creating the
486 tar file that had to deal with a sparse file.
487
488 After we read in the first five (at most) sparse structures, we
489 check to see if the file has an extended header, i.e., if more
490 sparse structures are needed to describe the contents of the new
491 file. If so, we read in the extended headers and continue to
492 store their contents into the sparsearray. */
493
494 case GNUTYPE_SPARSE:
495 sp_array_size = 10;
496 sparsearray = (struct sp_array *)
497 xmalloc (sp_array_size * sizeof (struct sp_array));
498
499 for (counter = 0; counter < SPARSES_IN_OLDGNU_HEADER; counter++)
500 {
501 sparsearray[counter].offset =
502 OFF_FROM_CHARS (current_header->oldgnu_header.sp[counter].offset);
503 sparsearray[counter].numbytes =
504 SIZE_FROM_CHARS (current_header->oldgnu_header.sp[counter].numbytes);
505 if (!sparsearray[counter].numbytes)
506 break;
507 }
508
509 if (current_header->oldgnu_header.isextended)
510 {
511 /* Read in the list of extended headers and translate them
512 into the sparsearray as before. Note that this
513 invalidates current_header. */
514
515 /* static */ int ind = SPARSES_IN_OLDGNU_HEADER;
516
517 while (1)
518 {
519 exhdr = find_next_block ();
520 for (counter = 0; counter < SPARSES_IN_SPARSE_HEADER; counter++)
521 {
522 if (counter + ind > sp_array_size - 1)
523 {
524 /* Realloc the scratch area since we've run out of
525 room. */
526
527 sp_array_size *= 2;
528 sparsearray = (struct sp_array *)
529 xrealloc (sparsearray,
530 sp_array_size * (sizeof (struct sp_array)));
531 }
532 /* Compare to 0, or use !(int)..., for Pyramid's dumb
533 compiler. */
534 if (exhdr->sparse_header.sp[counter].numbytes == 0)
535 break;
536 sparsearray[counter + ind].offset =
537 OFF_FROM_CHARS (exhdr->sparse_header.sp[counter].offset);
538 sparsearray[counter + ind].numbytes =
539 SIZE_FROM_CHARS (exhdr->sparse_header.sp[counter].numbytes);
540 }
541 if (!exhdr->sparse_header.isextended)
542 break;
543 else
544 {
545 ind += SPARSES_IN_SPARSE_HEADER;
546 set_next_block_after (exhdr);
547 }
548 }
549 set_next_block_after (exhdr);
550 }
551 /* Fall through. */
552
553 case AREGTYPE:
554 case REGTYPE:
555 case CONTTYPE:
556
557 /* Appears to be a file. But BSD tar uses the convention that a slash
558 suffix means a directory. */
559
560 name_length = strlen (CURRENT_FILE_NAME) - 1;
561 if (CURRENT_FILE_NAME[name_length] == '/')
562 goto really_dir;
563
564 /* FIXME: deal with protection issues. */
565
566 again_file:
567 openflag = (keep_old_files_option || unlink_first_option ?
568 O_WRONLY | O_BINARY | O_NONBLOCK | O_CREAT | O_EXCL :
569 O_WRONLY | O_BINARY | O_NONBLOCK | O_CREAT | O_TRUNC)
570 | ((typeflag == GNUTYPE_SPARSE) ? 0 : O_APPEND);
571
572 /* JK - The last | is a kludge to solve the problem the O_APPEND
573 flag causes with files we are trying to make sparse: when a file
574 is opened with O_APPEND, it writes to the last place that
575 something was written, thereby ignoring any lseeks that we have
576 done. We add this extra condition to make it able to lseek when
577 a file is sparse, i.e., we don't open the new file with this
578 flag. (Grump -- this bug caused me to waste a good deal of
579 time, I might add) */
580
581 if (to_stdout_option)
582 {
583 fd = 1;
584 goto extract_file;
585 }
586
587 if (!unlink_destination (CURRENT_FILE_NAME))
588 {
589 if (current_header->oldgnu_header.isextended)
590 skip_extended_headers ();
591 skip_file (current_stat.st_size);
592 if (backup_option)
593 undo_last_backup ();
594 break;
595 }
596
597 #if O_CTG
598 /* Contiguous files (on the Masscomp) have to specify the size in
599 the open call that creates them. */
600
601 if (typeflag == CONTTYPE)
602 fd = open (CURRENT_FILE_NAME, openflag | O_CTG,
603 current_stat.st_mode, current_stat.st_size);
604 else
605 fd = open (CURRENT_FILE_NAME, openflag, current_stat.st_mode);
606
607 #else /* not O_CTG */
608 if (typeflag == CONTTYPE)
609 {
610 static int conttype_diagnosed = 0;
611
612 if (!conttype_diagnosed)
613 {
614 conttype_diagnosed = 1;
615 WARN ((0, 0, _("Extracting contiguous files as regular files")));
616 }
617 }
618 fd = open (CURRENT_FILE_NAME, openflag, current_stat.st_mode);
619
620 #endif /* not O_CTG */
621
622 if (fd < 0)
623 {
624 if (maybe_recoverable (CURRENT_FILE_NAME))
625 goto again_file;
626
627 ERROR ((0, errno, _("%s: Could not create file"),
628 CURRENT_FILE_NAME));
629 if (current_header->oldgnu_header.isextended)
630 skip_extended_headers ();
631 skip_file (current_stat.st_size);
632 if (backup_option)
633 undo_last_backup ();
634 break;
635 }
636
637 extract_file:
638 if (typeflag == GNUTYPE_SPARSE)
639 {
640 char *name;
641 size_t name_length_bis;
642
643 /* Kludge alert. NAME is assigned to header.name because
644 during the extraction, the space that contains the header
645 will get scribbled on, and the name will get munged, so any
646 error messages that happen to contain the filename will look
647 REAL interesting unless we do this. */
648
649 name_length_bis = strlen (CURRENT_FILE_NAME) + 1;
650 name = (char *) xmalloc (name_length_bis);
651 memcpy (name, CURRENT_FILE_NAME, name_length_bis);
652 size = current_stat.st_size;
653 extract_sparse_file (fd, &size, current_stat.st_size, name);
654 }
655 else
656 for (size = current_stat.st_size;
657 size > 0;
658 size -= written)
659 {
660 if (multi_volume_option)
661 {
662 assign_string (&save_name, current_file_name);
663 save_totsize = current_stat.st_size;
664 save_sizeleft = size;
665 }
666
667 /* Locate data, determine max length writeable, write it,
668 block that we have used the data, then check if the write
669 worked. */
670
671 data_block = find_next_block ();
672 if (data_block == NULL)
673 {
674 ERROR ((0, 0, _("Unexpected EOF on archive file")));
675 break; /* FIXME: What happens, then? */
676 }
677
678 written = available_space_after (data_block);
679
680 if (written > size)
681 written = size;
682 errno = 0; /* FIXME: errno should be read-only */
683 sstatus = full_write (fd, data_block->buffer, written);
684
685 set_next_block_after ((union block *)
686 (data_block->buffer + written - 1));
687 if (sstatus == written)
688 continue;
689
690 /* Error in writing to file. Print it, skip to next file in
691 archive. */
692
693 if (sstatus < 0)
694 ERROR ((0, errno, _("%s: Could not write to file"),
695 CURRENT_FILE_NAME));
696 else
697 ERROR ((0, 0, _("%s: Could only write %lu of %lu bytes"),
698 CURRENT_FILE_NAME,
699 (unsigned long) sstatus,
700 (unsigned long) written));
701 skip_file (size - written);
702 break; /* still do the close, mod time, chmod, etc */
703 }
704
705 if (multi_volume_option)
706 assign_string (&save_name, NULL);
707
708 /* If writing to stdout, don't try to do anything to the filename;
709 it doesn't exist, or we don't want to touch it anyway. */
710
711 if (to_stdout_option)
712 break;
713
714 status = close (fd);
715 if (status < 0)
716 {
717 ERROR ((0, errno, _("%s: Error while closing"), CURRENT_FILE_NAME));
718 if (backup_option)
719 undo_last_backup ();
720 }
721
722 set_stat (CURRENT_FILE_NAME, &current_stat, 0);
723 break;
724
725 case SYMTYPE:
726 if (to_stdout_option)
727 break;
728
729 #ifdef HAVE_SYMLINK
730 if (!unlink_destination (CURRENT_FILE_NAME))
731 break;
732
733 while (status = symlink (current_link_name, CURRENT_FILE_NAME),
734 status != 0)
735 if (!maybe_recoverable (CURRENT_FILE_NAME))
736 break;
737
738 if (status == 0)
739
740 /* Setting the attributes of symbolic links might, on some systems,
741 change the pointed to file, instead of the symbolic link itself.
742 At least some of these systems have a lchown call, and the
743 set_stat routine knows about this. */
744
745 set_stat (CURRENT_FILE_NAME, &current_stat, 1);
746
747 else
748 {
749 ERROR ((0, errno, _("%s: Could not create symlink to `%s'"),
750 CURRENT_FILE_NAME, current_link_name));
751 if (backup_option)
752 undo_last_backup ();
753 }
754 break;
755
756 #else
757 {
758 static int warned_once = 0;
759
760 if (!warned_once)
761 {
762 warned_once = 1;
763 WARN ((0, 0, _("\
764 Attempting extraction of symbolic links as hard links")));
765 }
766 }
767 /* Fall through. */
768
769 #endif
770
771 case LNKTYPE:
772 if (to_stdout_option)
773 break;
774
775 if (!unlink_destination (CURRENT_FILE_NAME))
776 break;
777
778 again_link:
779 {
780 struct stat st1, st2;
781
782 /* MSDOS does not implement links. However, djgpp's link() actually
783 copies the file. */
784 status = link (current_link_name, CURRENT_FILE_NAME);
785
786 if (status == 0)
787 break;
788 if (maybe_recoverable (CURRENT_FILE_NAME))
789 goto again_link;
790
791 if (incremental_option && errno == EEXIST)
792 break;
793 if (stat (current_link_name, &st1) == 0
794 && stat (CURRENT_FILE_NAME, &st2) == 0
795 && st1.st_dev == st2.st_dev
796 && st1.st_ino == st2.st_ino)
797 break;
798
799 ERROR ((0, errno, _("%s: Could not link to `%s'"),
800 CURRENT_FILE_NAME, current_link_name));
801 if (backup_option)
802 undo_last_backup ();
803 }
804 break;
805
806 #if S_IFCHR
807 case CHRTYPE:
808 current_stat.st_mode |= S_IFCHR;
809 goto make_node;
810 #endif
811
812 #if S_IFBLK
813 case BLKTYPE:
814 current_stat.st_mode |= S_IFBLK;
815 #endif
816
817 #if S_IFCHR || S_IFBLK
818 make_node:
819 if (to_stdout_option)
820 break;
821
822 if (!unlink_destination (CURRENT_FILE_NAME))
823 break;
824
825 status = mknod (CURRENT_FILE_NAME, current_stat.st_mode,
826 current_stat.st_rdev);
827 if (status != 0)
828 {
829 if (maybe_recoverable (CURRENT_FILE_NAME))
830 goto make_node;
831
832 ERROR ((0, errno, _("%s: Could not make node"), CURRENT_FILE_NAME));
833 if (backup_option)
834 undo_last_backup ();
835 break;
836 };
837 set_stat (CURRENT_FILE_NAME, &current_stat, 0);
838 break;
839 #endif
840
841 #if HAVE_MKFIFO || defined mkfifo
842 case FIFOTYPE:
843 if (to_stdout_option)
844 break;
845
846 if (!unlink_destination (CURRENT_FILE_NAME))
847 break;
848
849 while (status = mkfifo (CURRENT_FILE_NAME, current_stat.st_mode),
850 status != 0)
851 if (!maybe_recoverable (CURRENT_FILE_NAME))
852 break;
853
854 if (status == 0)
855 set_stat (CURRENT_FILE_NAME, &current_stat, 0);
856 else
857 {
858 ERROR ((0, errno, _("%s: Could not make fifo"), CURRENT_FILE_NAME));
859 if (backup_option)
860 undo_last_backup ();
861 }
862 break;
863 #endif
864
865 case DIRTYPE:
866 case GNUTYPE_DUMPDIR:
867 name_length = strlen (CURRENT_FILE_NAME) - 1;
868
869 really_dir:
870 /* Check for trailing /, and zap as many as we find. */
871 while (name_length && CURRENT_FILE_NAME[name_length] == '/')
872 CURRENT_FILE_NAME[name_length--] = '\0';
873
874 if (incremental_option)
875 {
876 /* Read the entry and delete files that aren't listed in the
877 archive. */
878
879 gnu_restore (skipcrud);
880 }
881 else if (typeflag == GNUTYPE_DUMPDIR)
882 skip_file (current_stat.st_size);
883
884 if (to_stdout_option)
885 break;
886
887 again_dir:
888 status = mkdir (CURRENT_FILE_NAME,
889 ((we_are_root ? 0 : MODE_WXUSR)
890 | current_stat.st_mode));
891 if (status != 0)
892 {
893 /* If the directory creation fails, let's consider immediately the
894 case where the directory already exists. We have three good
895 reasons for clearing out this case before attempting recovery.
896
897 1) It would not be efficient recovering the error by deleting
898 the directory in maybe_recoverable, then recreating it right
899 away. We only hope we will be able to adjust its permissions
900 adequately, later.
901
902 2) Removing the directory might fail if it is not empty. By
903 exception, this real error is traditionally not reported.
904
905 3) Let's suppose `DIR' already exists and we are about to
906 extract `DIR/../DIR'. This would fail because the directory
907 already exists, and maybe_recoverable would react by removing
908 `DIR'. This then would fail again because there are missing
909 intermediate directories, and maybe_recoverable would react by
910 creating `DIR'. We would then have an extraction loop. */
911
912 if (errno == EEXIST)
913 {
914 struct stat st1;
915 int saved_errno = errno;
916
917 if (stat (CURRENT_FILE_NAME, &st1) == 0 && S_ISDIR (st1.st_mode))
918 goto check_perms;
919
920 errno = saved_errno; /* FIXME: errno should be read-only */
921 }
922
923 if (maybe_recoverable (CURRENT_FILE_NAME))
924 goto again_dir;
925
926 /* If we're trying to create '.', let it be. */
927
928 /* FIXME: Strange style... */
929
930 if (CURRENT_FILE_NAME[name_length] == '.'
931 && (name_length == 0
932 || CURRENT_FILE_NAME[name_length - 1] == '/'))
933 goto check_perms;
934
935 ERROR ((0, errno, _("%s: Could not create directory"),
936 CURRENT_FILE_NAME));
937 if (backup_option)
938 undo_last_backup ();
939 break;
940 }
941
942 check_perms:
943 if (!we_are_root && MODE_WXUSR != (MODE_WXUSR & current_stat.st_mode))
944 {
945 current_stat.st_mode |= MODE_WXUSR;
946 WARN ((0, 0, _("Added write and execute permission to directory %s"),
947 CURRENT_FILE_NAME));
948 }
949
950 #if !MSDOS
951 /* MSDOS does not associate timestamps with directories. In this
952 case, no need to try delaying their restoration. */
953
954 if (touch_option)
955
956 /* FIXME: I do not believe in this. Ignoring time stamps does not
957 alleviate the need of delaying the restoration of directories'
958 mode. Let's ponder this for a little while. */
959
960 set_mode (CURRENT_FILE_NAME, &current_stat);
961
962 else
963 {
964 data = ((struct delayed_set_stat *)
965 xmalloc (sizeof (struct delayed_set_stat)));
966 data->file_name = xstrdup (CURRENT_FILE_NAME);
967 data->stat_info = current_stat;
968 data->next = delayed_set_stat_head;
969 delayed_set_stat_head = data;
970 }
971 #endif /* !MSDOS */
972 break;
973
974 case GNUTYPE_VOLHDR:
975 if (verbose_option)
976 fprintf (stdlis, _("Reading %s\n"), current_file_name);
977 break;
978
979 case GNUTYPE_NAMES:
980 extract_mangle ();
981 break;
982
983 case GNUTYPE_MULTIVOL:
984 ERROR ((0, 0, _("\
985 Cannot extract `%s' -- file is continued from another volume"),
986 current_file_name));
987 skip_file (current_stat.st_size);
988 if (backup_option)
989 undo_last_backup ();
990 break;
991
992 case GNUTYPE_LONGNAME:
993 case GNUTYPE_LONGLINK:
994 ERROR ((0, 0, _("Visible long name error")));
995 skip_file (current_stat.st_size);
996 if (backup_option)
997 undo_last_backup ();
998 break;
999
1000 default:
1001 WARN ((0, 0,
1002 _("Unknown file type '%c' for %s, extracted as normal file"),
1003 typeflag, CURRENT_FILE_NAME));
1004 goto again_file;
1005 }
1006
1007 #undef CURRENT_FILE_NAME
1008 }
1009
1010 /*----------------------------------------------------------------.
1011 | Set back the utime and mode for all the extracted directories. |
1012 `----------------------------------------------------------------*/
1013
1014 void
1015 apply_delayed_set_stat (void)
1016 {
1017 struct delayed_set_stat *data;
1018
1019 while (delayed_set_stat_head != NULL)
1020 {
1021 data = delayed_set_stat_head;
1022 delayed_set_stat_head = delayed_set_stat_head->next;
1023 set_stat (data->file_name, &data->stat_info, 0);
1024 free (data->file_name);
1025 free (data);
1026 }
1027 }
This page took 0.076817 seconds and 5 git commands to generate.