]>
Dogcows Code - chaz/tar/blob - 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.
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 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
33 static int we_are_root
; /* true if our effective uid == 0 */
34 static mode_t newdir_umask
; /* umask when creating new directories */
35 static mode_t current_umask
; /* current umask (which is set to 0 if -p) */
37 struct delayed_set_stat
39 struct delayed_set_stat
*next
;
41 struct stat stat_info
;
44 static struct delayed_set_stat
*delayed_set_stat_head
;
46 /*--------------------------.
47 | Set up to extract files. |
48 `--------------------------*/
53 we_are_root
= geteuid () == 0;
54 same_permissions_option
+= we_are_root
;
55 same_owner_option
+= we_are_root
;
57 /* Option -p clears the kernel umask, so it does not affect proper
58 restoration of file permissions. New intermediate directories will
59 comply with umask at start of program. */
61 newdir_umask
= umask (0);
62 if (0 < same_permissions_option
)
66 umask (newdir_umask
); /* restore the kernel umask */
67 current_umask
= newdir_umask
;
70 /* FIXME: Just make sure we can add files in directories we create. Maybe
71 should we later remove permissions we are adding, here? */
72 newdir_umask
&= ~ MODE_WXUSR
;
75 /*------------------------------------------------------------------.
76 | Restore mode for FILE_NAME, from information given in STAT_INFO. |
77 `------------------------------------------------------------------*/
80 set_mode (char *file_name
, struct stat
*stat_info
)
82 /* Do nothing unless we are restoring the original permissions.
84 We must force permission when -k and -U are not selected, because if the
85 file already existed, open or creat would save the permission bits from
86 the previously created file, ignoring the ones we specified.
88 But with -k or -U selected, we know *we* created this file, so the mode
89 bits were set by our open. If the file has abnormal mode bits, we must
90 chmod since writing or chown has probably reset them. If the file is
91 normal, we merely skip the chmod. This works because we did umask (0)
92 when -p, so umask will have left the specified mode alone. */
94 if (0 < same_permissions_option
95 && ((!keep_old_files_option
&& !unlink_first_option
)
96 || (stat_info
->st_mode
& (S_ISUID
| S_ISGID
| S_ISVTX
))))
97 if (chmod (file_name
, ~current_umask
& stat_info
->st_mode
) < 0)
98 ERROR ((0, errno
, _("%s: Cannot change mode to %04lo"),
100 (unsigned long) (~current_umask
& stat_info
->st_mode
)));
103 /*----------------------------------------------------------------------.
104 | Restore stat attributes (owner, group, mode and times) for FILE_NAME, |
105 | using information given in STAT_INFO. SYMLINK_FLAG is non-zero for a |
106 | freshly restored symbolic link. |
107 `----------------------------------------------------------------------*/
109 /* FIXME: About proper restoration of symbolic link attributes, we still do
110 not have it right. Pretesters' reports tell us we need further study and
111 probably more configuration. For now, just use lchown if it exists, and
112 punt for the rest. Sigh! */
115 set_stat (char *file_name
, struct stat
*stat_info
, int symlink_flag
)
117 struct utimbuf utimbuf
;
121 /* We do the utime before the chmod because some versions of utime are
122 broken and trash the modes of the file. */
126 /* We set the accessed time to `now', which is really the time we
127 started extracting files, unless incremental_option is used, in
128 which case .st_atime is used. */
130 /* FIXME: incremental_option should set ctime too, but how? */
132 if (incremental_option
)
133 utimbuf
.actime
= stat_info
->st_atime
;
135 utimbuf
.actime
= start_time
;
137 utimbuf
.modtime
= stat_info
->st_mtime
;
139 if (utime (file_name
, &utimbuf
) < 0)
141 _("%s: Could not change access and modification times"),
145 /* Some systems allow non-root users to give files away. Once this
146 done, it is not possible anymore to change file permissions, so we
147 have to set permissions prior to possibly giving files away. */
149 set_mode (file_name
, stat_info
);
152 /* If we are root, set the owner and group of the extracted file, so we
153 extract as the original owner. Or else, if we are running as a user,
154 leave the owner and group as they are, so we extract as that user. */
156 if (0 < same_owner_option
)
158 /* When lchown exists, it should be used to change the attributes of
159 the symbolic link itself. In this case, a mere chown would change
160 the attributes of the file the symbolic link is pointing to, and
161 should be avoided. */
166 if (lchown (file_name
, stat_info
->st_uid
, stat_info
->st_gid
) < 0)
167 ERROR ((0, errno
, _("%s: Cannot lchown to uid %lu gid %lu"),
169 (unsigned long) stat_info
->st_uid
,
170 (unsigned long) stat_info
->st_gid
));
175 if (chown (file_name
, stat_info
->st_uid
, stat_info
->st_gid
) < 0)
176 ERROR ((0, errno
, _("%s: Cannot chown to uid %lu gid %lu"),
178 (unsigned long) stat_info
->st_uid
,
179 (unsigned long) stat_info
->st_gid
));
181 /* On a few systems, and in particular, those allowing to give files
182 away, changing the owner or group destroys the suid or sgid bits.
183 So let's attempt setting these bits once more. */
184 if (stat_info
->st_mode
& (S_ISUID
| S_ISGID
| S_ISVTX
))
185 set_mode (file_name
, stat_info
);
190 /*-----------------------------------------------------------------------.
191 | After a file/link/symlink/directory creation has failed, see if it's |
192 | because some required directory was not present, and if so, create all |
193 | required directories. Return non-zero if a directory was created. |
194 `-----------------------------------------------------------------------*/
197 make_directories (char *file_name
)
199 char *cursor
; /* points into path */
200 int did_something
= 0; /* did we do anything yet? */
201 int saved_errno
= errno
; /* remember caller's errno */
204 for (cursor
= strchr (file_name
, '/');
206 cursor
= strchr (cursor
+ 1, '/'))
208 /* Avoid mkdir of empty string, if leading or double '/'. */
210 if (cursor
== file_name
|| cursor
[-1] == '/')
213 /* Avoid mkdir where last part of path is '.'. */
215 if (cursor
[-1] == '.' && (cursor
== file_name
+ 1 || cursor
[-2] == '/'))
218 *cursor
= '\0'; /* truncate the path there */
219 status
= mkdir (file_name
, ~newdir_umask
& MODE_RWX
);
223 print_for_mkdir (file_name
, cursor
- file_name
,
224 ~newdir_umask
& MODE_RWX
);
235 /* Turbo C mkdir gives a funny errno. */
239 /* Directory already exists. */
242 /* Some other error in the mkdir. We return to the caller. */
246 errno
= saved_errno
; /* FIXME: errno should be read-only */
247 return did_something
; /* tell them to retry if we made one */
250 /*--------------------------------------------------------------------.
251 | Unlink the destination, if we are supposed to do so. |
252 | Return zero if extraction should not proceed. |
253 `--------------------------------------------------------------------*/
256 unlink_destination (char const *file_name
)
258 if (unlink_first_option
259 && !remove_any_file (file_name
, recursive_unlink_option
)
262 ERROR ((0, errno
, _("Cannot remove %s"), file_name
));
269 /*--------------------------------------------------------------------.
270 | Attempt repairing what went wrong with the extraction. Delete an |
271 | already existing file or create missing intermediate directories. |
272 | Return nonzero if we somewhat increased our chances at a successful |
273 | extraction. errno is properly restored on zero return. |
274 `--------------------------------------------------------------------*/
277 maybe_recoverable (char *file_name
)
282 /* Attempt deleting an existing file. However, with -k or -U, just stay
285 if (keep_old_files_option
|| unlink_first_option
)
288 return remove_any_file (file_name
, 0);
291 /* Attempt creating missing intermediate directories. */
293 return make_directories (file_name
);
296 /* Just say we can't do anything about it... */
307 extract_sparse_file (int fd
, off_t
*sizeleft
, off_t totalsize
, char *name
)
313 /* assuming sizeleft is initially totalsize */
315 while (*sizeleft
> 0)
317 union block
*data_block
= find_next_block ();
320 ERROR ((0, 0, _("Unexpected EOF on archive file")));
323 if (lseek (fd
, sparsearray
[sparse_ind
].offset
, SEEK_SET
) < 0)
325 char buf
[UINTMAX_STRSIZE_BOUND
];
326 ERROR ((0, errno
, _("%s: lseek error at byte %s"),
327 STRINGIFY_BIGINT (sparsearray
[sparse_ind
].offset
, buf
),
331 written
= sparsearray
[sparse_ind
++].numbytes
;
332 while (written
> BLOCKSIZE
)
334 count
= full_write (fd
, data_block
->buffer
, BLOCKSIZE
);
336 ERROR ((0, errno
, _("%s: Could not write to file"), name
));
339 set_next_block_after (data_block
);
340 data_block
= find_next_block ();
343 ERROR ((0, 0, _("Unexpected EOF on archive file")));
348 count
= full_write (fd
, data_block
->buffer
, written
);
351 ERROR ((0, errno
, _("%s: Could not write to file"), name
));
352 else if (count
!= written
)
354 char buf1
[UINTMAX_STRSIZE_BOUND
];
355 char buf2
[UINTMAX_STRSIZE_BOUND
];
356 ERROR ((0, 0, _("%s: Could only write %s of %s bytes"),
358 STRINGIFY_BIGINT (totalsize
- *sizeleft
, buf1
),
359 STRINGIFY_BIGINT (totalsize
, buf2
)));
360 skip_file (*sizeleft
);
365 set_next_block_after (data_block
);
371 /*----------------------------------.
372 | Extract a file from the archive. |
373 `----------------------------------*/
376 extract_archive (void)
378 union block
*data_block
;
393 struct delayed_set_stat
*data
;
395 #define CURRENT_FILE_NAME (skipcrud + current_file_name)
397 set_next_block_after (current_header
);
398 decode_header (current_header
, ¤t_stat
, ¤t_format
, 1);
400 if (interactive_option
&& !confirm ("extract", current_file_name
))
402 if (current_header
->oldgnu_header
.isextended
)
403 skip_extended_headers ();
404 skip_file (current_stat
.st_size
);
408 /* Print the block from `current_header' and `current_stat'. */
413 /* Check for fully specified file names and other atrocities. */
416 while (!absolute_names_option
&& CURRENT_FILE_NAME
[0] == '/')
418 static int warned_once
;
423 WARN ((0, 0, _("Removing leading `/' from archive names")));
425 skipcrud
++; /* force relative path */
428 /* Take a safety backup of a previously existing file. */
430 if (backup_option
&& !to_stdout_option
)
431 if (!maybe_backup_file (CURRENT_FILE_NAME
, 0))
433 ERROR ((0, errno
, _("%s: Was unable to backup this file"),
435 if (current_header
->oldgnu_header
.isextended
)
436 skip_extended_headers ();
437 skip_file (current_stat
.st_size
);
441 /* Extract the archive entry according to its type. */
443 typeflag
= current_header
->header
.typeflag
;
446 /* JK - What we want to do if the file is sparse is loop through
447 the array of sparse structures in the header and read in and
448 translate the character strings representing 1) the offset at
449 which to write and 2) how many bytes to write into numbers,
450 which we store into the scratch array, "sparsearray". This
451 array makes our life easier the same way it did in creating the
452 tar file that had to deal with a sparse file.
454 After we read in the first five (at most) sparse structures, we
455 check to see if the file has an extended header, i.e., if more
456 sparse structures are needed to describe the contents of the new
457 file. If so, we read in the extended headers and continue to
458 store their contents into the sparsearray. */
463 xmalloc (sp_array_size
* sizeof (struct sp_array
));
465 for (counter
= 0; counter
< SPARSES_IN_OLDGNU_HEADER
; counter
++)
467 struct sparse
const *s
= ¤t_header
->oldgnu_header
.sp
[counter
];
468 sparsearray
[counter
].offset
= OFF_FROM_HEADER (s
->offset
);
469 sparsearray
[counter
].numbytes
= SIZE_FROM_HEADER (s
->numbytes
);
470 if (!sparsearray
[counter
].numbytes
)
474 if (current_header
->oldgnu_header
.isextended
)
476 /* Read in the list of extended headers and translate them
477 into the sparsearray as before. Note that this
478 invalidates current_header. */
480 /* static */ int ind
= SPARSES_IN_OLDGNU_HEADER
;
484 exhdr
= find_next_block ();
487 ERROR ((0, 0, _("Unexpected EOF on archive file")));
490 for (counter
= 0; counter
< SPARSES_IN_SPARSE_HEADER
; counter
++)
492 struct sparse
const *s
= &exhdr
->sparse_header
.sp
[counter
];
493 if (counter
+ ind
> sp_array_size
- 1)
495 /* Realloc the scratch area since we've run out of
500 xrealloc (sparsearray
,
501 sp_array_size
* sizeof (struct sp_array
));
503 if (s
->numbytes
[0] == 0)
505 sparsearray
[counter
+ ind
].offset
=
506 OFF_FROM_HEADER (s
->offset
);
507 sparsearray
[counter
+ ind
].numbytes
=
508 SIZE_FROM_HEADER (s
->numbytes
);
510 if (!exhdr
->sparse_header
.isextended
)
514 ind
+= SPARSES_IN_SPARSE_HEADER
;
515 set_next_block_after (exhdr
);
518 set_next_block_after (exhdr
);
526 /* Appears to be a file. But BSD tar uses the convention that a slash
527 suffix means a directory. */
529 name_length
= strlen (CURRENT_FILE_NAME
) - 1;
530 if (CURRENT_FILE_NAME
[name_length
] == '/')
533 /* FIXME: deal with protection issues. */
536 openflag
= (keep_old_files_option
|| unlink_first_option
?
537 O_WRONLY
| O_BINARY
| O_NONBLOCK
| O_CREAT
| O_EXCL
:
538 O_WRONLY
| O_BINARY
| O_NONBLOCK
| O_CREAT
| O_TRUNC
)
539 | ((typeflag
== GNUTYPE_SPARSE
) ? 0 : O_APPEND
);
541 /* JK - The last | is a kludge to solve the problem the O_APPEND
542 flag causes with files we are trying to make sparse: when a file
543 is opened with O_APPEND, it writes to the last place that
544 something was written, thereby ignoring any lseeks that we have
545 done. We add this extra condition to make it able to lseek when
546 a file is sparse, i.e., we don't open the new file with this
547 flag. (Grump -- this bug caused me to waste a good deal of
548 time, I might add) */
550 if (to_stdout_option
)
556 if (!unlink_destination (CURRENT_FILE_NAME
))
558 if (current_header
->oldgnu_header
.isextended
)
559 skip_extended_headers ();
560 skip_file (current_stat
.st_size
);
567 /* Contiguous files (on the Masscomp) have to specify the size in
568 the open call that creates them. */
570 if (typeflag
== CONTTYPE
)
571 fd
= open (CURRENT_FILE_NAME
, openflag
| O_CTG
,
572 current_stat
.st_mode
, current_stat
.st_size
);
574 fd
= open (CURRENT_FILE_NAME
, openflag
, current_stat
.st_mode
);
576 #else /* not O_CTG */
577 if (typeflag
== CONTTYPE
)
579 static int conttype_diagnosed
;
581 if (!conttype_diagnosed
)
583 conttype_diagnosed
= 1;
584 WARN ((0, 0, _("Extracting contiguous files as regular files")));
587 fd
= open (CURRENT_FILE_NAME
, openflag
, current_stat
.st_mode
);
589 #endif /* not O_CTG */
593 if (maybe_recoverable (CURRENT_FILE_NAME
))
596 ERROR ((0, errno
, _("%s: Could not create file"),
598 if (current_header
->oldgnu_header
.isextended
)
599 skip_extended_headers ();
600 skip_file (current_stat
.st_size
);
607 if (typeflag
== GNUTYPE_SPARSE
)
610 size_t name_length_bis
;
612 /* Kludge alert. NAME is assigned to header.name because
613 during the extraction, the space that contains the header
614 will get scribbled on, and the name will get munged, so any
615 error messages that happen to contain the filename will look
616 REAL interesting unless we do this. */
618 name_length_bis
= strlen (CURRENT_FILE_NAME
) + 1;
619 name
= xmalloc (name_length_bis
);
620 memcpy (name
, CURRENT_FILE_NAME
, name_length_bis
);
621 size
= current_stat
.st_size
;
622 extract_sparse_file (fd
, &size
, current_stat
.st_size
, name
);
625 for (size
= current_stat
.st_size
;
629 if (multi_volume_option
)
631 assign_string (&save_name
, current_file_name
);
632 save_totsize
= current_stat
.st_size
;
633 save_sizeleft
= size
;
636 /* Locate data, determine max length writeable, write it,
637 block that we have used the data, then check if the write
640 data_block
= find_next_block ();
643 ERROR ((0, 0, _("Unexpected EOF on archive file")));
644 break; /* FIXME: What happens, then? */
647 written
= available_space_after (data_block
);
651 errno
= 0; /* FIXME: errno should be read-only */
652 sstatus
= full_write (fd
, data_block
->buffer
, written
);
654 set_next_block_after ((union block
*)
655 (data_block
->buffer
+ written
- 1));
656 if (sstatus
== written
)
659 /* Error in writing to file. Print it, skip to next file in
663 ERROR ((0, errno
, _("%s: Could not write to file"),
666 ERROR ((0, 0, _("%s: Could only write %lu of %lu bytes"),
668 (unsigned long) sstatus
,
669 (unsigned long) written
));
670 skip_file (size
- written
);
671 break; /* still do the close, mod time, chmod, etc */
674 if (multi_volume_option
)
675 assign_string (&save_name
, 0);
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
)
686 ERROR ((0, errno
, _("%s: Error while closing"), CURRENT_FILE_NAME
));
691 set_stat (CURRENT_FILE_NAME
, ¤t_stat
, 0);
695 if (to_stdout_option
)
699 if (!unlink_destination (CURRENT_FILE_NAME
))
702 while (status
= symlink (current_link_name
, CURRENT_FILE_NAME
),
704 if (!maybe_recoverable (CURRENT_FILE_NAME
))
709 /* Setting the attributes of symbolic links might, on some systems,
710 change the pointed to file, instead of the symbolic link itself.
711 At least some of these systems have a lchown call, and the
712 set_stat routine knows about this. */
714 set_stat (CURRENT_FILE_NAME
, ¤t_stat
, 1);
718 ERROR ((0, errno
, _("%s: Could not create symlink to `%s'"),
719 CURRENT_FILE_NAME
, current_link_name
));
727 static int warned_once
;
733 _("Attempting extraction of symbolic links as hard links")));
741 if (to_stdout_option
)
744 if (!unlink_destination (CURRENT_FILE_NAME
))
749 struct stat st1
, st2
;
751 /* MSDOS does not implement links. However, djgpp's link() actually
753 status
= link (current_link_name
, CURRENT_FILE_NAME
);
757 if (maybe_recoverable (CURRENT_FILE_NAME
))
760 if (incremental_option
&& errno
== EEXIST
)
762 if (stat (current_link_name
, &st1
) == 0
763 && stat (CURRENT_FILE_NAME
, &st2
) == 0
764 && st1
.st_dev
== st2
.st_dev
765 && st1
.st_ino
== st2
.st_ino
)
768 ERROR ((0, errno
, _("%s: Could not link to `%s'"),
769 CURRENT_FILE_NAME
, current_link_name
));
777 current_stat
.st_mode
|= S_IFCHR
;
783 current_stat
.st_mode
|= S_IFBLK
;
786 #if S_IFCHR || S_IFBLK
788 if (to_stdout_option
)
791 if (!unlink_destination (CURRENT_FILE_NAME
))
794 status
= mknod (CURRENT_FILE_NAME
, current_stat
.st_mode
,
795 current_stat
.st_rdev
);
798 if (maybe_recoverable (CURRENT_FILE_NAME
))
801 ERROR ((0, errno
, _("%s: Could not make node"), CURRENT_FILE_NAME
));
806 set_stat (CURRENT_FILE_NAME
, ¤t_stat
, 0);
810 #if HAVE_MKFIFO || defined mkfifo
812 if (to_stdout_option
)
815 if (!unlink_destination (CURRENT_FILE_NAME
))
818 while (status
= mkfifo (CURRENT_FILE_NAME
, current_stat
.st_mode
),
820 if (!maybe_recoverable (CURRENT_FILE_NAME
))
824 set_stat (CURRENT_FILE_NAME
, ¤t_stat
, 0);
827 ERROR ((0, errno
, _("%s: Could not make fifo"), CURRENT_FILE_NAME
));
835 case GNUTYPE_DUMPDIR
:
836 name_length
= strlen (CURRENT_FILE_NAME
) - 1;
839 /* Check for trailing /, and zap as many as we find. */
840 while (name_length
&& CURRENT_FILE_NAME
[name_length
] == '/')
841 CURRENT_FILE_NAME
[name_length
--] = '\0';
843 if (incremental_option
)
845 /* Read the entry and delete files that aren't listed in the
848 gnu_restore (skipcrud
);
850 else if (typeflag
== GNUTYPE_DUMPDIR
)
851 skip_file (current_stat
.st_size
);
853 if (to_stdout_option
)
857 status
= mkdir (CURRENT_FILE_NAME
,
858 ((we_are_root
? 0 : MODE_WXUSR
)
859 | current_stat
.st_mode
));
862 /* If the directory creation fails, let's consider immediately the
863 case where the directory already exists. We have three good
864 reasons for clearing out this case before attempting recovery.
866 1) It would not be efficient recovering the error by deleting
867 the directory in maybe_recoverable, then recreating it right
868 away. We only hope we will be able to adjust its permissions
871 2) Removing the directory might fail if it is not empty. By
872 exception, this real error is traditionally not reported.
874 3) Let's suppose `DIR' already exists and we are about to
875 extract `DIR/../DIR'. This would fail because the directory
876 already exists, and maybe_recoverable would react by removing
877 `DIR'. This then would fail again because there are missing
878 intermediate directories, and maybe_recoverable would react by
879 creating `DIR'. We would then have an extraction loop. */
884 int saved_errno
= errno
;
886 if (stat (CURRENT_FILE_NAME
, &st1
) == 0 && S_ISDIR (st1
.st_mode
))
889 errno
= saved_errno
; /* FIXME: errno should be read-only */
892 if (maybe_recoverable (CURRENT_FILE_NAME
))
895 /* If we're trying to create '.', let it be. */
897 /* FIXME: Strange style... */
899 if (CURRENT_FILE_NAME
[name_length
] == '.'
901 || CURRENT_FILE_NAME
[name_length
- 1] == '/'))
904 ERROR ((0, errno
, _("%s: Could not create directory"),
912 if (!we_are_root
&& MODE_WXUSR
!= (MODE_WXUSR
& current_stat
.st_mode
))
914 current_stat
.st_mode
|= MODE_WXUSR
;
915 WARN ((0, 0, _("Added write and execute permission to directory %s"),
920 /* MSDOS does not associate time stamps with directories. In this
921 case, no need to try delaying their restoration. */
925 /* FIXME: I do not believe in this. Ignoring time stamps does not
926 alleviate the need of delaying the restoration of directories'
927 mode. Let's ponder this for a little while. */
929 set_mode (CURRENT_FILE_NAME
, ¤t_stat
);
933 data
= xmalloc (sizeof (struct delayed_set_stat
));
934 data
->file_name
= xstrdup (CURRENT_FILE_NAME
);
935 data
->stat_info
= current_stat
;
936 data
->next
= delayed_set_stat_head
;
937 delayed_set_stat_head
= data
;
944 fprintf (stdlis
, _("Reading %s\n"), current_file_name
);
951 case GNUTYPE_MULTIVOL
:
953 _("Cannot extract `%s' -- file is continued from another volume"),
955 skip_file (current_stat
.st_size
);
960 case GNUTYPE_LONGNAME
:
961 case GNUTYPE_LONGLINK
:
962 ERROR ((0, 0, _("Visible long name error")));
963 skip_file (current_stat
.st_size
);
970 _("Unknown file type '%c' for %s, extracted as normal file"),
971 typeflag
, CURRENT_FILE_NAME
));
975 #undef CURRENT_FILE_NAME
978 /*----------------------------------------------------------------.
979 | Set back the utime and mode for all the extracted directories. |
980 `----------------------------------------------------------------*/
983 apply_delayed_set_stat (void)
985 struct delayed_set_stat
*data
;
987 while (delayed_set_stat_head
)
989 data
= delayed_set_stat_head
;
990 delayed_set_stat_head
= delayed_set_stat_head
->next
;
991 set_stat (data
->file_name
, &data
->stat_info
, 0);
992 free (data
->file_name
);
This page took 0.076838 seconds and 4 git commands to generate.