]> Dogcows Code - chaz/tar/blob - src/extract.c
e498cf4bfb24dcc08a5f259f73547d9215a2f8a0
[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 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 &= ~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 & stat_info->st_mode) < 0)
107 ERROR ((0, errno, _("%s: Cannot change mode to %0.4lo"),
108 file_name,
109 (unsigned long) (~current_umask & stat_info->st_mode)));
110 }
111
112 /*----------------------------------------------------------------------.
113 | Restore stat attributes (owner, group, mode and times) for FILE_NAME, |
114 | using information given in STAT_INFO. SYMLINK_FLAG is non-zero for a |
115 | freshly restored symbolic link. |
116 `----------------------------------------------------------------------*/
117
118 /* FIXME: About proper restoration of symbolic link attributes, we still do
119 not have it right. Pretesters' reports tell us we need further study and
120 probably more configuration. For now, just use lchown if it exists, and
121 punt for the rest. Sigh! */
122
123 static void
124 set_stat (char *file_name, struct stat *stat_info, int symlink_flag)
125 {
126 struct utimbuf utimbuf;
127
128 if (!symlink_flag)
129 {
130 /* We do the utime before the chmod because some versions of utime are
131 broken and trash the modes of the file. */
132
133 if (!touch_option)
134 {
135 /* We set the accessed time to `now', which is really the time we
136 started extracting files, unless incremental_option is used, in
137 which case .st_atime is used. */
138
139 /* FIXME: incremental_option should set ctime too, but how? */
140
141 if (incremental_option)
142 utimbuf.actime = stat_info->st_atime;
143 else
144 utimbuf.actime = now;
145
146 utimbuf.modtime = stat_info->st_mtime;
147
148 if (utime (file_name, &utimbuf) < 0)
149 ERROR ((0, errno,
150 _("%s: Could not change access and modification times"),
151 file_name));
152 }
153
154 /* Some systems allow non-root users to give files away. Once this
155 done, it is not possible anymore to change file permissions, so we
156 have to set permissions prior to possibly giving files away. */
157
158 set_mode (file_name, stat_info);
159 }
160
161 /* If we are root, set the owner and group of the extracted file, so we
162 extract as the original owner. Or else, if we are running as a user,
163 leave the owner and group as they are, so we extract as that user. */
164
165 if (we_are_root || same_owner_option)
166 {
167 #if HAVE_LCHOWN
168
169 /* When lchown exists, it should be used to change the attributes of
170 the symbolic link itself. In this case, a mere chown would change
171 the attributes of the file the symbolic link is pointing to, and
172 should be avoided. */
173
174 if (symlink_flag)
175 {
176 if (lchown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
177 ERROR ((0, errno, _("%s: Cannot lchown to uid %lu gid %lu"),
178 file_name,
179 (unsigned long) stat_info->st_uid,
180 (unsigned long) stat_info->st_gid));
181 }
182 else
183 {
184 if (chown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
185 ERROR ((0, errno, _("%s: Cannot chown to uid %lu gid %lu"),
186 file_name,
187 (unsigned long) stat_info->st_uid,
188 (unsigned long) stat_info->st_gid));
189 }
190
191 #else /* not HAVE_LCHOWN */
192
193 if (!symlink_flag)
194
195 if (chown (file_name, stat_info->st_uid, stat_info->st_gid) < 0)
196 ERROR ((0, errno, _("%s: Cannot chown to uid %lu gid %lu"),
197 file_name,
198 (unsigned long) stat_info->st_uid,
199 (unsigned long) stat_info->st_gid));
200
201 #endif/* not HAVE_LCHOWN */
202
203 if (!symlink_flag)
204
205 /* On a few systems, and in particular, those allowing to give files
206 away, changing the owner or group destroys the suid or sgid bits.
207 So let's attempt setting these bits once more. */
208
209 if (stat_info->st_mode & (S_ISUID | S_ISGID | S_ISVTX))
210 set_mode (file_name, stat_info);
211 }
212 }
213
214 /*-----------------------------------------------------------------------.
215 | After a file/link/symlink/directory creation has failed, see if it's |
216 | because some required directory was not present, and if so, create all |
217 | required directories. Return non-zero if a directory was created. |
218 `-----------------------------------------------------------------------*/
219
220 static int
221 make_directories (char *file_name)
222 {
223 char *cursor; /* points into path */
224 int did_something = 0; /* did we do anything yet? */
225 int saved_errno = errno; /* remember caller's errno */
226 int status;
227
228 for (cursor = strchr (file_name, '/');
229 cursor != NULL;
230 cursor = strchr (cursor + 1, '/'))
231 {
232 /* Avoid mkdir of empty string, if leading or double '/'. */
233
234 if (cursor == file_name || cursor[-1] == '/')
235 continue;
236
237 /* Avoid mkdir where last part of path is '.'. */
238
239 if (cursor[-1] == '.' && (cursor == file_name + 1 || cursor[-2] == '/'))
240 continue;
241
242 *cursor = '\0'; /* truncate the path there */
243 status = mkdir (file_name, ~newdir_umask & 0777);
244
245 if (status == 0)
246 {
247 /* Fix ownership. */
248
249 if (we_are_root)
250 if (chown (file_name, current_stat.st_uid, current_stat.st_gid) < 0)
251 ERROR ((0, errno,
252 _("%s: Cannot change owner to uid %lu, gid %lu"),
253 file_name,
254 (unsigned long) current_stat.st_uid,
255 (unsigned long) current_stat.st_gid));
256
257 print_for_mkdir (file_name, cursor - file_name,
258 ~newdir_umask & 0777);
259 did_something = 1;
260
261 *cursor = '/';
262 continue;
263 }
264
265 *cursor = '/';
266
267 if (errno == EEXIST
268 #if MSDOS
269 /* Turbo C mkdir gives a funny errno. */
270 || errno == EACCES
271 #endif
272 )
273 /* Directory already exists. */
274 continue;
275
276 /* Some other error in the mkdir. We return to the caller. */
277 break;
278 }
279
280 errno = saved_errno; /* FIXME: errno should be read-only */
281 return did_something; /* tell them to retry if we made one */
282 }
283
284 /*--------------------------------------------------------------------.
285 | Attempt repairing what went wrong with the extraction. Delete an |
286 | already existing file or create missing intermediate directories. |
287 | Return nonzero if we somewhat increased our chances at a successful |
288 | extraction. errno is properly restored on zero return. |
289 `--------------------------------------------------------------------*/
290
291 static int
292 maybe_recoverable (char *file_name)
293 {
294 switch (errno)
295 {
296 case EEXIST:
297 /* Attempt deleting an existing file. However, with -k, just stay
298 quiet. */
299
300 if (keep_old_files_option)
301 return 0;
302
303 return remove_any_file (file_name, 0);
304
305 case ENOENT:
306 /* Attempt creating missing intermediate directories. */
307
308 return make_directories (file_name);
309
310 default:
311 /* Just say we can't do anything about it... */
312
313 return 0;
314 }
315 }
316
317 /*---.
318 | ? |
319 `---*/
320
321 static void
322 extract_sparse_file (int fd, off_t *sizeleft, off_t totalsize, char *name)
323 {
324 union block *data_block;
325 int sparse_ind = 0;
326 size_t written;
327 ssize_t count;
328
329 /* FIXME: `data_block' might be used uninitialized in this function.
330 Reported by Bruno Haible. */
331
332 /* assuming sizeleft is initially totalsize */
333
334 while (*sizeleft > 0)
335 {
336 data_block = find_next_block ();
337 if (data_block == NULL)
338 {
339 ERROR ((0, 0, _("Unexpected EOF on archive file")));
340 return;
341 }
342 lseek (fd, sparsearray[sparse_ind].offset, 0);
343 written = sparsearray[sparse_ind++].numbytes;
344 while (written > BLOCKSIZE)
345 {
346 count = write (fd, data_block->buffer, BLOCKSIZE);
347 if (count < 0)
348 ERROR ((0, errno, _("%s: Could not write to file"), name));
349 written -= count;
350 *sizeleft -= count;
351 set_next_block_after (data_block);
352 data_block = find_next_block ();
353 }
354
355 count = write (fd, data_block->buffer, written);
356
357 if (count < 0)
358 ERROR ((0, errno, _("%s: Could not write to file"), name));
359 else if (count != written)
360 {
361 char buf1[UINTMAX_STRSIZE_BOUND];
362 char buf2[UINTMAX_STRSIZE_BOUND];
363 ERROR ((0, 0, _("%s: Could only write %s of %s bytes"),
364 name,
365 STRINGIFY_BIGINT (totalsize - *sizeleft, buf1),
366 STRINGIFY_BIGINT (totalsize, buf2)));
367 skip_file (*sizeleft);
368 }
369
370 written -= count;
371 *sizeleft -= count;
372 set_next_block_after (data_block);
373 }
374 free (sparsearray);
375 set_next_block_after (data_block);
376 }
377
378 /*----------------------------------.
379 | Extract a file from the archive. |
380 `----------------------------------*/
381
382 void
383 extract_archive (void)
384 {
385 union block *data_block;
386 int fd;
387 int status;
388 ssize_t sstatus;
389 size_t name_length;
390 size_t written;
391 int openflag;
392 off_t size;
393 int skipcrud;
394 int counter;
395 char typeflag;
396 #if 0
397 int sparse_ind = 0;
398 #endif
399 union block *exhdr;
400 struct delayed_set_stat *data;
401
402 #define CURRENT_FILE_NAME (skipcrud + current_file_name)
403
404 set_next_block_after (current_header);
405 decode_header (current_header, &current_stat, &current_format, 1);
406
407 if (interactive_option && !confirm ("extract", current_file_name))
408 {
409 if (current_header->oldgnu_header.isextended)
410 skip_extended_headers ();
411 skip_file (current_stat.st_size);
412 return;
413 }
414
415 /* Print the block from `current_header' and `current_stat'. */
416
417 if (verbose_option)
418 print_header ();
419
420 /* Check for fully specified file names and other atrocities. */
421
422 skipcrud = 0;
423 while (!absolute_names_option && CURRENT_FILE_NAME[0] == '/')
424 {
425 static int warned_once = 0;
426
427 skipcrud++; /* force relative path */
428 if (!warned_once)
429 {
430 warned_once = 1;
431 WARN ((0, 0, _("\
432 Removing leading `/' from absolute path names in the archive")));
433 }
434 }
435
436 /* Take a safety backup of a previously existing file. */
437
438 if (backup_option && !to_stdout_option)
439 if (!maybe_backup_file (CURRENT_FILE_NAME, 0))
440 {
441 ERROR ((0, errno, _("%s: Was unable to backup this file"),
442 CURRENT_FILE_NAME));
443 if (current_header->oldgnu_header.isextended)
444 skip_extended_headers ();
445 skip_file (current_stat.st_size);
446 return;
447 }
448
449 /* Extract the archive entry according to its type. */
450
451 typeflag = current_header->header.typeflag;
452 switch (typeflag)
453 {
454 /* JK - What we want to do if the file is sparse is loop through
455 the array of sparse structures in the header and read in and
456 translate the character strings representing 1) the offset at
457 which to write and 2) how many bytes to write into numbers,
458 which we store into the scratch array, "sparsearray". This
459 array makes our life easier the same way it did in creating the
460 tar file that had to deal with a sparse file.
461
462 After we read in the first five (at most) sparse structures, we
463 check to see if the file has an extended header, i.e., if more
464 sparse structures are needed to describe the contents of the new
465 file. If so, we read in the extended headers and continue to
466 store their contents into the sparsearray. */
467
468 case GNUTYPE_SPARSE:
469 sp_array_size = 10;
470 sparsearray = (struct sp_array *)
471 xmalloc (sp_array_size * sizeof (struct sp_array));
472
473 for (counter = 0; counter < SPARSES_IN_OLDGNU_HEADER; counter++)
474 {
475 sparsearray[counter].offset =
476 OFF_FROM_OCT (current_header->oldgnu_header.sp[counter].offset);
477 sparsearray[counter].numbytes =
478 SIZE_FROM_OCT (current_header->oldgnu_header.sp[counter].numbytes);
479 if (!sparsearray[counter].numbytes)
480 break;
481 }
482
483 if (current_header->oldgnu_header.isextended)
484 {
485 /* Read in the list of extended headers and translate them
486 into the sparsearray as before. Note that this
487 invalidates current_header. */
488
489 /* static */ int ind = SPARSES_IN_OLDGNU_HEADER;
490
491 while (1)
492 {
493 exhdr = find_next_block ();
494 for (counter = 0; counter < SPARSES_IN_SPARSE_HEADER; counter++)
495 {
496 if (counter + ind > sp_array_size - 1)
497 {
498 /* Realloc the scratch area since we've run out of
499 room. */
500
501 sp_array_size *= 2;
502 sparsearray = (struct sp_array *)
503 xrealloc (sparsearray,
504 sp_array_size * (sizeof (struct sp_array)));
505 }
506 /* Compare to 0, or use !(int)..., for Pyramid's dumb
507 compiler. */
508 if (exhdr->sparse_header.sp[counter].numbytes == 0)
509 break;
510 sparsearray[counter + ind].offset =
511 OFF_FROM_OCT (exhdr->sparse_header.sp[counter].offset);
512 sparsearray[counter + ind].numbytes =
513 SIZE_FROM_OCT (exhdr->sparse_header.sp[counter].numbytes);
514 }
515 if (!exhdr->sparse_header.isextended)
516 break;
517 else
518 {
519 ind += SPARSES_IN_SPARSE_HEADER;
520 set_next_block_after (exhdr);
521 }
522 }
523 set_next_block_after (exhdr);
524 }
525 /* Fall through. */
526
527 case AREGTYPE:
528 case REGTYPE:
529 case CONTTYPE:
530
531 /* Appears to be a file. But BSD tar uses the convention that a slash
532 suffix means a directory. */
533
534 name_length = strlen (CURRENT_FILE_NAME) - 1;
535 if (CURRENT_FILE_NAME[name_length] == '/')
536 goto really_dir;
537
538 /* FIXME: deal with protection issues. */
539
540 again_file:
541 openflag = (keep_old_files_option ?
542 O_BINARY | O_NDELAY | O_WRONLY | O_CREAT | O_EXCL :
543 O_BINARY | O_NDELAY | O_WRONLY | O_CREAT | O_TRUNC)
544 | ((typeflag == GNUTYPE_SPARSE) ? 0 : O_APPEND);
545
546 /* JK - The last | is a kludge to solve the problem the O_APPEND
547 flag causes with files we are trying to make sparse: when a file
548 is opened with O_APPEND, it writes to the last place that
549 something was written, thereby ignoring any lseeks that we have
550 done. We add this extra condition to make it able to lseek when
551 a file is sparse, i.e., we don't open the new file with this
552 flag. (Grump -- this bug caused me to waste a good deal of
553 time, I might add) */
554
555 if (to_stdout_option)
556 {
557 fd = 1;
558 goto extract_file;
559 }
560
561 if (unlink_first_option)
562 remove_any_file (CURRENT_FILE_NAME, recursive_unlink_option);
563
564 #if O_CTG
565 /* Contiguous files (on the Masscomp) have to specify the size in
566 the open call that creates them. */
567
568 if (typeflag == CONTTYPE)
569 fd = open (CURRENT_FILE_NAME, openflag | O_CTG,
570 current_stat.st_mode, current_stat.st_size);
571 else
572 fd = open (CURRENT_FILE_NAME, openflag, current_stat.st_mode);
573
574 #else /* not O_CTG */
575 if (typeflag == CONTTYPE)
576 {
577 static int conttype_diagnosed = 0;
578
579 if (!conttype_diagnosed)
580 {
581 conttype_diagnosed = 1;
582 WARN ((0, 0, _("Extracting contiguous files as regular files")));
583 }
584 }
585 fd = open (CURRENT_FILE_NAME, openflag, current_stat.st_mode);
586
587 #endif /* not O_CTG */
588
589 if (fd < 0)
590 {
591 if (maybe_recoverable (CURRENT_FILE_NAME))
592 goto again_file;
593
594 ERROR ((0, errno, _("%s: Could not create file"),
595 CURRENT_FILE_NAME));
596 if (current_header->oldgnu_header.isextended)
597 skip_extended_headers ();
598 skip_file (current_stat.st_size);
599 if (backup_option)
600 undo_last_backup ();
601 break;
602 }
603
604 extract_file:
605 if (typeflag == GNUTYPE_SPARSE)
606 {
607 char *name;
608 size_t name_length_bis;
609
610 /* Kludge alert. NAME is assigned to header.name because
611 during the extraction, the space that contains the header
612 will get scribbled on, and the name will get munged, so any
613 error messages that happen to contain the filename will look
614 REAL interesting unless we do this. */
615
616 name_length_bis = strlen (CURRENT_FILE_NAME) + 1;
617 name = (char *) xmalloc (name_length_bis);
618 memcpy (name, CURRENT_FILE_NAME, name_length_bis);
619 size = current_stat.st_size;
620 extract_sparse_file (fd, &size, current_stat.st_size, name);
621 }
622 else
623 for (size = current_stat.st_size;
624 size > 0;
625 size -= written)
626 {
627 if (multi_volume_option)
628 {
629 assign_string (&save_name, current_file_name);
630 save_totsize = current_stat.st_size;
631 save_sizeleft = size;
632 }
633
634 /* Locate data, determine max length writeable, write it,
635 block that we have used the data, then check if the write
636 worked. */
637
638 data_block = find_next_block ();
639 if (data_block == NULL)
640 {
641 ERROR ((0, 0, _("Unexpected EOF on archive file")));
642 break; /* FIXME: What happens, then? */
643 }
644
645 /* If the file is sparse, use the sparsearray that we created
646 before to lseek into the new file the proper amount, and to
647 see how many bytes we want to write at that position. */
648
649 #if 0
650 if (typeflag == GNUTYPE_SPARSE)
651 {
652 lseek (fd, sparsearray[sparse_ind].offset, 0);
653 written = sparsearray[sparse_ind++].numbytes;
654 }
655 else
656 #endif
657 written = available_space_after (data_block);
658
659 if (written > size)
660 written = size;
661 errno = 0; /* FIXME: errno should be read-only */
662 sstatus = write (fd, data_block->buffer, written);
663
664 set_next_block_after ((union block *)
665 (data_block->buffer + written - 1));
666 if (sstatus == written)
667 continue;
668
669 /* Error in writing to file. Print it, skip to next file in
670 archive. */
671
672 if (sstatus < 0)
673 ERROR ((0, errno, _("%s: Could not write to file"),
674 CURRENT_FILE_NAME));
675 else
676 ERROR ((0, 0, _("%s: Could only write %lu of %lu bytes"),
677 CURRENT_FILE_NAME,
678 (unsigned long) sstatus,
679 (unsigned long) written));
680 skip_file (size - written);
681 break; /* still do the close, mod time, chmod, etc */
682 }
683
684 if (multi_volume_option)
685 assign_string (&save_name, NULL);
686
687 /* If writing to stdout, don't try to do anything to the filename;
688 it doesn't exist, or we don't want to touch it anyway. */
689
690 if (to_stdout_option)
691 break;
692
693 #if 0
694 if (current_header->header.isextended)
695 {
696 union block *exhdr;
697 int counter;
698
699 for (counter = 0; counter < 21; counter++)
700 {
701 off_t offset;
702
703 if (!exhdr->sparse_header.sp[counter].numbytes)
704 break;
705 offset = OFF_FROM_OCT (exhdr->sparse_header.sp[counter].offset);
706 written
707 = SIZE_FROM_OCT (exhdr->sparse_header.sp[counter].numbytes);
708 lseek (fd, offset, 0);
709 sstatus = write (fd, data_block->buffer, written);
710 if (sstatus == written)
711 continue;
712 }
713 }
714 #endif
715 status = close (fd);
716 if (status < 0)
717 {
718 ERROR ((0, errno, _("%s: Error while closing"), CURRENT_FILE_NAME));
719 if (backup_option)
720 undo_last_backup ();
721 }
722
723 set_stat (CURRENT_FILE_NAME, &current_stat, 0);
724 break;
725
726 case SYMTYPE:
727 if (to_stdout_option)
728 break;
729
730 #ifdef S_ISLNK
731 if (unlink_first_option)
732 remove_any_file (CURRENT_FILE_NAME, recursive_unlink_option);
733
734 while (status = symlink (current_link_name, CURRENT_FILE_NAME),
735 status != 0)
736 if (!maybe_recoverable (CURRENT_FILE_NAME))
737 break;
738
739 if (status == 0)
740
741 /* Setting the attributes of symbolic links might, on some systems,
742 change the pointed to file, instead of the symbolic link itself.
743 At least some of these systems have a lchown call, and the
744 set_stat routine knows about this. */
745
746 set_stat (CURRENT_FILE_NAME, &current_stat, 1);
747
748 else
749 {
750 ERROR ((0, errno, _("%s: Could not create symlink to `%s'"),
751 CURRENT_FILE_NAME, current_link_name));
752 if (backup_option)
753 undo_last_backup ();
754 }
755 break;
756
757 #else /* not S_ISLNK */
758 {
759 static int warned_once = 0;
760
761 if (!warned_once)
762 {
763 warned_once = 1;
764 WARN ((0, 0, _("\
765 Attempting extraction of symbolic links as hard links")));
766 }
767 }
768 /* Fall through. */
769
770 #endif /* not S_ISLNK */
771
772 case LNKTYPE:
773 if (to_stdout_option)
774 break;
775
776 if (unlink_first_option)
777 remove_any_file (CURRENT_FILE_NAME, recursive_unlink_option);
778
779 again_link:
780 {
781 struct stat st1, st2;
782
783 /* MSDOS does not implement links. However, djgpp's link() actually
784 copies the file. */
785 status = link (current_link_name, CURRENT_FILE_NAME);
786
787 if (status == 0)
788 break;
789 if (maybe_recoverable (CURRENT_FILE_NAME))
790 goto again_link;
791
792 if (incremental_option && errno == EEXIST)
793 break;
794 if (stat (current_link_name, &st1) == 0
795 && stat (CURRENT_FILE_NAME, &st2) == 0
796 && st1.st_dev == st2.st_dev
797 && st1.st_ino == st2.st_ino)
798 break;
799
800 ERROR ((0, errno, _("%s: Could not link to `%s'"),
801 CURRENT_FILE_NAME, current_link_name));
802 if (backup_option)
803 undo_last_backup ();
804 }
805 break;
806
807 #if S_IFCHR
808 case CHRTYPE:
809 current_stat.st_mode |= S_IFCHR;
810 goto make_node;
811 #endif
812
813 #if S_IFBLK
814 case BLKTYPE:
815 current_stat.st_mode |= S_IFBLK;
816 #endif
817
818 #if defined(S_IFCHR) || defined(S_IFBLK)
819 make_node:
820 if (to_stdout_option)
821 break;
822
823 if (unlink_first_option)
824 remove_any_file (CURRENT_FILE_NAME, recursive_unlink_option);
825
826 status = mknod (CURRENT_FILE_NAME, current_stat.st_mode,
827 current_stat.st_rdev);
828 if (status != 0)
829 {
830 if (maybe_recoverable (CURRENT_FILE_NAME))
831 goto make_node;
832
833 ERROR ((0, errno, _("%s: Could not make node"), CURRENT_FILE_NAME));
834 if (backup_option)
835 undo_last_backup ();
836 break;
837 };
838 set_stat (CURRENT_FILE_NAME, &current_stat, 0);
839 break;
840 #endif
841
842 #ifdef S_ISFIFO
843 case FIFOTYPE:
844 if (to_stdout_option)
845 break;
846
847 if (unlink_first_option)
848 remove_any_file (CURRENT_FILE_NAME, recursive_unlink_option);
849
850 while (status = mkfifo (CURRENT_FILE_NAME, current_stat.st_mode),
851 status != 0)
852 if (!maybe_recoverable (CURRENT_FILE_NAME))
853 break;
854
855 if (status == 0)
856 set_stat (CURRENT_FILE_NAME, &current_stat, 0);
857 else
858 {
859 ERROR ((0, errno, _("%s: Could not make fifo"), CURRENT_FILE_NAME));
860 if (backup_option)
861 undo_last_backup ();
862 }
863 break;
864 #endif
865
866 case DIRTYPE:
867 case GNUTYPE_DUMPDIR:
868 name_length = strlen (CURRENT_FILE_NAME) - 1;
869
870 really_dir:
871 /* Check for trailing /, and zap as many as we find. */
872 while (name_length && CURRENT_FILE_NAME[name_length] == '/')
873 CURRENT_FILE_NAME[name_length--] = '\0';
874
875 if (incremental_option)
876 {
877 /* Read the entry and delete files that aren't listed in the
878 archive. */
879
880 gnu_restore (skipcrud);
881 }
882 else if (typeflag == GNUTYPE_DUMPDIR)
883 skip_file (current_stat.st_size);
884
885 if (to_stdout_option)
886 break;
887
888 again_dir:
889 status = mkdir (CURRENT_FILE_NAME,
890 (we_are_root ? 0 : 0300) | 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 && 0300 != (0300 & current_stat.st_mode))
944 {
945 current_stat.st_mode |= 0300;
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.073077 seconds and 3 git commands to generate.