]>
Dogcows Code - chaz/tar/blob - 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.
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
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.
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. */
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) */
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
;
46 /* Number of elts storable in the sparsearray. */
47 int sp_array_size
= 10;
50 struct delayed_set_stat
52 struct delayed_set_stat
*next
;
54 struct stat stat_info
;
57 static struct delayed_set_stat
*delayed_set_stat_head
;
59 /*--------------------------.
60 | Set up to extract files. |
61 `--------------------------*/
66 now
= time ((time_t *) 0);
67 we_are_root
= geteuid () == 0;
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. */
73 newdir_umask
= umask (0);
74 if (same_permissions_option
)
78 umask (newdir_umask
); /* restore the kernel umask */
79 current_umask
= newdir_umask
;
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;
87 /*------------------------------------------------------------------.
88 | Restore mode for FILE_NAME, from information given in STAT_INFO. |
89 `------------------------------------------------------------------*/
92 set_mode (char *file_name
, struct stat
*stat_info
)
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.
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. */
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
));
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 `----------------------------------------------------------------------*/
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! */
123 set_stat (char *file_name
, struct stat
*stat_info
, int symlink_flag
)
125 struct utimbuf utimbuf
;
129 /* We do the utime before the chmod because some versions of utime are
130 broken and trash the modes of the file. */
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. */
138 /* FIXME: incremental_option should set ctime too, but how? */
140 if (incremental_option
)
141 utimbuf
.actime
= stat_info
->st_atime
;
143 utimbuf
.actime
= now
;
145 utimbuf
.modtime
= stat_info
->st_mtime
;
147 if (utime (file_name
, &utimbuf
) < 0)
149 _("%s: Could not change access and modification times"),
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. */
157 set_mode (file_name
, stat_info
);
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. */
164 if (we_are_root
|| same_owner_option
)
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. */
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
));
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
));
186 #else /* not HAVE_LCHOWN */
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
));
194 #endif/* not HAVE_LCHOWN */
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. */
202 if (we_are_root
&& (stat_info
->st_mode
& (S_ISUID
| S_ISGID
| S_ISVTX
)))
203 set_mode (file_name
, stat_info
);
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 `-----------------------------------------------------------------------*/
214 make_directories (char *file_name
)
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 */
221 for (cursor
= strchr (file_name
, '/');
223 cursor
= strchr (cursor
+ 1, '/'))
225 /* Avoid mkdir of empty string, if leading or double '/'. */
227 if (cursor
== file_name
|| cursor
[-1] == '/')
230 /* Avoid mkdir where last part of path is '.'. */
232 if (cursor
[-1] == '.' && (cursor
== file_name
+ 1 || cursor
[-2] == '/'))
235 *cursor
= '\0'; /* truncate the path there */
236 status
= mkdir (file_name
, ~newdir_umask
& 0777);
243 if (chown (file_name
, current_stat
.st_uid
, current_stat
.st_gid
) < 0)
245 _("%s: Cannot change owner to uid %d, gid %d"),
246 file_name
, current_stat
.st_uid
, current_stat
.st_gid
));
248 print_for_mkdir (file_name
, cursor
- file_name
,
249 ~newdir_umask
& 0777);
260 /* Turbo C mkdir gives a funny errno. */
264 /* Directory already exists. */
267 /* Some other error in the mkdir. We return to the caller. */
271 errno
= saved_errno
; /* FIXME: errno should be read-only */
272 return did_something
; /* tell them to retry if we made one */
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 `--------------------------------------------------------------------*/
283 maybe_recoverable (char *file_name
)
288 /* Attempt deleting an existing file. However, with -k, just stay
291 if (keep_old_files_option
)
294 return remove_any_file (file_name
, 0);
297 /* Attempt creating missing intermediate directories. */
299 return make_directories (file_name
);
302 /* Just say we can't do anything about it... */
313 extract_sparse_file (int fd
, long *sizeleft
, long totalsize
, char *name
)
315 union block
*data_block
;
319 /* FIXME: `data_block' might be used uninitialized in this function.
320 Reported by Bruno Haible. */
322 /* assuming sizeleft is initially totalsize */
324 while (*sizeleft
> 0)
326 data_block
= find_next_block ();
327 if (data_block
== NULL
)
329 ERROR ((0, 0, _("Unexpected EOF on archive file")));
332 lseek (fd
, sparsearray
[sparse_ind
].offset
, 0);
333 written
= sparsearray
[sparse_ind
++].numbytes
;
334 while (written
> BLOCKSIZE
)
336 count
= write (fd
, data_block
->buffer
, BLOCKSIZE
);
338 ERROR ((0, errno
, _("%s: Could not write to file"), name
));
341 set_next_block_after (data_block
);
342 data_block
= find_next_block ();
345 count
= write (fd
, data_block
->buffer
, (size_t) written
);
348 ERROR ((0, errno
, _("%s: Could not write to file"), name
));
349 else if (count
!= written
)
351 ERROR ((0, 0, _("%s: Could only write %d of %d bytes"),
352 name
, count
, totalsize
));
353 skip_file ((long) (*sizeleft
));
358 set_next_block_after (data_block
);
361 set_next_block_after (data_block
);
364 /*----------------------------------.
365 | Extract a file from the archive. |
366 `----------------------------------*/
369 extract_archive (void)
371 union block
*data_block
;
384 struct delayed_set_stat
*data
;
386 #define CURRENT_FILE_NAME (skipcrud + current_file_name)
388 set_next_block_after (current_header
);
389 decode_header (current_header
, ¤t_stat
, ¤t_format
, 1);
391 if (interactive_option
&& !confirm ("extract", current_file_name
))
393 if (current_header
->oldgnu_header
.isextended
)
394 skip_extended_headers ();
395 skip_file ((long) current_stat
.st_size
);
399 /* Print the block from `current_header' and `current_stat'. */
404 /* Check for fully specified file names and other atrocities. */
407 while (!absolute_names_option
&& CURRENT_FILE_NAME
[0] == '/')
409 static int warned_once
= 0;
411 skipcrud
++; /* force relative path */
416 Removing leading `/' from absolute path names in the archive")));
420 /* Take a safety backup of a previously existing file. */
422 if (backup_option
&& !to_stdout_option
)
423 if (!maybe_backup_file (CURRENT_FILE_NAME
, 0))
425 ERROR ((0, errno
, _("%s: Was unable to backup this file"),
427 if (current_header
->oldgnu_header
.isextended
)
428 skip_extended_headers ();
429 skip_file ((long) current_stat
.st_size
);
433 /* Extract the archive entry according to its type. */
435 switch (current_header
->header
.typeflag
)
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.
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. */
453 sparsearray
= (struct sp_array
*)
454 xmalloc (sp_array_size
* sizeof (struct sp_array
));
456 for (counter
= 0; counter
< SPARSES_IN_OLDGNU_HEADER
; counter
++)
458 sparsearray
[counter
].offset
=
460 current_header
->oldgnu_header
.sp
[counter
].offset
);
461 sparsearray
[counter
].numbytes
=
463 current_header
->oldgnu_header
.sp
[counter
].numbytes
);
464 if (!sparsearray
[counter
].numbytes
)
468 if (current_header
->oldgnu_header
.isextended
)
470 /* Read in the list of extended headers and translate them into
471 the sparsearray as before. */
473 /* static */ int ind
= SPARSES_IN_OLDGNU_HEADER
;
477 exhdr
= find_next_block ();
478 for (counter
= 0; counter
< SPARSES_IN_SPARSE_HEADER
; counter
++)
480 if (counter
+ ind
> sp_array_size
- 1)
482 /* Realloc the scratch area since we've run out of
486 sparsearray
= (struct sp_array
*)
487 xrealloc (sparsearray
,
488 sp_array_size
* (sizeof (struct sp_array
)));
490 /* Compare to 0, or use !(int)..., for Pyramid's dumb
492 if (exhdr
->sparse_header
.sp
[counter
].numbytes
== 0)
494 sparsearray
[counter
+ ind
].offset
=
496 exhdr
->sparse_header
.sp
[counter
].offset
);
497 sparsearray
[counter
+ ind
].numbytes
=
499 exhdr
->sparse_header
.sp
[counter
].numbytes
);
501 if (!exhdr
->sparse_header
.isextended
)
505 ind
+= SPARSES_IN_SPARSE_HEADER
;
506 set_next_block_after (exhdr
);
509 set_next_block_after (exhdr
);
517 /* Appears to be a file. But BSD tar uses the convention that a slash
518 suffix means a directory. */
520 name_length
= strlen (CURRENT_FILE_NAME
) - 1;
521 if (CURRENT_FILE_NAME
[name_length
] == '/')
524 /* FIXME: deal with protection issues. */
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
);
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) */
541 if (to_stdout_option
)
547 if (unlink_first_option
)
548 remove_any_file (CURRENT_FILE_NAME
, recursive_unlink_option
);
551 /* Contiguous files (on the Masscomp) have to specify the size in
552 the open call that creates them. */
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
);
558 fd
= open (CURRENT_FILE_NAME
, openflag
, current_stat
.st_mode
);
560 #else /* not O_CTG */
561 if (current_header
->header
.typeflag
== CONTTYPE
)
563 static int conttype_diagnosed
= 0;
565 if (!conttype_diagnosed
)
567 conttype_diagnosed
= 1;
568 WARN ((0, 0, _("Extracting contiguous files as regular files")));
571 fd
= open (CURRENT_FILE_NAME
, openflag
, current_stat
.st_mode
);
573 #endif /* not O_CTG */
577 if (maybe_recoverable (CURRENT_FILE_NAME
))
580 ERROR ((0, errno
, _("%s: Could not create file"),
582 if (current_header
->oldgnu_header
.isextended
)
583 skip_extended_headers ();
584 skip_file ((long) current_stat
.st_size
);
591 if (current_header
->header
.typeflag
== GNUTYPE_SPARSE
)
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. */
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
);
609 for (size
= current_stat
.st_size
;
614 long offset
, numbytes
;
616 if (multi_volume_option
)
618 assign_string (&save_name
, current_file_name
);
619 save_totsize
= current_stat
.st_size
;
620 save_sizeleft
= size
;
623 /* Locate data, determine max length writeable, write it,
624 block that we have used the data, then check if the write
627 data_block
= find_next_block ();
628 if (data_block
== NULL
)
630 ERROR ((0, 0, _("Unexpected EOF on archive file")));
631 break; /* FIXME: What happens, then? */
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. */
639 if (current_header
->header
.typeflag
== GNUTYPE_SPARSE
)
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
;
649 written
= available_space_after (data_block
);
653 errno
= 0; /* FIXME: errno should be read-only */
654 status
= write (fd
, data_block
->buffer
, (size_t) written
);
656 set_next_block_after ((union block
*)
657 (data_block
->buffer
+ written
- 1));
658 if (status
== written
)
661 /* Error in writing to file. Print it, skip to next file in
665 ERROR ((0, errno
, _("%s: Could not write to file"),
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 */
674 if (multi_volume_option
)
675 assign_string (&save_name
, NULL
);
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. */
680 if (to_stdout_option
)
684 if (current_header
->header
.isextended
)
689 for (counter
= 0; counter
< 21; counter
++)
693 if (!exhdr
->sparse_header
.sp
[counter
].numbytes
)
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
)
707 ERROR ((0, errno
, _("%s: Error while closing"), CURRENT_FILE_NAME
));
712 set_stat (CURRENT_FILE_NAME
, ¤t_stat
, 0);
716 if (to_stdout_option
)
720 if (unlink_first_option
)
721 remove_any_file (CURRENT_FILE_NAME
, recursive_unlink_option
);
723 while (status
= symlink (current_link_name
, CURRENT_FILE_NAME
),
725 if (!maybe_recoverable (CURRENT_FILE_NAME
))
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. */
735 set_stat (CURRENT_FILE_NAME
, ¤t_stat
, 1);
739 ERROR ((0, errno
, _("%s: Could not create symlink to `%s'"),
740 CURRENT_FILE_NAME
, current_link_name
));
746 #else /* not S_ISLNK */
748 static int warned_once
= 0;
754 Attempting extraction of symbolic links as hard links")));
759 #endif /* not S_ISLNK */
762 if (to_stdout_option
)
765 if (unlink_first_option
)
766 remove_any_file (CURRENT_FILE_NAME
, recursive_unlink_option
);
770 struct stat st1
, st2
;
772 /* MSDOS does not implement links. However, djgpp's link() actually
774 status
= link (current_link_name
, CURRENT_FILE_NAME
);
778 if (maybe_recoverable (CURRENT_FILE_NAME
))
781 if (incremental_option
&& errno
== EEXIST
)
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
)
789 ERROR ((0, errno
, _("%s: Could not link to `%s'"),
790 CURRENT_FILE_NAME
, current_link_name
));
798 current_stat
.st_mode
|= S_IFCHR
;
804 current_stat
.st_mode
|= S_IFBLK
;
807 #if defined(S_IFCHR) || defined(S_IFBLK)
809 if (to_stdout_option
)
812 if (unlink_first_option
)
813 remove_any_file (CURRENT_FILE_NAME
, recursive_unlink_option
);
815 status
= mknod (CURRENT_FILE_NAME
, (int) current_stat
.st_mode
,
816 (int) current_stat
.st_rdev
);
819 if (maybe_recoverable (CURRENT_FILE_NAME
))
822 ERROR ((0, errno
, _("%s: Could not make node"), CURRENT_FILE_NAME
));
827 set_stat (CURRENT_FILE_NAME
, ¤t_stat
, 0);
833 if (to_stdout_option
)
836 if (unlink_first_option
)
837 remove_any_file (CURRENT_FILE_NAME
, recursive_unlink_option
);
839 while (status
= mkfifo (CURRENT_FILE_NAME
, (int) current_stat
.st_mode
),
841 if (!maybe_recoverable (CURRENT_FILE_NAME
))
845 set_stat (CURRENT_FILE_NAME
, ¤t_stat
, 0);
848 ERROR ((0, errno
, _("%s: Could not make fifo"), CURRENT_FILE_NAME
));
856 case GNUTYPE_DUMPDIR
:
857 name_length
= strlen (CURRENT_FILE_NAME
) - 1;
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';
864 if (incremental_option
)
866 /* Read the entry and delete files that aren't listed in the
869 gnu_restore (skipcrud
);
871 else if (current_header
->header
.typeflag
== GNUTYPE_DUMPDIR
)
872 skip_file ((long) (current_stat
.st_size
));
874 if (to_stdout_option
)
878 status
= mkdir (CURRENT_FILE_NAME
,
879 (we_are_root
? 0 : 0300) | (int) current_stat
.st_mode
);
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.
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
891 2) Removing the directory might fail if it is not empty. By
892 exception, this real error is traditionally not reported.
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. */
904 int saved_errno
= errno
;
906 if (stat (CURRENT_FILE_NAME
, &st1
) == 0 && S_ISDIR (st1
.st_mode
))
909 errno
= saved_errno
; /* FIXME: errno should be read-only */
912 if (maybe_recoverable (CURRENT_FILE_NAME
))
915 /* If we're trying to create '.', let it be. */
917 /* FIXME: Strange style... */
919 if (CURRENT_FILE_NAME
[name_length
] == '.'
921 || CURRENT_FILE_NAME
[name_length
- 1] == '/'))
924 ERROR ((0, errno
, _("%s: Could not create directory"),
932 if (!we_are_root
&& 0300 != (0300 & (int) current_stat
.st_mode
))
934 current_stat
.st_mode
|= 0300;
935 WARN ((0, 0, _("Added write and execute permission to directory %s"),
940 /* MSDOS does not associate timestamps with directories. In this
941 case, no need to try delaying their restoration. */
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. */
949 set_mode (CURRENT_FILE_NAME
, ¤t_stat
);
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
;
965 fprintf (stdlis
, _("Reading %s\n"), current_file_name
);
972 case GNUTYPE_MULTIVOL
:
974 Cannot extract `%s' -- file is continued from another volume"),
976 skip_file ((long) current_stat
.st_size
);
981 case GNUTYPE_LONGNAME
:
982 case GNUTYPE_LONGLINK
:
983 ERROR ((0, 0, _("Visible long name error")));
984 skip_file ((long) current_stat
.st_size
);
991 _("Unknown file type '%c' for %s, extracted as normal file"),
992 current_header
->header
.typeflag
, CURRENT_FILE_NAME
));
996 #undef CURRENT_FILE_NAME
999 /*----------------------------------------------------------------.
1000 | Set back the utime and mode for all the extracted directories. |
1001 `----------------------------------------------------------------*/
1004 apply_delayed_set_stat (void)
1006 struct delayed_set_stat
*data
;
1008 while (delayed_set_stat_head
!= NULL
)
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
);
This page took 0.089631 seconds and 4 git commands to generate.