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