]> Dogcows Code - chaz/tar/blob - src/extract.c
(set_stat): chmod after chown even when not root; if we are using
[chaz/tar] / src / extract.c
1 /* Extract files from a tar archive.
2 Copyright (C) 1988, 92, 93, 94, 96, 97 Free Software Foundation, Inc.
3 Written by John Gilmore, on 1985-11-19.
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 2, or (at your option) any later
8 version.
9
10 This program is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13 Public License for more details.
14
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 59 Place - Suite 330, Boston, MA 02111-1307, USA. */
18
19 #include "system.h"
20
21 #include <time.h>
22 time_t time ();
23
24 #if HAVE_UTIME_H
25 # include <utime.h>
26 #else
27 struct utimbuf
28 {
29 long actime;
30 long modtime;
31 };
32 #endif
33
34 #include "common.h"
35
36 static time_t now; /* current time */
37 static int we_are_root; /* true if our effective uid == 0 */
38 static 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 #if 0
396 int sparse_ind = 0;
397 #endif
398 union block *exhdr;
399 struct delayed_set_stat *data;
400
401 #define CURRENT_FILE_NAME (skipcrud + current_file_name)
402
403 set_next_block_after (current_header);
404 decode_header (current_header, &current_stat, &current_format, 1);
405
406 if (interactive_option && !confirm ("extract", current_file_name))
407 {
408 if (current_header->oldgnu_header.isextended)
409 skip_extended_headers ();
410 skip_file (current_stat.st_size);
411 return;
412 }
413
414 /* Print the block from `current_header' and `current_stat'. */
415
416 if (verbose_option)
417 print_header ();
418
419 /* Check for fully specified file names and other atrocities. */
420
421 skipcrud = 0;
422 while (!absolute_names_option && CURRENT_FILE_NAME[0] == '/')
423 {
424 static int warned_once = 0;
425
426 skipcrud++; /* force relative path */
427 if (!warned_once)
428 {
429 warned_once = 1;
430 WARN ((0, 0, _("\
431 Removing leading `/' from absolute path names in the archive")));
432 }
433 }
434
435 /* Take a safety backup of a previously existing file. */
436
437 if (backup_option && !to_stdout_option)
438 if (!maybe_backup_file (CURRENT_FILE_NAME, 0))
439 {
440 ERROR ((0, errno, _("%s: Was unable to backup this file"),
441 CURRENT_FILE_NAME));
442 if (current_header->oldgnu_header.isextended)
443 skip_extended_headers ();
444 skip_file (current_stat.st_size);
445 return;
446 }
447
448 /* Extract the archive entry according to its type. */
449
450 switch (current_header->header.typeflag)
451 {
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.
459
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. */
465
466 case GNUTYPE_SPARSE:
467 sp_array_size = 10;
468 sparsearray = (struct sp_array *)
469 xmalloc (sp_array_size * sizeof (struct sp_array));
470
471 for (counter = 0; counter < SPARSES_IN_OLDGNU_HEADER; counter++)
472 {
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)
478 break;
479 }
480
481 if (current_header->oldgnu_header.isextended)
482 {
483 /* Read in the list of extended headers and translate them into
484 the sparsearray as before. */
485
486 /* static */ int ind = SPARSES_IN_OLDGNU_HEADER;
487
488 while (1)
489 {
490 exhdr = find_next_block ();
491 for (counter = 0; counter < SPARSES_IN_SPARSE_HEADER; counter++)
492 {
493 if (counter + ind > sp_array_size - 1)
494 {
495 /* Realloc the scratch area since we've run out of
496 room. */
497
498 sp_array_size *= 2;
499 sparsearray = (struct sp_array *)
500 xrealloc (sparsearray,
501 sp_array_size * (sizeof (struct sp_array)));
502 }
503 /* Compare to 0, or use !(int)..., for Pyramid's dumb
504 compiler. */
505 if (exhdr->sparse_header.sp[counter].numbytes == 0)
506 break;
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);
511 }
512 if (!exhdr->sparse_header.isextended)
513 break;
514 else
515 {
516 ind += SPARSES_IN_SPARSE_HEADER;
517 set_next_block_after (exhdr);
518 }
519 }
520 set_next_block_after (exhdr);
521 }
522 /* Fall through. */
523
524 case AREGTYPE:
525 case REGTYPE:
526 case CONTTYPE:
527
528 /* Appears to be a file. But BSD tar uses the convention that a slash
529 suffix means a directory. */
530
531 name_length = strlen (CURRENT_FILE_NAME) - 1;
532 if (CURRENT_FILE_NAME[name_length] == '/')
533 goto really_dir;
534
535 /* FIXME: deal with protection issues. */
536
537 again_file:
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);
542
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) */
551
552 if (to_stdout_option)
553 {
554 fd = 1;
555 goto extract_file;
556 }
557
558 if (unlink_first_option)
559 remove_any_file (CURRENT_FILE_NAME, recursive_unlink_option);
560
561 #if O_CTG
562 /* Contiguous files (on the Masscomp) have to specify the size in
563 the open call that creates them. */
564
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);
568 else
569 fd = open (CURRENT_FILE_NAME, openflag, current_stat.st_mode);
570
571 #else /* not O_CTG */
572 if (current_header->header.typeflag == CONTTYPE)
573 {
574 static int conttype_diagnosed = 0;
575
576 if (!conttype_diagnosed)
577 {
578 conttype_diagnosed = 1;
579 WARN ((0, 0, _("Extracting contiguous files as regular files")));
580 }
581 }
582 fd = open (CURRENT_FILE_NAME, openflag, current_stat.st_mode);
583
584 #endif /* not O_CTG */
585
586 if (fd < 0)
587 {
588 if (maybe_recoverable (CURRENT_FILE_NAME))
589 goto again_file;
590
591 ERROR ((0, errno, _("%s: Could not create file"),
592 CURRENT_FILE_NAME));
593 if (current_header->oldgnu_header.isextended)
594 skip_extended_headers ();
595 skip_file (current_stat.st_size);
596 if (backup_option)
597 undo_last_backup ();
598 break;
599 }
600
601 extract_file:
602 if (current_header->header.typeflag == GNUTYPE_SPARSE)
603 {
604 char *name;
605 size_t name_length_bis;
606
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. */
612
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);
618 }
619 else
620 for (size = current_stat.st_size;
621 size > 0;
622 size -= written)
623 {
624 if (multi_volume_option)
625 {
626 assign_string (&save_name, current_file_name);
627 save_totsize = current_stat.st_size;
628 save_sizeleft = size;
629 }
630
631 /* Locate data, determine max length writeable, write it,
632 block that we have used the data, then check if the write
633 worked. */
634
635 data_block = find_next_block ();
636 if (data_block == NULL)
637 {
638 ERROR ((0, 0, _("Unexpected EOF on archive file")));
639 break; /* FIXME: What happens, then? */
640 }
641
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. */
645
646 #if 0
647 if (current_header->header.typeflag == GNUTYPE_SPARSE)
648 {
649 lseek (fd, sparsearray[sparse_ind].offset, 0);
650 written = sparsearray[sparse_ind++].numbytes;
651 }
652 else
653 #endif
654 written = available_space_after (data_block);
655
656 if (written > size)
657 written = size;
658 errno = 0; /* FIXME: errno should be read-only */
659 sstatus = write (fd, data_block->buffer, written);
660
661 set_next_block_after ((union block *)
662 (data_block->buffer + written - 1));
663 if (sstatus == written)
664 continue;
665
666 /* Error in writing to file. Print it, skip to next file in
667 archive. */
668
669 if (sstatus < 0)
670 ERROR ((0, errno, _("%s: Could not write to file"),
671 CURRENT_FILE_NAME));
672 else
673 ERROR ((0, 0, _("%s: Could only write %lu of %lu bytes"),
674 CURRENT_FILE_NAME,
675 (unsigned long) sstatus,
676 (unsigned long) written));
677 skip_file (size - written);
678 break; /* still do the close, mod time, chmod, etc */
679 }
680
681 if (multi_volume_option)
682 assign_string (&save_name, NULL);
683
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. */
686
687 if (to_stdout_option)
688 break;
689
690 #if 0
691 if (current_header->header.isextended)
692 {
693 union block *exhdr;
694 int counter;
695
696 for (counter = 0; counter < 21; counter++)
697 {
698 off_t offset;
699
700 if (!exhdr->sparse_header.sp[counter].numbytes)
701 break;
702 offset = OFF_FROM_OCT (exhdr->sparse_header.sp[counter].offset);
703 written
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)
708 continue;
709 }
710 }
711 #endif
712 status = close (fd);
713 if (status < 0)
714 {
715 ERROR ((0, errno, _("%s: Error while closing"), CURRENT_FILE_NAME));
716 if (backup_option)
717 undo_last_backup ();
718 }
719
720 set_stat (CURRENT_FILE_NAME, &current_stat, 0);
721 break;
722
723 case SYMTYPE:
724 if (to_stdout_option)
725 break;
726
727 #ifdef S_ISLNK
728 if (unlink_first_option)
729 remove_any_file (CURRENT_FILE_NAME, recursive_unlink_option);
730
731 while (status = symlink (current_link_name, CURRENT_FILE_NAME),
732 status != 0)
733 if (!maybe_recoverable (CURRENT_FILE_NAME))
734 break;
735
736 if (status == 0)
737
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. */
742
743 set_stat (CURRENT_FILE_NAME, &current_stat, 1);
744
745 else
746 {
747 ERROR ((0, errno, _("%s: Could not create symlink to `%s'"),
748 CURRENT_FILE_NAME, current_link_name));
749 if (backup_option)
750 undo_last_backup ();
751 }
752 break;
753
754 #else /* not S_ISLNK */
755 {
756 static int warned_once = 0;
757
758 if (!warned_once)
759 {
760 warned_once = 1;
761 WARN ((0, 0, _("\
762 Attempting extraction of symbolic links as hard links")));
763 }
764 }
765 /* Fall through. */
766
767 #endif /* not S_ISLNK */
768
769 case LNKTYPE:
770 if (to_stdout_option)
771 break;
772
773 if (unlink_first_option)
774 remove_any_file (CURRENT_FILE_NAME, recursive_unlink_option);
775
776 again_link:
777 {
778 struct stat st1, st2;
779
780 /* MSDOS does not implement links. However, djgpp's link() actually
781 copies the file. */
782 status = link (current_link_name, CURRENT_FILE_NAME);
783
784 if (status == 0)
785 break;
786 if (maybe_recoverable (CURRENT_FILE_NAME))
787 goto again_link;
788
789 if (incremental_option && errno == EEXIST)
790 break;
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)
795 break;
796
797 ERROR ((0, errno, _("%s: Could not link to `%s'"),
798 CURRENT_FILE_NAME, current_link_name));
799 if (backup_option)
800 undo_last_backup ();
801 }
802 break;
803
804 #if S_IFCHR
805 case CHRTYPE:
806 current_stat.st_mode |= S_IFCHR;
807 goto make_node;
808 #endif
809
810 #if S_IFBLK
811 case BLKTYPE:
812 current_stat.st_mode |= S_IFBLK;
813 #endif
814
815 #if defined(S_IFCHR) || defined(S_IFBLK)
816 make_node:
817 if (to_stdout_option)
818 break;
819
820 if (unlink_first_option)
821 remove_any_file (CURRENT_FILE_NAME, recursive_unlink_option);
822
823 status = mknod (CURRENT_FILE_NAME, current_stat.st_mode,
824 current_stat.st_rdev);
825 if (status != 0)
826 {
827 if (maybe_recoverable (CURRENT_FILE_NAME))
828 goto make_node;
829
830 ERROR ((0, errno, _("%s: Could not make node"), CURRENT_FILE_NAME));
831 if (backup_option)
832 undo_last_backup ();
833 break;
834 };
835 set_stat (CURRENT_FILE_NAME, &current_stat, 0);
836 break;
837 #endif
838
839 #ifdef S_ISFIFO
840 case FIFOTYPE:
841 if (to_stdout_option)
842 break;
843
844 if (unlink_first_option)
845 remove_any_file (CURRENT_FILE_NAME, recursive_unlink_option);
846
847 while (status = mkfifo (CURRENT_FILE_NAME, current_stat.st_mode),
848 status != 0)
849 if (!maybe_recoverable (CURRENT_FILE_NAME))
850 break;
851
852 if (status == 0)
853 set_stat (CURRENT_FILE_NAME, &current_stat, 0);
854 else
855 {
856 ERROR ((0, errno, _("%s: Could not make fifo"), CURRENT_FILE_NAME));
857 if (backup_option)
858 undo_last_backup ();
859 }
860 break;
861 #endif
862
863 case DIRTYPE:
864 case GNUTYPE_DUMPDIR:
865 name_length = strlen (CURRENT_FILE_NAME) - 1;
866
867 really_dir:
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';
871
872 if (incremental_option)
873 {
874 /* Read the entry and delete files that aren't listed in the
875 archive. */
876
877 gnu_restore (skipcrud);
878 }
879 else if (current_header->header.typeflag == GNUTYPE_DUMPDIR)
880 skip_file (current_stat.st_size);
881
882 if (to_stdout_option)
883 break;
884
885 again_dir:
886 status = mkdir (CURRENT_FILE_NAME,
887 (we_are_root ? 0 : 0300) | current_stat.st_mode);
888 if (status != 0)
889 {
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.
893
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
897 adequately, later.
898
899 2) Removing the directory might fail if it is not empty. By
900 exception, this real error is traditionally not reported.
901
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. */
908
909 if (errno == EEXIST)
910 {
911 struct stat st1;
912 int saved_errno = errno;
913
914 if (stat (CURRENT_FILE_NAME, &st1) == 0 && S_ISDIR (st1.st_mode))
915 goto check_perms;
916
917 errno = saved_errno; /* FIXME: errno should be read-only */
918 }
919
920 if (maybe_recoverable (CURRENT_FILE_NAME))
921 goto again_dir;
922
923 /* If we're trying to create '.', let it be. */
924
925 /* FIXME: Strange style... */
926
927 if (CURRENT_FILE_NAME[name_length] == '.'
928 && (name_length == 0
929 || CURRENT_FILE_NAME[name_length - 1] == '/'))
930 goto check_perms;
931
932 ERROR ((0, errno, _("%s: Could not create directory"),
933 CURRENT_FILE_NAME));
934 if (backup_option)
935 undo_last_backup ();
936 break;
937 }
938
939 check_perms:
940 if (!we_are_root && 0300 != (0300 & current_stat.st_mode))
941 {
942 current_stat.st_mode |= 0300;
943 WARN ((0, 0, _("Added write and execute permission to directory %s"),
944 CURRENT_FILE_NAME));
945 }
946
947 #if !MSDOS
948 /* MSDOS does not associate timestamps with directories. In this
949 case, no need to try delaying their restoration. */
950
951 if (touch_option)
952
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. */
956
957 set_mode (CURRENT_FILE_NAME, &current_stat);
958
959 else
960 {
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;
967 }
968 #endif /* !MSDOS */
969 break;
970
971 case GNUTYPE_VOLHDR:
972 if (verbose_option)
973 fprintf (stdlis, _("Reading %s\n"), current_file_name);
974 break;
975
976 case GNUTYPE_NAMES:
977 extract_mangle ();
978 break;
979
980 case GNUTYPE_MULTIVOL:
981 ERROR ((0, 0, _("\
982 Cannot extract `%s' -- file is continued from another volume"),
983 current_file_name));
984 skip_file (current_stat.st_size);
985 if (backup_option)
986 undo_last_backup ();
987 break;
988
989 case GNUTYPE_LONGNAME:
990 case GNUTYPE_LONGLINK:
991 ERROR ((0, 0, _("Visible long name error")));
992 skip_file (current_stat.st_size);
993 if (backup_option)
994 undo_last_backup ();
995 break;
996
997 default:
998 WARN ((0, 0,
999 _("Unknown file type '%c' for %s, extracted as normal file"),
1000 current_header->header.typeflag, CURRENT_FILE_NAME));
1001 goto again_file;
1002 }
1003
1004 #undef CURRENT_FILE_NAME
1005 }
1006
1007 /*----------------------------------------------------------------.
1008 | Set back the utime and mode for all the extracted directories. |
1009 `----------------------------------------------------------------*/
1010
1011 void
1012 apply_delayed_set_stat (void)
1013 {
1014 struct delayed_set_stat *data;
1015
1016 while (delayed_set_stat_head != NULL)
1017 {
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);
1022 free (data);
1023 }
1024 }
This page took 0.081391 seconds and 5 git commands to generate.