Contents of /trunk/mkinitrd-magellan/busybox/archival/libunarchive/data_extract_all.c
Parent Directory | Revision Log
Revision 532 -
(show annotations)
(download)
Sat Sep 1 22:45:15 2007 UTC (17 years ago) by niro
File MIME type: text/plain
File size: 3444 byte(s)
Sat Sep 1 22:45:15 2007 UTC (17 years 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 | /* 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 | } |