diff options
Diffstat (limited to 'ar.c')
-rw-r--r-- | ar.c | 88 |
1 files changed, 25 insertions, 63 deletions
@@ -30,36 +30,27 @@ | |||
30 | 30 | ||
31 | extern int ar_main(int argc, char **argv) | 31 | extern int ar_main(int argc, char **argv) |
32 | { | 32 | { |
33 | const int preserve_date = 1; /* preserve original dates */ | 33 | FILE *src_stream = NULL; |
34 | const int verbose = 2; /* be verbose */ | 34 | int extract_function = 0, opt = 0; |
35 | const int display = 4; /* display contents */ | 35 | file_headers_t *head; |
36 | const int extract_to_file = 8; /* extract contents of archive */ | 36 | file_headers_t *ar_extract_list = NULL; |
37 | const int extract_to_stdout = 16; /* extract to stdout */ | ||
38 | |||
39 | FILE *src_file = NULL, *dst_file = NULL; | ||
40 | int funct = 0, opt=0; | ||
41 | |||
42 | ar_headers_t *head, *ar_extract_list=NULL; | ||
43 | |||
44 | ar_extract_list = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t)); | ||
45 | head = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t)); | ||
46 | 37 | ||
47 | while ((opt = getopt(argc, argv, "ovtpx")) != -1) { | 38 | while ((opt = getopt(argc, argv, "ovtpx")) != -1) { |
48 | switch (opt) { | 39 | switch (opt) { |
49 | case 'o': | 40 | case 'o': |
50 | funct |= preserve_date; | 41 | extract_function |= extract_preserve_date; |
51 | break; | 42 | break; |
52 | case 'v': | 43 | case 'v': |
53 | funct |= verbose; | 44 | extract_function |= extract_verbose_list; |
54 | break; | 45 | break; |
55 | case 't': | 46 | case 't': |
56 | funct |= display; | 47 | extract_function |= extract_list; |
57 | break; | 48 | break; |
58 | case 'p': | 49 | case 'p': |
59 | funct |= extract_to_stdout; | 50 | extract_function |= extract_to_stdout; |
60 | break; | 51 | break; |
61 | case 'x': | 52 | case 'x': |
62 | funct |= extract_to_file; | 53 | extract_function |= extract_all_to_fs; |
63 | break; | 54 | break; |
64 | default: | 55 | default: |
65 | show_usage(); | 56 | show_usage(); |
@@ -71,57 +62,28 @@ extern int ar_main(int argc, char **argv) | |||
71 | show_usage(); | 62 | show_usage(); |
72 | } | 63 | } |
73 | 64 | ||
74 | if ( (src_file = wfopen(argv[optind], "r")) < 0) { | 65 | src_stream = xfopen(argv[optind++], "r"); |
75 | error_msg_and_die("Cannot read %s", argv[optind]); | 66 | head = get_ar_headers(src_stream); |
76 | } | ||
77 | 67 | ||
78 | optind++; | ||
79 | head = get_ar_headers(src_file); | ||
80 | /* find files to extract or display */ | 68 | /* find files to extract or display */ |
81 | /* search through argv and build extract list */ | 69 | /* search through argv and build extract list */ |
82 | for (;optind < argc; optind++) { | 70 | ar_extract_list = (file_headers_t *) xcalloc(1, sizeof(file_headers_t)); |
83 | ar_headers_t *ar_entry; | 71 | if (optind < argc) { |
84 | ar_entry = (ar_headers_t *) xcalloc(1, sizeof(ar_headers_t)); | 72 | while (optind < argc) { |
85 | ar_entry = head; | 73 | ar_extract_list = add_from_archive_list(head, ar_extract_list, argv[optind]); |
86 | while (ar_entry->next != NULL) { | 74 | optind++; |
87 | if (strcmp(argv[optind], ar_entry->name) == 0) { | ||
88 | ar_headers_t *tmp; | ||
89 | tmp = (ar_headers_t *) xmalloc(sizeof(ar_headers_t)); | ||
90 | *tmp = *ar_extract_list; | ||
91 | *ar_extract_list = *ar_entry; | ||
92 | ar_extract_list->next = tmp; | ||
93 | break; | ||
94 | } | ||
95 | ar_entry=ar_entry->next; | ||
96 | } | 75 | } |
97 | } | 76 | } else { |
98 | |||
99 | /* if individual files not found extract all files */ | ||
100 | if (ar_extract_list->next==NULL) { | ||
101 | ar_extract_list = head; | 77 | ar_extract_list = head; |
102 | } | 78 | } |
103 | 79 | ||
104 | /* find files to extract or display */ | 80 | /* If there isnt even one possible entry then abort */ |
105 | while (ar_extract_list->next != NULL) { | 81 | if (ar_extract_list->name == NULL) { |
106 | if (funct & extract_to_file) { | 82 | error_msg_and_die("No files to extract"); |
107 | dst_file = wfopen(ar_extract_list->name, "w"); | 83 | } |
108 | } | 84 | |
109 | else if (funct & extract_to_stdout) { | 85 | fseek(src_stream, 0, SEEK_SET); |
110 | dst_file = stdout; | 86 | extract_archive(src_stream, stdout, ar_extract_list, extract_function, "./"); |
111 | } | 87 | |
112 | if ((funct & extract_to_file) || (funct & extract_to_stdout)) { | ||
113 | fseek(src_file, ar_extract_list->offset, SEEK_SET); | ||
114 | copy_file_chunk(src_file, dst_file, ar_extract_list->size); | ||
115 | } | ||
116 | if (funct & verbose) { | ||
117 | printf("%s %d/%d %8d %s ", mode_string(ar_extract_list->mode), | ||
118 | ar_extract_list->uid, ar_extract_list->gid, | ||
119 | (int) ar_extract_list->size, time_string(ar_extract_list->mtime)); | ||
120 | } | ||
121 | if ((funct & display) || (funct & verbose)){ | ||
122 | puts(ar_extract_list->name); | ||
123 | } | ||
124 | ar_extract_list = ar_extract_list->next; | ||
125 | } | ||
126 | return EXIT_SUCCESS; | 88 | return EXIT_SUCCESS; |
127 | } | 89 | } |