]>
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 mode_t newdir_umask
; /* umask when creating new directories */
39 static mode_t 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
& stat_info
->st_mode
) < 0)
107 ERROR ((0, errno
, _("%s: Cannot change mode to %0.4lo"),
109 (unsigned long) (~current_umask
& stat_info
->st_mode
)));
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 `----------------------------------------------------------------------*/
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! */
124 set_stat (char *file_name
, struct stat
*stat_info
, int symlink_flag
)
126 struct utimbuf utimbuf
;
130 /* We do the utime before the chmod because some versions of utime are
131 broken and trash the modes of the file. */
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. */
139 /* FIXME: incremental_option should set ctime too, but how? */
141 if (incremental_option
)
142 utimbuf
.actime
= stat_info
->st_atime
;
144 utimbuf
.actime
= now
;
146 utimbuf
.modtime
= stat_info
->st_mtime
;
148 if (utime (file_name
, &utimbuf
) < 0)
150 _("%s: Could not change access and modification times"),
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. */
158 set_mode (file_name
, stat_info
);
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. */
165 if (we_are_root
|| same_owner_option
)
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. */
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"),
179 (unsigned long) stat_info
->st_uid
,
180 (unsigned long) stat_info
->st_gid
));
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"),
187 (unsigned long) stat_info
->st_uid
,
188 (unsigned long) stat_info
->st_gid
));
191 #else /* not HAVE_LCHOWN */
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"),
198 (unsigned long) stat_info
->st_uid
,
199 (unsigned long) stat_info
->st_gid
));
201 #endif/* not HAVE_LCHOWN */
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. */
209 if (stat_info
->st_mode
& (S_ISUID
| S_ISGID
| S_ISVTX
))
210 set_mode (file_name
, stat_info
);
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 `-----------------------------------------------------------------------*/
221 make_directories (char *file_name
)
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 */
228 for (cursor
= strchr (file_name
, '/');
230 cursor
= strchr (cursor
+ 1, '/'))
232 /* Avoid mkdir of empty string, if leading or double '/'. */
234 if (cursor
== file_name
|| cursor
[-1] == '/')
237 /* Avoid mkdir where last part of path is '.'. */
239 if (cursor
[-1] == '.' && (cursor
== file_name
+ 1 || cursor
[-2] == '/'))
242 *cursor
= '\0'; /* truncate the path there */
243 status
= mkdir (file_name
, ~newdir_umask
& 0777);
250 if (chown (file_name
, current_stat
.st_uid
, current_stat
.st_gid
) < 0)
252 _("%s: Cannot change owner to uid %lu, gid %lu"),
254 (unsigned long) current_stat
.st_uid
,
255 (unsigned long) current_stat
.st_gid
));
257 print_for_mkdir (file_name
, cursor
- file_name
,
258 ~newdir_umask
& 0777);
269 /* Turbo C mkdir gives a funny errno. */
273 /* Directory already exists. */
276 /* Some other error in the mkdir. We return to the caller. */
280 errno
= saved_errno
; /* FIXME: errno should be read-only */
281 return did_something
; /* tell them to retry if we made one */
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 `--------------------------------------------------------------------*/
292 maybe_recoverable (char *file_name
)
297 /* Attempt deleting an existing file. However, with -k, just stay
300 if (keep_old_files_option
)
303 return remove_any_file (file_name
, 0);
306 /* Attempt creating missing intermediate directories. */
308 return make_directories (file_name
);
311 /* Just say we can't do anything about it... */
322 extract_sparse_file (int fd
, off_t
*sizeleft
, off_t totalsize
, char *name
)
324 union block
*data_block
;
329 /* FIXME: `data_block' might be used uninitialized in this function.
330 Reported by Bruno Haible. */
332 /* assuming sizeleft is initially totalsize */
334 while (*sizeleft
> 0)
336 data_block
= find_next_block ();
337 if (data_block
== NULL
)
339 ERROR ((0, 0, _("Unexpected EOF on archive file")));
342 lseek (fd
, sparsearray
[sparse_ind
].offset
, 0);
343 written
= sparsearray
[sparse_ind
++].numbytes
;
344 while (written
> BLOCKSIZE
)
346 count
= write (fd
, data_block
->buffer
, BLOCKSIZE
);
348 ERROR ((0, errno
, _("%s: Could not write to file"), name
));
351 set_next_block_after (data_block
);
352 data_block
= find_next_block ();
355 count
= write (fd
, data_block
->buffer
, written
);
358 ERROR ((0, errno
, _("%s: Could not write to file"), name
));
359 else if (count
!= written
)
361 char buf1
[UINTMAX_STRSIZE_BOUND
];
362 char buf2
[UINTMAX_STRSIZE_BOUND
];
363 ERROR ((0, 0, _("%s: Could only write %s of %s bytes"),
365 STRINGIFY_BIGINT (totalsize
- *sizeleft
, buf1
),
366 STRINGIFY_BIGINT (totalsize
, buf2
)));
367 skip_file (*sizeleft
);
372 set_next_block_after (data_block
);
375 set_next_block_after (data_block
);
378 /*----------------------------------.
379 | Extract a file from the archive. |
380 `----------------------------------*/
383 extract_archive (void)
385 union block
*data_block
;
399 struct delayed_set_stat
*data
;
401 #define CURRENT_FILE_NAME (skipcrud + current_file_name)
403 set_next_block_after (current_header
);
404 decode_header (current_header
, ¤t_stat
, ¤t_format
, 1);
406 if (interactive_option
&& !confirm ("extract", current_file_name
))
408 if (current_header
->oldgnu_header
.isextended
)
409 skip_extended_headers ();
410 skip_file (current_stat
.st_size
);
414 /* Print the block from `current_header' and `current_stat'. */
419 /* Check for fully specified file names and other atrocities. */
422 while (!absolute_names_option
&& CURRENT_FILE_NAME
[0] == '/')
424 static int warned_once
= 0;
426 skipcrud
++; /* force relative path */
431 Removing leading `/' from absolute path names in the archive")));
435 /* Take a safety backup of a previously existing file. */
437 if (backup_option
&& !to_stdout_option
)
438 if (!maybe_backup_file (CURRENT_FILE_NAME
, 0))
440 ERROR ((0, errno
, _("%s: Was unable to backup this file"),
442 if (current_header
->oldgnu_header
.isextended
)
443 skip_extended_headers ();
444 skip_file (current_stat
.st_size
);
448 /* Extract the archive entry according to its type. */
450 switch (current_header
->header
.typeflag
)
452 /* JK - What we want to do if the file is sparse is loop through
453 the array of sparse structures in the header and read in and
454 translate the character strings representing 1) the offset at
455 which to write and 2) how many bytes to write into numbers,
456 which we store into the scratch array, "sparsearray". This
457 array makes our life easier the same way it did in creating the
458 tar file that had to deal with a sparse file.
460 After we read in the first five (at most) sparse structures, we
461 check to see if the file has an extended header, i.e., if more
462 sparse structures are needed to describe the contents of the new
463 file. If so, we read in the extended headers and continue to
464 store their contents into the sparsearray. */
468 sparsearray
= (struct sp_array
*)
469 xmalloc (sp_array_size
* sizeof (struct sp_array
));
471 for (counter
= 0; counter
< SPARSES_IN_OLDGNU_HEADER
; counter
++)
473 sparsearray
[counter
].offset
=
474 OFF_FROM_OCT (current_header
->oldgnu_header
.sp
[counter
].offset
);
475 sparsearray
[counter
].numbytes
=
476 SIZE_FROM_OCT (current_header
->oldgnu_header
.sp
[counter
].numbytes
);
477 if (!sparsearray
[counter
].numbytes
)
481 if (current_header
->oldgnu_header
.isextended
)
483 /* Read in the list of extended headers and translate them into
484 the sparsearray as before. */
486 /* static */ int ind
= SPARSES_IN_OLDGNU_HEADER
;
490 exhdr
= find_next_block ();
491 for (counter
= 0; counter
< SPARSES_IN_SPARSE_HEADER
; counter
++)
493 if (counter
+ ind
> sp_array_size
- 1)
495 /* Realloc the scratch area since we've run out of
499 sparsearray
= (struct sp_array
*)
500 xrealloc (sparsearray
,
501 sp_array_size
* (sizeof (struct sp_array
)));
503 /* Compare to 0, or use !(int)..., for Pyramid's dumb
505 if (exhdr
->sparse_header
.sp
[counter
].numbytes
== 0)
507 sparsearray
[counter
+ ind
].offset
=
508 OFF_FROM_OCT (exhdr
->sparse_header
.sp
[counter
].offset
);
509 sparsearray
[counter
+ ind
].numbytes
=
510 SIZE_FROM_OCT (exhdr
->sparse_header
.sp
[counter
].numbytes
);
512 if (!exhdr
->sparse_header
.isextended
)
516 ind
+= SPARSES_IN_SPARSE_HEADER
;
517 set_next_block_after (exhdr
);
520 set_next_block_after (exhdr
);
528 /* Appears to be a file. But BSD tar uses the convention that a slash
529 suffix means a directory. */
531 name_length
= strlen (CURRENT_FILE_NAME
) - 1;
532 if (CURRENT_FILE_NAME
[name_length
] == '/')
535 /* FIXME: deal with protection issues. */
538 openflag
= (keep_old_files_option
?
539 O_BINARY
| O_NDELAY
| O_WRONLY
| O_CREAT
| O_EXCL
:
540 O_BINARY
| O_NDELAY
| O_WRONLY
| O_CREAT
| O_TRUNC
)
541 | ((current_header
->header
.typeflag
== GNUTYPE_SPARSE
) ? 0 : O_APPEND
);
543 /* JK - The last | is a kludge to solve the problem the O_APPEND
544 flag causes with files we are trying to make sparse: when a file
545 is opened with O_APPEND, it writes to the last place that
546 something was written, thereby ignoring any lseeks that we have
547 done. We add this extra condition to make it able to lseek when
548 a file is sparse, i.e., we don't open the new file with this
549 flag. (Grump -- this bug caused me to waste a good deal of
550 time, I might add) */
552 if (to_stdout_option
)
558 if (unlink_first_option
)
559 remove_any_file (CURRENT_FILE_NAME
, recursive_unlink_option
);
562 /* Contiguous files (on the Masscomp) have to specify the size in
563 the open call that creates them. */
565 if (current_header
->header
.typeflag
== CONTTYPE
)
566 fd
= open (CURRENT_FILE_NAME
, openflag
| O_CTG
,
567 current_stat
.st_mode
, current_stat
.st_size
);
569 fd
= open (CURRENT_FILE_NAME
, openflag
, current_stat
.st_mode
);
571 #else /* not O_CTG */
572 if (current_header
->header
.typeflag
== CONTTYPE
)
574 static int conttype_diagnosed
= 0;
576 if (!conttype_diagnosed
)
578 conttype_diagnosed
= 1;
579 WARN ((0, 0, _("Extracting contiguous files as regular files")));
582 fd
= open (CURRENT_FILE_NAME
, openflag
, current_stat
.st_mode
);
584 #endif /* not O_CTG */
588 if (maybe_recoverable (CURRENT_FILE_NAME
))
591 ERROR ((0, errno
, _("%s: Could not create file"),
593 if (current_header
->oldgnu_header
.isextended
)
594 skip_extended_headers ();
595 skip_file (current_stat
.st_size
);
602 if (current_header
->header
.typeflag
== GNUTYPE_SPARSE
)
605 size_t name_length_bis
;
607 /* Kludge alert. NAME is assigned to header.name because
608 during the extraction, the space that contains the header
609 will get scribbled on, and the name will get munged, so any
610 error messages that happen to contain the filename will look
611 REAL interesting unless we do this. */
613 name_length_bis
= strlen (CURRENT_FILE_NAME
) + 1;
614 name
= (char *) xmalloc (name_length_bis
);
615 memcpy (name
, CURRENT_FILE_NAME
, name_length_bis
);
616 size
= current_stat
.st_size
;
617 extract_sparse_file (fd
, &size
, current_stat
.st_size
, name
);
620 for (size
= current_stat
.st_size
;
624 if (multi_volume_option
)
626 assign_string (&save_name
, current_file_name
);
627 save_totsize
= current_stat
.st_size
;
628 save_sizeleft
= size
;
631 /* Locate data, determine max length writeable, write it,
632 block that we have used the data, then check if the write
635 data_block
= find_next_block ();
636 if (data_block
== NULL
)
638 ERROR ((0, 0, _("Unexpected EOF on archive file")));
639 break; /* FIXME: What happens, then? */
642 /* If the file is sparse, use the sparsearray that we created
643 before to lseek into the new file the proper amount, and to
644 see how many bytes we want to write at that position. */
647 if (current_header
->header
.typeflag
== GNUTYPE_SPARSE
)
649 lseek (fd
, sparsearray
[sparse_ind
].offset
, 0);
650 written
= sparsearray
[sparse_ind
++].numbytes
;
654 written
= available_space_after (data_block
);
658 errno
= 0; /* FIXME: errno should be read-only */
659 sstatus
= write (fd
, data_block
->buffer
, written
);
661 set_next_block_after ((union block
*)
662 (data_block
->buffer
+ written
- 1));
663 if (sstatus
== written
)
666 /* Error in writing to file. Print it, skip to next file in
670 ERROR ((0, errno
, _("%s: Could not write to file"),
673 ERROR ((0, 0, _("%s: Could only write %lu of %lu bytes"),
675 (unsigned long) sstatus
,
676 (unsigned long) written
));
677 skip_file (size
- written
);
678 break; /* still do the close, mod time, chmod, etc */
681 if (multi_volume_option
)
682 assign_string (&save_name
, NULL
);
684 /* If writing to stdout, don't try to do anything to the filename;
685 it doesn't exist, or we don't want to touch it anyway. */
687 if (to_stdout_option
)
691 if (current_header
->header
.isextended
)
696 for (counter
= 0; counter
< 21; counter
++)
700 if (!exhdr
->sparse_header
.sp
[counter
].numbytes
)
702 offset
= OFF_FROM_OCT (exhdr
->sparse_header
.sp
[counter
].offset
);
704 = SIZE_FROM_OCT (exhdr
->sparse_header
.sp
[counter
].numbytes
);
705 lseek (fd
, offset
, 0);
706 sstatus
= write (fd
, data_block
->buffer
, written
);
707 if (sstatus
== written
)
715 ERROR ((0, errno
, _("%s: Error while closing"), CURRENT_FILE_NAME
));
720 set_stat (CURRENT_FILE_NAME
, ¤t_stat
, 0);
724 if (to_stdout_option
)
728 if (unlink_first_option
)
729 remove_any_file (CURRENT_FILE_NAME
, recursive_unlink_option
);
731 while (status
= symlink (current_link_name
, CURRENT_FILE_NAME
),
733 if (!maybe_recoverable (CURRENT_FILE_NAME
))
738 /* Setting the attributes of symbolic links might, on some systems,
739 change the pointed to file, instead of the symbolic link itself.
740 At least some of these systems have a lchown call, and the
741 set_stat routine knows about this. */
743 set_stat (CURRENT_FILE_NAME
, ¤t_stat
, 1);
747 ERROR ((0, errno
, _("%s: Could not create symlink to `%s'"),
748 CURRENT_FILE_NAME
, current_link_name
));
754 #else /* not S_ISLNK */
756 static int warned_once
= 0;
762 Attempting extraction of symbolic links as hard links")));
767 #endif /* not S_ISLNK */
770 if (to_stdout_option
)
773 if (unlink_first_option
)
774 remove_any_file (CURRENT_FILE_NAME
, recursive_unlink_option
);
778 struct stat st1
, st2
;
780 /* MSDOS does not implement links. However, djgpp's link() actually
782 status
= link (current_link_name
, CURRENT_FILE_NAME
);
786 if (maybe_recoverable (CURRENT_FILE_NAME
))
789 if (incremental_option
&& errno
== EEXIST
)
791 if (stat (current_link_name
, &st1
) == 0
792 && stat (CURRENT_FILE_NAME
, &st2
) == 0
793 && st1
.st_dev
== st2
.st_dev
794 && st1
.st_ino
== st2
.st_ino
)
797 ERROR ((0, errno
, _("%s: Could not link to `%s'"),
798 CURRENT_FILE_NAME
, current_link_name
));
806 current_stat
.st_mode
|= S_IFCHR
;
812 current_stat
.st_mode
|= S_IFBLK
;
815 #if defined(S_IFCHR) || defined(S_IFBLK)
817 if (to_stdout_option
)
820 if (unlink_first_option
)
821 remove_any_file (CURRENT_FILE_NAME
, recursive_unlink_option
);
823 status
= mknod (CURRENT_FILE_NAME
, current_stat
.st_mode
,
824 current_stat
.st_rdev
);
827 if (maybe_recoverable (CURRENT_FILE_NAME
))
830 ERROR ((0, errno
, _("%s: Could not make node"), CURRENT_FILE_NAME
));
835 set_stat (CURRENT_FILE_NAME
, ¤t_stat
, 0);
841 if (to_stdout_option
)
844 if (unlink_first_option
)
845 remove_any_file (CURRENT_FILE_NAME
, recursive_unlink_option
);
847 while (status
= mkfifo (CURRENT_FILE_NAME
, current_stat
.st_mode
),
849 if (!maybe_recoverable (CURRENT_FILE_NAME
))
853 set_stat (CURRENT_FILE_NAME
, ¤t_stat
, 0);
856 ERROR ((0, errno
, _("%s: Could not make fifo"), CURRENT_FILE_NAME
));
864 case GNUTYPE_DUMPDIR
:
865 name_length
= strlen (CURRENT_FILE_NAME
) - 1;
868 /* Check for trailing /, and zap as many as we find. */
869 while (name_length
&& CURRENT_FILE_NAME
[name_length
] == '/')
870 CURRENT_FILE_NAME
[name_length
--] = '\0';
872 if (incremental_option
)
874 /* Read the entry and delete files that aren't listed in the
877 gnu_restore (skipcrud
);
879 else if (current_header
->header
.typeflag
== GNUTYPE_DUMPDIR
)
880 skip_file (current_stat
.st_size
);
882 if (to_stdout_option
)
886 status
= mkdir (CURRENT_FILE_NAME
,
887 (we_are_root
? 0 : 0300) | current_stat
.st_mode
);
890 /* If the directory creation fails, let's consider immediately the
891 case where the directory already exists. We have three good
892 reasons for clearing out this case before attempting recovery.
894 1) It would not be efficient recovering the error by deleting
895 the directory in maybe_recoverable, then recreating it right
896 away. We only hope we will be able to adjust its permissions
899 2) Removing the directory might fail if it is not empty. By
900 exception, this real error is traditionally not reported.
902 3) Let's suppose `DIR' already exists and we are about to
903 extract `DIR/../DIR'. This would fail because the directory
904 already exists, and maybe_recoverable would react by removing
905 `DIR'. This then would fail again because there are missing
906 intermediate directories, and maybe_recoverable would react by
907 creating `DIR'. We would then have an extraction loop. */
912 int saved_errno
= errno
;
914 if (stat (CURRENT_FILE_NAME
, &st1
) == 0 && S_ISDIR (st1
.st_mode
))
917 errno
= saved_errno
; /* FIXME: errno should be read-only */
920 if (maybe_recoverable (CURRENT_FILE_NAME
))
923 /* If we're trying to create '.', let it be. */
925 /* FIXME: Strange style... */
927 if (CURRENT_FILE_NAME
[name_length
] == '.'
929 || CURRENT_FILE_NAME
[name_length
- 1] == '/'))
932 ERROR ((0, errno
, _("%s: Could not create directory"),
940 if (!we_are_root
&& 0300 != (0300 & current_stat
.st_mode
))
942 current_stat
.st_mode
|= 0300;
943 WARN ((0, 0, _("Added write and execute permission to directory %s"),
948 /* MSDOS does not associate timestamps with directories. In this
949 case, no need to try delaying their restoration. */
953 /* FIXME: I do not believe in this. Ignoring time stamps does not
954 alleviate the need of delaying the restoration of directories'
955 mode. Let's ponder this for a little while. */
957 set_mode (CURRENT_FILE_NAME
, ¤t_stat
);
961 data
= ((struct delayed_set_stat
*)
962 xmalloc (sizeof (struct delayed_set_stat
)));
963 data
->file_name
= xstrdup (CURRENT_FILE_NAME
);
964 data
->stat_info
= current_stat
;
965 data
->next
= delayed_set_stat_head
;
966 delayed_set_stat_head
= data
;
973 fprintf (stdlis
, _("Reading %s\n"), current_file_name
);
980 case GNUTYPE_MULTIVOL
:
982 Cannot extract `%s' -- file is continued from another volume"),
984 skip_file (current_stat
.st_size
);
989 case GNUTYPE_LONGNAME
:
990 case GNUTYPE_LONGLINK
:
991 ERROR ((0, 0, _("Visible long name error")));
992 skip_file (current_stat
.st_size
);
999 _("Unknown file type '%c' for %s, extracted as normal file"),
1000 current_header
->header
.typeflag
, CURRENT_FILE_NAME
));
1004 #undef CURRENT_FILE_NAME
1007 /*----------------------------------------------------------------.
1008 | Set back the utime and mode for all the extracted directories. |
1009 `----------------------------------------------------------------*/
1012 apply_delayed_set_stat (void)
1014 struct delayed_set_stat
*data
;
1016 while (delayed_set_stat_head
!= NULL
)
1018 data
= delayed_set_stat_head
;
1019 delayed_set_stat_head
= delayed_set_stat_head
->next
;
1020 set_stat (data
->file_name
, &data
->stat_info
, 0);
1021 free (data
->file_name
);
This page took 0.087905 seconds and 4 git commands to generate.