aboutsummaryrefslogtreecommitdiff
path: root/archival/libunarchive/get_header_zip.c
diff options
context:
space:
mode:
Diffstat (limited to 'archival/libunarchive/get_header_zip.c')
-rw-r--r--archival/libunarchive/get_header_zip.c171
1 files changed, 0 insertions, 171 deletions
diff --git a/archival/libunarchive/get_header_zip.c b/archival/libunarchive/get_header_zip.c
deleted file mode 100644
index 5fa3a6c8c..000000000
--- a/archival/libunarchive/get_header_zip.c
+++ /dev/null
@@ -1,171 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * get_header_zip for busybox
4 *
5 * Copyright (C) 2001 by Laurence Anderson
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <stddef.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include "unarchive.h"
27#include "libbb.h"
28
29#define ZIP_FILEHEADER_MAGIC 0x04034b50
30#define ZIP_CDS_MAGIC 0x02014b50
31#define ZIP_CDS_END_MAGIC 0x06054b50
32#define ZIP_DD_MAGIC 0x08074b50
33
34
35enum {
36 zh_version,
37 zh_flags,
38 zh_method,
39 zh_modtime,
40 zh_moddate,
41 zh_crc32,
42 zh_cmpsize,
43 zh_ucmpsize,
44 zh_filename_len,
45 zh_extra_len
46};
47
48static const char fail_msg[] = "Invalid file or read error";
49
50static int le_read_int(FILE *fp, int n)
51{
52 int r = 0;
53 int s = 1;
54 int c;
55
56 archive_offset += n;
57
58 do {
59 if ((c = fgetc(fp)) == EOF) {
60 error_msg_and_die(fail_msg);
61 }
62 r += s * c;
63 s <<= 8;
64 } while (--n);
65
66 return r;
67}
68
69static void read_header(FILE *fp, int *zh)
70{
71 static const char s[] = { 2, 2, 2, 2, 2, 4, 4, 4, 2, 2, 0 };
72 int i = 0;
73
74 do {
75 zh[i] = le_read_int(fp, s[i]);
76 } while (s[++i]);
77}
78
79file_header_t *get_header_zip(FILE *zip_stream)
80{
81 int zip_header[10];
82 file_header_t *zip_entry = NULL;
83 int magic, tmpmagic;
84 /* If dd_ahead is true, we didn't know the last extracted file's length. */
85 static int dd_ahead = 0;
86
87 magic = le_read_int(zip_stream, 4);
88
89 checkmagic:
90 switch (magic) {
91 case ZIP_FILEHEADER_MAGIC:
92 zip_entry = xcalloc(1, sizeof(file_header_t));
93
94 read_header(zip_stream, zip_header);
95
96 if (zip_header[zh_method] == 8) {
97 zip_entry->extract_func = &inflate;
98 } else if (zip_header[zh_method] != 0) {
99 error_msg_and_die("Unsupported compression method %d\n",
100 zip_header[zh_method]);
101 }
102
103 zip_entry->name = xmalloc(zip_header[zh_filename_len] + 1);
104 if (!fread(zip_entry->name, zip_header[zh_filename_len], 1, zip_stream)) {
105 error_msg_and_die(fail_msg);
106 }
107 archive_offset += zip_header[zh_filename_len];
108
109 seek_sub_file(zip_stream, zip_header[zh_extra_len]);
110
111 zip_entry->size = zip_header[zh_cmpsize];
112
113 zip_entry->mode = S_IFREG | 0777;
114
115 /* Time/Date? */
116
117 zip_entry->name[zip_header[zh_filename_len]] = 0;
118 if (*(zip_entry->name + zip_header[zh_filename_len] - 1) == '/') {
119 /* Files that end in a / are directories */
120 /* Remove trailing / so unarchive doesn't get confused */
121 *(zip_entry->name + zip_header[zh_filename_len] - 1) = '\0';
122 zip_entry->mode ^= S_IFREG;
123 zip_entry->mode |= S_IFDIR;
124 }
125
126 if (zip_header[zh_flags] & 0x8) {
127 /* crc32, and sizes are in the data description _after_ the file */
128 if (zip_header[zh_cmpsize] == 0) {
129 /* As we don't know how long this file it is difficult to skip!
130 * but it is compressed, so normally its ok */
131 dd_ahead = 1;
132 }
133 if (zip_header[zh_ucmpsize] != 0) {
134 /* Humm... we would otherwise skip this twice - not good! */
135 dd_ahead = 2;
136 }
137 }
138 break;
139
140 case ZIP_CDS_MAGIC: /* FALLTHRU */
141 case ZIP_CDS_END_MAGIC:
142 return(NULL);
143 break;
144
145 case ZIP_DD_MAGIC: {
146 int cmpsize;
147 seek_sub_file(zip_stream, 4); // Skip crc32
148 cmpsize = le_read_int(zip_stream, 4);
149 if (dd_ahead == 1) archive_offset += cmpsize;
150 seek_sub_file(zip_stream, 4); // Skip uncompressed size
151 dd_ahead = 0;
152 return (get_header_zip(zip_stream));
153 break; }
154
155 default:
156 if (!dd_ahead) error_msg("Invalid magic (%#x): Trying to skip junk", magic);
157 dd_ahead = 0;
158 while ((tmpmagic = fgetc(zip_stream)) != EOF) {
159 archive_offset++;
160 magic = ((magic >> 8) & 0x00ffffff) | ((tmpmagic << 24) & 0xff000000);
161 if (magic == ZIP_FILEHEADER_MAGIC
162 || magic == ZIP_CDS_MAGIC
163 || magic == ZIP_CDS_END_MAGIC) {
164 goto checkmagic;
165 }
166 }
167 error_msg_and_die(fail_msg);
168 }
169
170 return(zip_entry);
171}