diff options
author | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2002-09-25 02:47:48 +0000 |
---|---|---|
committer | bug1 <bug1@69ca8d6d-28ef-0310-b511-8ec308f3f277> | 2002-09-25 02:47:48 +0000 |
commit | d4a48a11220f6a86ee2702c01c986d0a1a0a7bbc (patch) | |
tree | f38c7ef4317eea28c6abdb0adbbb286fe041711e /archival/ar.c | |
parent | d2871e072e3f545a35e07d715f3cf02cf96c011d (diff) | |
download | busybox-w32-d4a48a11220f6a86ee2702c01c986d0a1a0a7bbc.tar.gz busybox-w32-d4a48a11220f6a86ee2702c01c986d0a1a0a7bbc.tar.bz2 busybox-w32-d4a48a11220f6a86ee2702c01c986d0a1a0a7bbc.zip |
New common unarchive code.
git-svn-id: svn://busybox.net/trunk/busybox@5589 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'archival/ar.c')
-rw-r--r-- | archival/ar.c | 123 |
1 files changed, 92 insertions, 31 deletions
diff --git a/archival/ar.c b/archival/ar.c index ac8c41f96..b5fa7956e 100644 --- a/archival/ar.c +++ b/archival/ar.c | |||
@@ -21,41 +21,100 @@ | |||
21 | * along with this program; if not, write to the Free Software | 21 | * along with this program; if not, write to the Free Software |
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 | * | 23 | * |
24 | * There is no signle standard to adhere to so ar may not portable | ||
25 | * between different systems | ||
26 | * http://www.unix-systems.org/single_unix_specification_v2/xcu/ar.html | ||
24 | */ | 27 | */ |
28 | #include <sys/types.h> | ||
25 | #include <fcntl.h> | 29 | #include <fcntl.h> |
30 | #include <fnmatch.h> | ||
26 | #include <stdio.h> | 31 | #include <stdio.h> |
27 | #include <stdlib.h> | 32 | #include <stdlib.h> |
28 | #include <string.h> | 33 | #include <string.h> |
34 | #include <time.h> | ||
35 | #include <utime.h> | ||
36 | #include <unistd.h> | ||
29 | #include <getopt.h> | 37 | #include <getopt.h> |
30 | #include "unarchive.h" | 38 | #include "unarchive.h" |
31 | #include "busybox.h" | 39 | #include "busybox.h" |
32 | 40 | ||
41 | static void header_verbose_list_ar(const file_header_t *file_header) | ||
42 | { | ||
43 | const char *mode = mode_string(file_header->mode); | ||
44 | char *mtime; | ||
45 | |||
46 | mtime = ctime(&file_header->mtime); | ||
47 | mtime[16] = ' '; | ||
48 | memmove(&mtime[17], &mtime[20], 4); | ||
49 | mtime[21] = '\0'; | ||
50 | printf("%s %d/%d%7d %s %s\n", &mode[1], file_header->uid, file_header->gid, (int) file_header->size, &mtime[4], file_header->name); | ||
51 | } | ||
52 | |||
53 | #if defined CONFIG_TAR | defined CONFIG_DPKG_DEB | defined CONFIG_CPIO | ||
54 | /* This is simpler than data_extract_all */ | ||
55 | static void data_extract_regular_file(archive_handle_t *archive_handle) | ||
56 | { | ||
57 | file_header_t *file_header; | ||
58 | int dst_fd; | ||
59 | |||
60 | file_header = archive_handle->file_header; | ||
61 | dst_fd = xopen(file_header->name, O_WRONLY | O_CREAT); | ||
62 | copy_file_chunk_fd(archive_handle->src_fd, dst_fd, file_header->size); | ||
63 | close(dst_fd); | ||
64 | |||
65 | chmod(file_header->name, file_header->mode); | ||
66 | chown(file_header->name, file_header->uid, file_header->gid); | ||
67 | |||
68 | if (archive_handle->flags & ARCHIVE_PRESERVE_DATE) { | ||
69 | struct utimbuf t; | ||
70 | t.actime = t.modtime = file_header->mtime; | ||
71 | utime(file_header->name, &t); | ||
72 | } | ||
73 | |||
74 | return; | ||
75 | } | ||
76 | #endif | ||
77 | |||
33 | extern int ar_main(int argc, char **argv) | 78 | extern int ar_main(int argc, char **argv) |
34 | { | 79 | { |
35 | FILE *src_stream = NULL; | 80 | archive_handle_t *archive_handle; |
36 | char **extract_names = NULL; | ||
37 | char ar_magic[8]; | ||
38 | int extract_function = extract_unconditional; | ||
39 | int opt; | 81 | int opt; |
40 | int num_of_entries = 0; | ||
41 | extern off_t archive_offset; | ||
42 | 82 | ||
43 | while ((opt = getopt(argc, argv, "ovtpx")) != -1) { | 83 | #if defined CONFIG_TAR | defined CONFIG_DPKG_DEB | defined CONFIG_CPIO |
84 | archive_handle = init_handle(); | ||
85 | #else | ||
86 | char magic[8]; | ||
87 | |||
88 | archive_handle = xcalloc(1, sizeof(archive_handle_t)); | ||
89 | archive_handle->filter = filter_accept_all; | ||
90 | archive_handle->action_data = data_skip; | ||
91 | archive_handle->action_header = header_skip; | ||
92 | archive_handle->file_header =xmalloc(sizeof(file_header_t)); | ||
93 | #endif | ||
94 | |||
95 | while ((opt = getopt(argc, argv, "covtpxX")) != -1) { | ||
44 | switch (opt) { | 96 | switch (opt) { |
45 | case 'o': | 97 | case 'p': /* print */ |
46 | extract_function |= extract_preserve_date; | 98 | archive_handle->action_data = data_extract_to_stdout; |
47 | break; | 99 | break; |
48 | case 'v': | 100 | case 't': /* list contents */ |
49 | extract_function |= extract_verbose_list; | 101 | archive_handle->action_header = header_list; |
50 | break; | 102 | break; |
51 | case 't': | 103 | case 'X': |
52 | extract_function |= extract_list; | 104 | archive_handle->action_header = header_verbose_list_ar; |
105 | case 'x': /* extract */ | ||
106 | #if defined CONFIG_TAR | defined CONFIG_DPKG_DEB | defined CONFIG_CPIO | ||
107 | archive_handle->action_data = data_extract_all; | ||
108 | #else | ||
109 | archive_handle->action_data = data_extract_regular_file; | ||
110 | #endif | ||
53 | break; | 111 | break; |
54 | case 'p': | 112 | /* Modifiers */ |
55 | extract_function |= extract_to_stdout; | 113 | case 'o': /* preserve original dates */ |
114 | archive_handle->flags |= ARCHIVE_PRESERVE_DATE; | ||
56 | break; | 115 | break; |
57 | case 'x': | 116 | case 'v': /* verbose */ |
58 | extract_function |= extract_all_to_fs; | 117 | archive_handle->action_header = header_verbose_list_ar; |
59 | break; | 118 | break; |
60 | default: | 119 | default: |
61 | show_usage(); | 120 | show_usage(); |
@@ -67,24 +126,26 @@ extern int ar_main(int argc, char **argv) | |||
67 | show_usage(); | 126 | show_usage(); |
68 | } | 127 | } |
69 | 128 | ||
70 | src_stream = xfopen(argv[optind++], "r"); | 129 | archive_handle->src_fd = xopen(argv[optind++], O_RDONLY); |
71 | 130 | ||
72 | /* check ar magic */ | 131 | /* TODO: This is the same as in tar, seperate function ? */ |
73 | fread(ar_magic, 1, 8, src_stream); | ||
74 | archive_offset = 8; | ||
75 | if (strncmp(ar_magic,"!<arch>",7) != 0) { | ||
76 | error_msg_and_die("invalid magic"); | ||
77 | } | ||
78 | |||
79 | /* Create a list of files to extract */ | ||
80 | while (optind < argc) { | 132 | while (optind < argc) { |
81 | extract_names = xrealloc(extract_names, sizeof(char *) * (num_of_entries + 2)); | 133 | archive_handle->filter = filter_accept_list; |
82 | extract_names[num_of_entries] = xstrdup(argv[optind]); | 134 | archive_handle->accept = add_to_list(archive_handle->accept, argv[optind]); |
83 | num_of_entries++; | ||
84 | extract_names[num_of_entries] = NULL; | ||
85 | optind++; | 135 | optind++; |
86 | } | 136 | } |
87 | 137 | ||
88 | unarchive(src_stream, stdout, &get_header_ar, extract_function, "./", extract_names, NULL); | 138 | #if defined CONFIG_DPKG_DEB |
139 | unpack_ar_archive(archive_handle); | ||
140 | #else | ||
141 | xread_all(archive_handle->src_fd, magic, 7); | ||
142 | if (strncmp(magic, "!<arch>", 7) != 0) { | ||
143 | error_msg_and_die("Invalid ar magic"); | ||
144 | } | ||
145 | archive_handle->offset += 7; | ||
146 | |||
147 | while (get_header_ar(archive_handle) == EXIT_SUCCESS); | ||
148 | #endif | ||
149 | |||
89 | return EXIT_SUCCESS; | 150 | return EXIT_SUCCESS; |
90 | } | 151 | } |