Annotation of /trunk/mkinitrd-magellan/busybox/archival/libunarchive/data_extract_all.c
Parent Directory | Revision Log
Revision 532 -
(hide annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 3444 byte(s)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File MIME type: text/plain
File size: 3444 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd
1 | niro | 532 | /* vi: set sw=4 ts=4: */ |
2 | /* | ||
3 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. | ||
4 | */ | ||
5 | |||
6 | #include "libbb.h" | ||
7 | #include "unarchive.h" | ||
8 | |||
9 | void data_extract_all(archive_handle_t *archive_handle) | ||
10 | { | ||
11 | file_header_t *file_header = archive_handle->file_header; | ||
12 | int dst_fd; | ||
13 | int res; | ||
14 | |||
15 | if (archive_handle->flags & ARCHIVE_CREATE_LEADING_DIRS) { | ||
16 | char *name = xstrdup(file_header->name); | ||
17 | bb_make_directory(dirname(name), -1, FILEUTILS_RECUR); | ||
18 | free(name); | ||
19 | } | ||
20 | |||
21 | /* Check if the file already exists */ | ||
22 | if (archive_handle->flags & ARCHIVE_EXTRACT_UNCONDITIONAL) { | ||
23 | /* Remove the existing entry if it exists */ | ||
24 | if (((file_header->mode & S_IFMT) != S_IFDIR) | ||
25 | && (unlink(file_header->name) == -1) | ||
26 | && (errno != ENOENT) | ||
27 | ) { | ||
28 | bb_perror_msg_and_die("cannot remove old file"); | ||
29 | } | ||
30 | } | ||
31 | else if (archive_handle->flags & ARCHIVE_EXTRACT_NEWER) { | ||
32 | /* Remove the existing entry if its older than the extracted entry */ | ||
33 | struct stat statbuf; | ||
34 | if (lstat(file_header->name, &statbuf) == -1) { | ||
35 | if (errno != ENOENT) { | ||
36 | bb_perror_msg_and_die("cannot stat old file"); | ||
37 | } | ||
38 | } | ||
39 | else if (statbuf.st_mtime <= file_header->mtime) { | ||
40 | if (!(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { | ||
41 | bb_error_msg("%s not created: newer or " | ||
42 | "same age file exists", file_header->name); | ||
43 | } | ||
44 | data_skip(archive_handle); | ||
45 | return; | ||
46 | } | ||
47 | else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) { | ||
48 | bb_perror_msg_and_die("cannot remove old file %s", | ||
49 | file_header->name); | ||
50 | } | ||
51 | } | ||
52 | |||
53 | /* Handle hard links separately | ||
54 | * We identified hard links as regular files of size 0 with a symlink */ | ||
55 | if (S_ISREG(file_header->mode) && (file_header->link_name) | ||
56 | && (file_header->size == 0) | ||
57 | ) { | ||
58 | /* hard link */ | ||
59 | res = link(file_header->link_name, file_header->name); | ||
60 | if ((res == -1) && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET)) { | ||
61 | bb_perror_msg("cannot create hard link"); | ||
62 | } | ||
63 | } else { | ||
64 | /* Create the filesystem entry */ | ||
65 | switch (file_header->mode & S_IFMT) { | ||
66 | case S_IFREG: { | ||
67 | /* Regular file */ | ||
68 | dst_fd = xopen3(file_header->name, O_WRONLY | O_CREAT | O_EXCL, | ||
69 | file_header->mode); | ||
70 | bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size); | ||
71 | close(dst_fd); | ||
72 | break; | ||
73 | } | ||
74 | case S_IFDIR: | ||
75 | res = mkdir(file_header->name, file_header->mode); | ||
76 | if ((errno != EISDIR) && (res == -1) | ||
77 | && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET) | ||
78 | ) { | ||
79 | bb_perror_msg("extract_archive: %s", file_header->name); | ||
80 | } | ||
81 | break; | ||
82 | case S_IFLNK: | ||
83 | /* Symlink */ | ||
84 | res = symlink(file_header->link_name, file_header->name); | ||
85 | if ((res == -1) | ||
86 | && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET) | ||
87 | ) { | ||
88 | bb_perror_msg("cannot create symlink " | ||
89 | "from %s to '%s'", | ||
90 | file_header->name, | ||
91 | file_header->link_name); | ||
92 | } | ||
93 | break; | ||
94 | case S_IFSOCK: | ||
95 | case S_IFBLK: | ||
96 | case S_IFCHR: | ||
97 | case S_IFIFO: | ||
98 | res = mknod(file_header->name, file_header->mode, file_header->device); | ||
99 | if ((res == -1) | ||
100 | && !(archive_handle->flags & ARCHIVE_EXTRACT_QUIET) | ||
101 | ) { | ||
102 | bb_perror_msg("cannot create node %s", file_header->name); | ||
103 | } | ||
104 | break; | ||
105 | default: | ||
106 | bb_error_msg_and_die("unrecognized file type"); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | if (!(archive_handle->flags & ARCHIVE_NOPRESERVE_OWN)) { | ||
111 | lchown(file_header->name, file_header->uid, file_header->gid); | ||
112 | } | ||
113 | |||
114 | if (archive_handle->flags & ARCHIVE_PRESERVE_DATE) { | ||
115 | struct utimbuf t; | ||
116 | t.actime = t.modtime = file_header->mtime; | ||
117 | utime(file_header->name, &t); | ||
118 | } | ||
119 | } |