aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn L McGrath <bug1@ihug.co.nz>2004-01-04 10:28:22 +0000
committerGlenn L McGrath <bug1@ihug.co.nz>2004-01-04 10:28:22 +0000
commit930453bdcf27bdb4f51d3f4060ebd368aad18c56 (patch)
treee6b99f01b030a2d92c100d945f60a76180a8391c
parent40ec4aeb8e26199a076627060a888c80146ab753 (diff)
downloadbusybox-w32-930453bdcf27bdb4f51d3f4060ebd368aad18c56.tar.gz
busybox-w32-930453bdcf27bdb4f51d3f4060ebd368aad18c56.tar.bz2
busybox-w32-930453bdcf27bdb4f51d3f4060ebd368aad18c56.zip
Use bb_getopt_ulflags, saves some space, better argument checking.
Remove ar specific extraction code, always use common extraction code.
-rw-r--r--archival/ar.c102
1 files changed, 32 insertions, 70 deletions
diff --git a/archival/ar.c b/archival/ar.c
index 1cb418ab4..890e81fc5 100644
--- a/archival/ar.c
+++ b/archival/ar.c
@@ -21,20 +21,20 @@
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 24 * There is no single standard to adhere to so ar may not portable
25 * between different systems 25 * between different systems
26 * http://www.unix-systems.org/single_unix_specification_v2/xcu/ar.html 26 * http://www.unix-systems.org/single_unix_specification_v2/xcu/ar.html
27 */ 27 */
28#include <sys/types.h> 28
29#include <fcntl.h> 29#include <fcntl.h>
30#include <fnmatch.h> 30#include <getopt.h>
31#include <stdio.h> 31#include <stdio.h>
32#include <stdlib.h> 32#include <stdlib.h>
33#include <string.h> 33#include <string.h>
34#include <time.h> 34#include <time.h>
35#include <utime.h> 35#include <utime.h>
36#include <unistd.h> 36#include <unistd.h>
37#include <getopt.h> 37
38#include "unarchive.h" 38#include "unarchive.h"
39#include "busybox.h" 39#include "busybox.h"
40 40
@@ -50,87 +50,50 @@ static void header_verbose_list_ar(const file_header_t *file_header)
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); 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} 51}
52 52
53#if !defined CONFIG_TAR && !defined CONFIG_DPKG_DEB && !defined CONFIG_CPIO 53#define AR_CTX_PRINT 1
54/* This is simpler than data_extract_all */ 54#define AR_CTX_LIST 2
55static void data_extract_regular_file(archive_handle_t *archive_handle) 55#define AR_CTX_EXTRACT 4
56{ 56#define AR_OPT_PRESERVE_DATE 8
57 file_header_t *file_header; 57#define AR_OPT_VERBOSE 16
58 int dst_fd;
59
60 file_header = archive_handle->file_header;
61 dst_fd = bb_xopen(file_header->name, O_WRONLY | O_CREAT);
62 bb_copyfd_size(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 58
78extern int ar_main(int argc, char **argv) 59extern int ar_main(int argc, char **argv)
79{ 60{
80 archive_handle_t *archive_handle; 61 archive_handle_t *archive_handle;
81 int opt; 62 unsigned long opt;
82
83#if !defined CONFIG_DPKG_DEB && !defined CONFIG_DPKG
84 char magic[8]; 63 char magic[8];
85#endif 64
86 archive_handle = init_handle(); 65 archive_handle = init_handle();
87 66
88 while ((opt = getopt(argc, argv, "covtpxX")) != -1) { 67 bb_opt_complementaly = "p~tx:t~px:x~pt";
89 switch (opt) { 68 opt = bb_getopt_ulflags(argc, argv, "ptxov");
90 case 'p': /* print */ 69
91 archive_handle->action_data = data_extract_to_stdout; 70 if ((opt & 0x80000000UL) || (optind == argc)) {
92 break;
93 case 't': /* list contents */
94 archive_handle->action_header = header_list;
95 break;
96 case 'X':
97 archive_handle->action_header = header_verbose_list_ar;
98 case 'x': /* extract */
99#if defined CONFIG_TAR || defined CONFIG_DPKG_DEB || defined CONFIG_CPIO
100 archive_handle->action_data = data_extract_all;
101#else
102 archive_handle->action_data = data_extract_regular_file;
103#endif
104 break;
105 /* Modifiers */
106 case 'o': /* preserve original dates */
107 archive_handle->flags |= ARCHIVE_PRESERVE_DATE;
108 break;
109 case 'v': /* verbose */
110 archive_handle->action_header = header_verbose_list_ar;
111 break;
112 default:
113 bb_show_usage();
114 }
115 }
116
117 /* check the src filename was specified */
118 if (optind == argc) {
119 bb_show_usage(); 71 bb_show_usage();
120 } 72 }
121 73
74 if (opt & AR_CTX_PRINT) {
75 archive_handle->action_data = data_extract_to_stdout;
76 }
77 if (opt & AR_CTX_LIST) {
78 archive_handle->action_header = header_list;
79 }
80 if (opt & AR_CTX_EXTRACT) {
81 archive_handle->action_data = data_extract_all;
82 }
83 if (opt & AR_OPT_PRESERVE_DATE) {
84 archive_handle->flags |= ARCHIVE_PRESERVE_DATE;
85 }
86 if (opt & AR_OPT_VERBOSE) {
87 archive_handle->action_header = header_verbose_list_ar;
88 }
89
122 archive_handle->src_fd = bb_xopen(argv[optind++], O_RDONLY); 90 archive_handle->src_fd = bb_xopen(argv[optind++], O_RDONLY);
123 91
124 /* TODO: This is the same as in tar, seperate function ? */
125 while (optind < argc) { 92 while (optind < argc) {
126 archive_handle->filter = filter_accept_list; 93 archive_handle->filter = filter_accept_list;
127 archive_handle->accept = llist_add_to(archive_handle->accept, argv[optind]); 94 archive_handle->accept = llist_add_to(archive_handle->accept, argv[optind++]);
128 optind++;
129 } 95 }
130 96
131#if defined CONFIG_DPKG_DEB || defined CONFIG_DPKG
132 unpack_ar_archive(archive_handle);
133#else
134 archive_xread_all(archive_handle, magic, 7); 97 archive_xread_all(archive_handle, magic, 7);
135 if (strncmp(magic, "!<arch>", 7) != 0) { 98 if (strncmp(magic, "!<arch>", 7) != 0) {
136 bb_error_msg_and_die("Invalid ar magic"); 99 bb_error_msg_and_die("Invalid ar magic");
@@ -138,7 +101,6 @@ extern int ar_main(int argc, char **argv)
138 archive_handle->offset += 7; 101 archive_handle->offset += 7;
139 102
140 while (get_header_ar(archive_handle) == EXIT_SUCCESS); 103 while (get_header_ar(archive_handle) == EXIT_SUCCESS);
141#endif
142 104
143 return EXIT_SUCCESS; 105 return EXIT_SUCCESS;
144} 106}