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