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