1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed to the Apache Software Foundation (ASF) under one or more
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * contributor license agreements.  See the NOTICE file distributed with
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this work for additional information regarding copyright ownership.
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The ASF licenses this file to You under the Apache License, Version 2.0
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (the "License"); you may not use this file except in compliance with
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the License.  You may obtain a copy of the License at
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @file
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @ingroup ZipSupport
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @brief Zip Support for Java VM
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <string.h>
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <sys/stat.h>
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "hy2sie.h"
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "zipsup.h"
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "zlib.h"
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// zlib is statically linked for Android:
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define checkZipLibrary(dummy) 0
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef checkZipLibrary
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define inflateInit2Func(a, b, c, d) inflateInit2_ (a, b, c, d)
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define inflateFunc(a, b) inflate (a, b)
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define inflateEndFunc(a) inflateEnd (a)
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#else
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* Globals for the zip library */
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectUDATA zipDLLDescriptor = 0;
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint (*inflateInit2Func) (void *, int, const char *, int);
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint (*inflateFunc) (void *, int);
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint (*inflateEndFunc) (void *);
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define ZIP_NEXT_U8(value, index) (value = *(index++))
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define ZIP_NEXT_U16(value, index) ((value = (index[1] << 8) | index[0]), index += 2, value)
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define ZIP_NEXT_U32(value, index) ((value = ((U_32)index[3] << 24) | ((U_32)index[2] << 16) | ((U_32)index[1] << 8) | (U_32)index[0]), index += 4, value)
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define WORK_BUFFER_SIZE 64000
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define SCAN_CHUNK_SIZE 1024
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstruct workBuffer
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  HyPortLibrary *portLib;
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  UDATA *bufferStart;
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  UDATA *bufferEnd;
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  UDATA *currentAlloc;
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  UDATA cntr;
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project};
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION _prototypes_private
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32 zip_populateCache
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, HyZipFile * zipFile));
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic I_32 inflateData
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((struct workBuffer * workBuf, U_8 * inputBuffer,
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            U_32 inputBufferSize, U_8 * outputBuffer, U_32 outputBufferSize));
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32 checkZipLibrary PROTOTYPE ((HyPortLibrary * portLib));
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32 scanForDataDescriptor
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, HyZipFile * zipFile,
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            HyZipEntry * zipEntry));
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid zdatafree PROTOTYPE ((void *opaque, void *address));
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic I_32 readZipEntry
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, HyZipFile * zipFile,
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            HyZipEntry * zipEntry, const char *filename,
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            IDATA * enumerationPointer, IDATA * entryStart,
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            BOOLEAN findDirectory));
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32 scanForCentralEnd
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, HyZipFile * zipFile,
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            HyZipCentralEnd * endEntry));
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid *zdataalloc PROTOTYPE ((void *opaque, U_32 items, U_32 size));
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION _prototypes_public
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32 zip_getZipEntryData
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, HyZipFile * zipFile, HyZipEntry * entry,
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            U_8 * buffer, U_32 bufferSize));
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32 zip_getZipEntryFromOffset
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, HyZipFile * zipFile, HyZipEntry * entry,
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            IDATA offset));
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32 zip_establishCache
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, HyZipFile * zipFile));
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid zip_resetZipFile
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, HyZipFile * zipFile,
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            IDATA * nextEntryPointer));
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32 zip_getNextZipEntry
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, HyZipFile * zipFile,
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            HyZipEntry * zipEntry, IDATA * nextEntryPointer));
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32 zip_getZipEntry
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, HyZipFile * zipFile, HyZipEntry * entry,
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            const char *filename, BOOLEAN findDirectory));
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32 zip_getZipEntryExtraField
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, HyZipFile * zipFile, HyZipEntry * entry,
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            U_8 * buffer, U_32 bufferSize));
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid zip_initZipEntry
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, HyZipEntry * entry));
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32 zip_openZipFile
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, char *filename, HyZipFile * zipFile,
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            HyZipCachePool * cachePool));
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid zip_freeZipEntry
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, HyZipEntry * entry));
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32 VMCALL zip_closeZipFile
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, struct HyZipFile * zipFile));
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32 zip_getZipEntryComment
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPROTOTYPE ((HyPortLibrary * portLib, HyZipFile * zipFile, HyZipEntry * entry,
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            U_8 * buffer, U_32 bufferSize));
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//#include "hythread.h"
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//#define ENTER() hythread_monitor_enter(hythread_global_monitor())
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//#define EXIT() hythread_monitor_exit(hythread_global_monitor())
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "hymutex.h"
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectMUTEX zip_globalMutex;
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int initialized = 0;
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define ENTER() \
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (!initialized) { MUTEX_INIT(zip_globalMutex); initialized = 1; } \
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  MUTEX_ENTER(zip_globalMutex);
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define EXIT() MUTEX_EXIT(zip_globalMutex);
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectHyZipCachePool *
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzipsup_GetZipCachePool(JNIEnv * env)
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  static HyZipCachePool *pool = 0;
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (pool == 0) {
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pool = zipCachePool_new(env);
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  }
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return pool;
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifndef checkZipLibrary
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION checkZipLibrary
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	Ensure that the zip library is loaded.
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	Return 0 on success, -1 on failure.
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectcheckZipLibrary (HyPortLibrary * portLib)
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* if the library has already been loaded return success/failure */
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipDLLDescriptor > 1)
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipDLLDescriptor == 1)
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return -1;
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* open up the zip library by name */
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (hysl_open_shared_library (HY_ZIP_DLL_NAME, &zipDLLDescriptor, TRUE))
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    goto openFailed;
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* look up the functions */
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (hysl_lookup_name
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      (zipDLLDescriptor, "inflateInit2_", (void *) &inflateInit2Func,
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project       "ILILI"))
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    goto loadFailed;
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (hysl_lookup_name
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      (zipDLLDescriptor, "inflate", (void *) &inflateFunc, "IPI"))
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    goto loadFailed;
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (hysl_lookup_name
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      (zipDLLDescriptor, "inflateEnd", (void *) &inflateEndFunc, "IP"))
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    goto loadFailed;
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* good to go */
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return 0;
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectloadFailed:
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  hysl_close_shared_library (zipDLLDescriptor);
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* mark the descriptor as a failed load. only report the error once */
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipDLLDescriptor = 1;
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Unable to open %s (Missing export) */
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  hynls_printf (PORTLIB, HYNLS_WARNING, HYNLS_ZIP_MISSING_EXPORT,
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                HY_ZIP_DLL_NAME);
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return -1;
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectopenFailed:
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* mark the descriptor as a failed load. only report the error once */
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipDLLDescriptor = 1;
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Unable to open %s (%s) */
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  hynls_printf (PORTLIB, HYNLS_WARNING, HYNLS_ZIP_UNABLE_TO_OPEN_ZIP_DLL,
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                HY_ZIP_DLL_NAME, hyerror_last_error_message ());
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return -1;
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION inflateData
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	Returns 0 on success or one of the following:
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_UNSUPPORTED_FILE_TYPE
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_FILE_CORRUPT
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_OUT_OF_MEMORY
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_INTERNAL_ERROR
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic I_32
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectinflateData (struct workBuffer *workBuf, U_8 * inputBuffer,
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             U_32 inputBufferSize, U_8 * outputBuffer, U_32 outputBufferSize)
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (workBuf->portLib);
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  z_stream stream;
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_32 err;
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  stream.next_in = inputBuffer;
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  stream.avail_in = inputBufferSize;
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  stream.next_out = outputBuffer;
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  stream.avail_out = outputBufferSize;
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  stream.opaque = workBuf;
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  stream.zalloc = zdataalloc;
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  stream.zfree = zdatafree;
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Initialize stream. Pass "-15" as max number of window bits, negated
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     to indicate that no zlib header is present in the data. */
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  err = inflateInit2Func (&stream, -15, ZLIB_VERSION, sizeof (z_stream));
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (err != Z_OK)
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return -1;
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Inflate the data. */
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  err = inflateFunc (&stream, Z_SYNC_FLUSH);
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Clean up the stream. */
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  inflateEndFunc (&stream);
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Check the return code. Did we complete the inflate? */
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((err == Z_STREAM_END) || (err == Z_OK))
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (stream.total_out == outputBufferSize)
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return 0;
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  switch (err)
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case Z_OK:                 /* an error if file is incomplete */
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case Z_STREAM_END:         /* an error if file is incomplete */
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case Z_ERRNO:              /* a random error */
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case Z_STREAM_ERROR:       /* stream inconsistent */
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case Z_DATA_ERROR:         /* corrupted zip */
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return ZIP_ERR_FILE_CORRUPT;
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case Z_VERSION_ERROR:      /* wrong zlib version */
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case Z_NEED_DICT:          /* needs a preset dictionary that we can't provide */
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return ZIP_ERR_UNSUPPORTED_FILE_TYPE;
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case Z_MEM_ERROR:          /* out of memory */
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return ZIP_ERR_OUT_OF_MEMORY;
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case Z_BUF_ERROR:          /* no progress / out of output buffer */
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:                   /* jic */
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return ZIP_ERR_INTERNAL_ERROR;
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION scanForCentralEnd
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	Scan backward from end of file for a central end header. Read from zipFile and update the HyZipCentralEnd provided.
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	Returns 0 on success or one of the following:
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_FILE_READ_ERROR
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_FILE_CORRUPT
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectscanForCentralEnd (HyPortLibrary * portLib, HyZipFile * zipFile,
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                   HyZipCentralEnd * endEntry)
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_8 *current;
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_8 buffer[SCAN_CHUNK_SIZE];
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_32 i, size, state;
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_32 dataSize = 0;
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_64 seekResult;
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_32 fileSize;
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_32 bytesAlreadyRead = 0;
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Haven't seen anything yet. */
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  state = 0;
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  seekResult = hyfile_seek (zipFile->fd, 0, HySeekEnd);
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((seekResult < 0) || (seekResult > HYCONST64 (0x7FFFFFFF)))
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer = -1;
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return ZIP_ERR_FILE_READ_ERROR;
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  fileSize = (I_32) seekResult;
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipFile->pointer = fileSize;
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  while (TRUE)
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Fill the buffer. */
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (bytesAlreadyRead == fileSize)
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_FILE_CORRUPT;
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      size = SCAN_CHUNK_SIZE;
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (size > fileSize - bytesAlreadyRead)
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        size = fileSize - bytesAlreadyRead;
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      bytesAlreadyRead += size;
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      seekResult =
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hyfile_seek (zipFile->fd, fileSize - bytesAlreadyRead, HySeekSet);
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if ((seekResult < 0) || (seekResult > HYCONST64 (0x7FFFFFFF)))
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_FILE_READ_ERROR;
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer = (I_32) seekResult;
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (hyfile_read (zipFile->fd, buffer, size) != size)
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_FILE_READ_ERROR;
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer += size;
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Scan the buffer (backwards) for CentralEnd signature = PK^E^F. */
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      for (i = size; i--; dataSize++)
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          switch (state)
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0:
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* Nothing yet. */
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (buffer[i] == 6)
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                state = 1;
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              break;
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 1:
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* Seen ^F */
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (buffer[i] == 5)
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                state = 2;
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              else
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                state = 0;
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              break;
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 2:
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* Seen ^E^F */
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (buffer[i] == 'K')
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                state = 3;
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              else
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                state = 0;
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              break;
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 3:
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* Seen K^E^F */
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (buffer[i] == 'P' && dataSize >= 21)
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  /* Found it.  Read the data from the end-of-central-dir record. */
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  current = buffer + i + 4;
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  ZIP_NEXT_U16 (endEntry->diskNumber, current);
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  ZIP_NEXT_U16 (endEntry->dirStartDisk, current);
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  ZIP_NEXT_U16 (endEntry->thisDiskEntries, current);
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  ZIP_NEXT_U16 (endEntry->totalEntries, current);
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  ZIP_NEXT_U32 (endEntry->dirSize, current);
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  ZIP_NEXT_U32 (endEntry->dirOffset, current);
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  ZIP_NEXT_U16 (endEntry->commentLength, current);
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  /* Quick test to ensure that the header isn't invalid.
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     Current dataSize is the number of bytes of data scanned, up to the ^H in the stream. */
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  if (dataSize >= (U_32) (21 + endEntry->commentLength))
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    return 0;
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  /* Header looked invalid. Pretend we didn't see it and keep scanning.. */
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              state = 0;
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              break;
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION scanForDataDescriptor
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	Scan ahead for a data descriptor. Read from zipFile and update the HyZipLocalHeader provided.
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	Returns 0 on success or one of the following:
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_FILE_READ_ERROR
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_FILE_CORRUPT
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectscanForDataDescriptor (HyPortLibrary * portLib, HyZipFile * zipFile,
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                       HyZipEntry * zipEntry)
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_8 *current;
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_8 buffer[SCAN_CHUNK_SIZE], descriptor[16];
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_32 i, size, state;
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_32 dataSize, blockPointer;
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_64 seekResult;
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Skip ahead and read the data descriptor. The compressed size should be 0. */
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipFile->pointer !=
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      (IDATA) (zipEntry->dataPointer + zipEntry->compressedSize))
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      seekResult =
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hyfile_seek (zipFile->fd,
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     zipEntry->dataPointer + zipEntry->compressedSize,
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     HySeekSet);
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if ((seekResult < 0) || (seekResult > HYCONST64 (0x7FFFFFFF)))
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_FILE_READ_ERROR;
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer = (I_32) seekResult;
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Haven't seen anything yet. */
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  blockPointer = dataSize = zipEntry->compressedSize;
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  state = 0;
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Scan until we find PK^G^H (otherwise it's an error). */
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  while (1)
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Fill the buffer. */
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      size = hyfile_read (zipFile->fd, buffer, SCAN_CHUNK_SIZE);
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (size == 0)
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_FILE_CORRUPT;
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      else if (size < 0)
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_FILE_READ_ERROR;
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer += size;
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      blockPointer += size;
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Scan the buffer. */
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      for (i = 0; i < size; i++, dataSize++)
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          switch (state)
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0:
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* Nothing yet. */
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (buffer[i] == 'P')
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  state = 1;
474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              break;
476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 1:
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* Seen P */
479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (buffer[i] == 'K')
480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  state = 2;
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              else
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                state = 0;
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              break;
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 2:
488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* Seen PK */
489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (buffer[i] == 7)
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  state = 3;
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              else
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  state = 0;
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              break;
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 3:
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* Seen PK^G */
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (buffer[i] == 8)
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  /* Found it! Read the descriptor */
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  if (i + 12 < size)
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    {
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                      current = &buffer[i + 1];
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  else
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    {
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                      seekResult =
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        hyfile_seek (zipFile->fd,
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                     zipEntry->dataPointer + dataSize + 1,
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                     HySeekSet);
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                      if ((seekResult < 0)
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                          || (seekResult > HYCONST64 (0x7FFFFFFF)))
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        {
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                          zipFile->pointer = -1;
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                          return ZIP_ERR_FILE_READ_ERROR;
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        }
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                      zipFile->pointer = (I_32) seekResult;
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                      if (hyfile_read (zipFile->fd, descriptor, 12) != 12)
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        {
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                          zipFile->pointer = -1;
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                          return ZIP_ERR_FILE_READ_ERROR;
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        }
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                      zipFile->pointer += 12;
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                      current = descriptor;
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  /* Read the data from the descriptor. */
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  ZIP_NEXT_U32 (zipEntry->crc32, current);
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  ZIP_NEXT_U32 (zipEntry->compressedSize, current);
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  ZIP_NEXT_U32 (zipEntry->uncompressedSize, current);
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  /* Quick test to ensure that the header isn't invalid.
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     Current dataSize is the number of bytes of data scanned, up to the ^H in the stream. */
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  if (dataSize - 3 == zipEntry->compressedSize)
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    {
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                      return 0;
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  /* Header looked invalid. Reset the pointer and continue scanning. */
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  seekResult =
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    hyfile_seek (zipFile->fd,
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                 zipEntry->dataPointer + blockPointer,
546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                 HySeekSet);
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  if ((seekResult < 0)
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                      || (seekResult > HYCONST64 (0x7FFFFFFF)))
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    {
550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                      zipFile->pointer = -1;
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                      return ZIP_ERR_FILE_READ_ERROR;
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    }
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  zipFile->pointer = (I_32) seekResult;
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              else
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                state = 0;
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              break;
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zip_populateCache
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	Fill in the cache of a given zip file.  This should only be called once during zip_openZipFile!
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	Returns 0 on success or one of the following:
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_FILE_READ_ERROR
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_FILE_OPEN_ERROR
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_UNKNOWN_FILE_TYPE
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_UNSUPPORTED_FILE_TYPE
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_OUT_OF_MEMORY
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_INTERNAL_ERROR
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzip_populateCache (HyPortLibrary * portLib, HyZipFile * zipFile)
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_32 result = 0;
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA bufferSize = 65536;
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA unreadSize = 0;
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA bufferedSize = 0;
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA bytesToRead = 0;
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA filenameCopied;
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  HyZipEntry entry;
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  HyZipCentralEnd endEntry;
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_8 *buffer = NULL;
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_8 *filename = NULL;
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA filenameSize = 256;     /* Should be sufficient for most filenames */
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_8 *current;
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_32 sig;
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_32 localHeaderOffset;
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA startCentralDir;
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_64 seekResult;
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (!zipFile->cache)
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return ZIP_ERR_INTERNAL_ERROR;
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Find and read the end-of-central-dir record. */
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  result = scanForCentralEnd (portLib, zipFile, &endEntry);
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (result != 0)
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  unreadSize = endEntry.dirSize + 4 /* slop */ ;
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipFile->cache->startCentralDir = startCentralDir =
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    (IDATA) ((UDATA) endEntry.dirOffset);
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipFile->pointer != startCentralDir)
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      seekResult = hyfile_seek (zipFile->fd, startCentralDir, HySeekSet);
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if ((seekResult < 0) || (seekResult > HYCONST64 (0x7FFFFFFF)))
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_FILE_READ_ERROR;
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer = (I_32) seekResult;
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (zipFile->pointer != startCentralDir)
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_FILE_READ_ERROR;
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* No point in allocating more than we'll actually need.. */
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (bufferSize > unreadSize)
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bufferSize = unreadSize;
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  filename = hymem_allocate_memory (filenameSize);
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (!filename)
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = ZIP_ERR_OUT_OF_MEMORY;
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      goto finished;
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Allocate some space to hold central directory goo as we eat through it */
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  buffer = hymem_allocate_memory (bufferSize);
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (!buffer && (bufferSize > 4096))
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Not enough memory, fall back to a smaller buffer! */
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      bufferSize = 4096;
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      buffer = hymem_allocate_memory (bufferSize);
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (!buffer)
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = ZIP_ERR_OUT_OF_MEMORY;
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      goto finished;
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  while (unreadSize)
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Read as much as needed into buffer. */
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      bytesToRead = bufferSize - bufferedSize;
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (bytesToRead > unreadSize)
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        bytesToRead = unreadSize;
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = hyfile_read (zipFile->fd, buffer + bufferedSize, bytesToRead);
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (result < 0)
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_FILE_READ_ERROR;
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer += result;
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      unreadSize -= result;
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      bufferedSize += result;
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      current = buffer;
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* consume entries until we run out. */
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      while (current + 46 < buffer + bufferedSize)
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          IDATA entryPointer;
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          entryPointer =
680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            zipFile->pointer + (current - (buffer + bufferedSize));
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          sig = 0;
683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U32 (sig, current);
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (sig == ZIP_CentralEnd)
685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* We're done here. */
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              result = 0;
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              goto finished;
689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (sig != ZIP_CentralHeader)
691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* Umm...What the Hell? */
693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              result = ZIP_ERR_FILE_CORRUPT;
694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              goto finished;
695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          /* Read ZIP_CentralHeader entry */
698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U16 (entry.versionCreated, current);
699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U16 (entry.versionNeeded, current);
700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U16 (entry.flags, current);
701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U16 (entry.compressionMethod, current);
702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U16 (entry.lastModTime, current);
703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U16 (entry.lastModDate, current);
704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U32 (entry.crc32, current);
705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U32 (entry.compressedSize, current);
706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U32 (entry.uncompressedSize, current);
707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U16 (entry.filenameLength, current);
708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U16 (entry.extraFieldLength, current);
709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U16 (entry.fileCommentLength, current);
710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          current += sizeof (U_16);     /* skip disk number field */
711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U16 (entry.internalAttributes, current);
712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          current += sizeof (U_32);     /* skip external attributes field */
713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ZIP_NEXT_U32 (localHeaderOffset, current);
714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          /* Increase filename buffer size if necessary. */
716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (filenameSize < entry.filenameLength + 1)
717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              hymem_free_memory (filename);
719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              filenameSize = entry.filenameLength + 1;
720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              filename = hymem_allocate_memory (filenameSize);
721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (!filename)
722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  result = ZIP_ERR_OUT_OF_MEMORY;
724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  goto finished;
725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          filenameCopied = 0;
729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          while (filenameCopied < entry.filenameLength)
730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              IDATA size;
732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* Copy as much of the filename as we can see in the buffer (probably the whole thing). */
733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              size = entry.filenameLength - filenameCopied;
735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (size > bufferedSize - (current - buffer))
736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  size = bufferedSize - (current - buffer);
738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              memcpy (filename + filenameCopied, current, size);
740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              filenameCopied += size;
741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              current += size;
742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (filenameCopied >= entry.filenameLength)
743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;          /* done */
744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* Otherwise, we ran out of source string.  Load another chunk.. */
746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              bufferedSize = 0;
747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (!unreadSize)
748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  /* Central header is supposedly done?  Bak */
750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  result = ZIP_ERR_FILE_CORRUPT;
751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  goto finished;
752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              bytesToRead = bufferSize - bufferedSize;
754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (bytesToRead > unreadSize)
755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                bytesToRead = unreadSize;
756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              result =
757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                hyfile_read (zipFile->fd, buffer + bufferedSize, bytesToRead);
758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (result < 0)
759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  result = ZIP_ERR_FILE_READ_ERROR;
761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  zipFile->pointer = -1;
762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  goto finished;
763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              zipFile->pointer += result;
765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              unreadSize -= result;
766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              bufferedSize += result;
767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              current = buffer;
768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          filename[entry.filenameLength] = '\0';        /* null-terminate */
770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (((entry.compressionMethod == ZIP_CM_Deflated)
772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project               && (entry.flags & 0x8)) || (entry.fileCommentLength != 0))
773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* Either local header doesn't know the compressedSize, or this entry has a file
775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 comment.  In either case, cache the central header instead of the local header
776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 so we can find the information we need later. */
777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              result =
779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                zipCache_addElement (zipFile->cache, (char *) filename,
780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                     entryPointer);
781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          else
784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              result =
786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                zipCache_addElement (zipFile->cache, (char *) filename,
787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                     localHeaderOffset);
788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (!result)
791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              result = ZIP_ERR_OUT_OF_MEMORY;
793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              goto finished;
794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          /* Skip the data and comment. */
797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          bytesToRead = entry.extraFieldLength + entry.fileCommentLength;
798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (bufferedSize - (current - buffer) >= bytesToRead)
799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              current += bytesToRead;
801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          else
803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* The rest of the buffer is uninteresting.  Skip ahead to where the good stuff is */
805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              bytesToRead -= (bufferedSize - (current - buffer));
806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              current = buffer + bufferedSize;
807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              unreadSize -= bytesToRead;
808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              seekResult = hyfile_seek (zipFile->fd, bytesToRead, HySeekCur);
810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if ((seekResult < 0) || (seekResult > HYCONST64 (0x7FFFFFFF)))
811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  zipFile->pointer = -1;
813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  result = ZIP_ERR_FILE_READ_ERROR;
814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  goto finished;
815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              zipFile->pointer = (I_32) seekResult;
817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      bufferedSize -= (current - buffer);
820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      memmove (buffer, current, bufferedSize);
821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  result = 0;
824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfinished:
826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (filename)
827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    hymem_free_memory (filename);
828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (buffer)
829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    hymem_free_memory (buffer);
830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return result;
831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION readZipEntry
836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	Read the next zip entry for the zipFile into the zipEntry provided.  If filename is non-NULL, it is expected to match
838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	the filename read for the entry.  If (cachePointer != -1) the filename of the entry will be looked up in the cache (assuming
839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	there is one) to help detect use of an invalid cache.  If enumerationPointer is non-NULL, sequential access is assumed and
840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	either a local zip entry or a data descriptor will be accepted, but a central zip entry will cause ZIP_ERR_NO_MORE_ENTRIES
841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	to be returned.  If enumerationPointer is NULL, random access is assumed and either a local zip entry or a central zip
842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	entry will be accepted.
843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	Returns 0 on success or one of the following:
845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_FILE_READ_ERROR
846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_FILE_CORRUPT
847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_OUT_OF_MEMORY
848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project			ZIP_ERR_NO_MORE_ENTRIES
849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic I_32
851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectreadZipEntry (HyPortLibrary * portLib, HyZipFile * zipFile,
852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              HyZipEntry * zipEntry, const char *filename,
853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              IDATA * enumerationPointer, IDATA * entryStart,
854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              BOOLEAN findDirectory)
855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_32 result;
859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_8 buffer[46 + 128];
860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_8 *current;
861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_32 sig;
862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA readLength;
863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_64 seekResult;
864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_8 *readBuffer;
865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA currentEntryPointer, localEntryPointer;
866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA headerSize;
867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA filenameLength = filename ? strlen (filename) : 0;
868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectretry:
870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (entryStart)
871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    *entryStart = zipFile->pointer;
872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  readBuffer = NULL;
873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Guess how many bytes we'll need to read.  If we guess correctly we will do fewer I/O operations */
874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  headerSize = 30;              /* local zip header size */
875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipFile->cache && (zipFile->pointer >= zipFile->cache->startCentralDir))
876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      headerSize = 46;          /* central zip header size */
878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  readLength = headerSize + (filename ? filenameLength : 128);
880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (findDirectory)
881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Extra byte for possible trailing '/' */
883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      readLength++;
884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Allocate some memory if necessary */
887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (readLength <= sizeof (buffer))
888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      current = buffer;
890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  else
892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      current = readBuffer = hymem_allocate_memory (readLength);
894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (!readBuffer)
895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return ZIP_ERR_OUT_OF_MEMORY;
896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  currentEntryPointer = localEntryPointer = zipFile->pointer;
899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  result = hyfile_read (zipFile->fd, current, readLength);
901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((result < 22)
902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      || (filename
903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          && !(result == readLength
904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project               || (findDirectory && result == (readLength - 1)))))
905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* We clearly didn't get enough bytes */
907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = ZIP_ERR_FILE_READ_ERROR;
908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      goto finished;
909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipFile->pointer += result;
911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  readLength = result;          /* If it's not enough, we'll catch that later */
912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ZIP_NEXT_U32 (sig, current);
913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (enumerationPointer)
915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if ((sig == ZIP_CentralEnd))
917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_NO_MORE_ENTRIES;
919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((enumerationPointer || (!zipFile->cache))
923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      && (sig == ZIP_DataDescriptor))
924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* We failed to predict a data descriptor here.  This should be an error (i.e. only happens in malformed zips?)
926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         but, but we will silently skip over it */
927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      seekResult =
928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hyfile_seek (zipFile->fd, currentEntryPointer + 16, HySeekSet);
929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if ((seekResult < 0) || (seekResult > HYCONST64 (0x7FFFFFFF)))
930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_FILE_READ_ERROR;
933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer = (I_32) seekResult;
936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (zipFile->pointer == currentEntryPointer + 16)
938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (readBuffer)
940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              hymem_free_memory (readBuffer);
942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto retry;
944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = ZIP_ERR_FILE_READ_ERROR;
946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      goto finished;
947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((sig != ZIP_CentralHeader) && (sig != ZIP_LocalHeader))
950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Unexpected. */
952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = ZIP_ERR_FILE_CORRUPT;
953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      goto finished;
954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  headerSize = ((sig == ZIP_CentralHeader) ? 46 : 30);
956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (readLength < headerSize)
957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* We didn't get the whole header (and none of the filename).. */
959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* NOTE: this could happen in normal use if the assumed filename length above is <16.  Since it's 128, we don't
960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         handle the impossible case where we would have to read more header.  It could also happen if the caller
961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         supplied a filename of length <16 but that only happens when we have a cache (so we'll know the header size)
962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project       */
963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = ZIP_ERR_FILE_READ_ERROR;
964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  readLength -= headerSize;
966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (sig == ZIP_CentralHeader)
968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      current += 2;             /* skip versionCreated field */
970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ZIP_NEXT_U16 (zipEntry->versionNeeded, current);
972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ZIP_NEXT_U16 (zipEntry->flags, current);
973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ZIP_NEXT_U16 (zipEntry->compressionMethod, current);
974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ZIP_NEXT_U16 (zipEntry->lastModTime, current);
975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ZIP_NEXT_U16 (zipEntry->lastModDate, current);
976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ZIP_NEXT_U32 (zipEntry->crc32, current);
977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ZIP_NEXT_U32 (zipEntry->compressedSize, current);
978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ZIP_NEXT_U32 (zipEntry->uncompressedSize, current);
979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ZIP_NEXT_U16 (zipEntry->filenameLength, current);
980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ZIP_NEXT_U16 (zipEntry->extraFieldLength, current);
981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipEntry->fileCommentLength = 0;
982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (sig == ZIP_CentralHeader)
984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      ZIP_NEXT_U16 (zipEntry->fileCommentLength, current);
986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      current += 8;             /* skip disk number start + internal attrs + external attrs */
987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      ZIP_NEXT_U32 (localEntryPointer, current);
988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (filename)
991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (zipFile->cache)
993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (!
995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              (readLength == zipEntry->filenameLength
996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project               || (findDirectory
997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                   && (readLength - 1) == zipEntry->filenameLength)))
998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* We knew exactly how much we were supposed to read, and this wasn't it */
1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              result = ZIP_ERR_FILE_CORRUPT;
1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              goto finished;
1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Allocate space for filename */
1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipEntry->filenameLength >= ZIP_INTERNAL_MAX)
1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipEntry->filename =
1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hymem_allocate_memory (zipEntry->filenameLength + 1);
1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (!zipEntry->filename)
1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_OUT_OF_MEMORY;
1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  else
1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipEntry->filename = zipEntry->internalFilename;
1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (readLength > zipEntry->filenameLength)
1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      readLength = zipEntry->filenameLength;
1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  memcpy (zipEntry->filename, current, readLength);
1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Read the rest of the filename if necessary.  Allocate space in HyZipEntry for it! */
1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (readLength < zipEntry->filenameLength)
1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result =
1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hyfile_read (zipFile->fd, zipEntry->filename + readLength,
1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     zipEntry->filenameLength - readLength);
1033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (result != (zipEntry->filenameLength - readLength))
1034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_FILE_READ_ERROR;
1036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer += result;
1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipEntry->filename[zipEntry->filenameLength] = '\0';
1041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* If we know what filename is supposed to be, compare it and make sure it matches */
1043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Note: CASE-SENSITIVE COMPARE because filenames in zips are case sensitive (even on platforms with
1044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     case-insensitive file systems) */
1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (filename)
1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (!
1048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ((findDirectory && zipEntry->filenameLength == (filenameLength + 1)
1049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            && zipEntry->filename[filenameLength] == '/'
1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            && !strncmp ((char *) zipEntry->filename, (const char *) filename,
1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                         filenameLength))
1052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project           || !strcmp ((const char *) zipEntry->filename,
1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                       (const char *) filename)))
1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          /* We seem to have read something totally invalid.. */
1056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_FILE_CORRUPT;
1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipEntry->filenamePointer = currentEntryPointer + headerSize;
1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipEntry->extraFieldPointer =
1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    localEntryPointer + 30 + zipEntry->filenameLength;
1064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipEntry->dataPointer =
1065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    zipEntry->extraFieldPointer + zipEntry->extraFieldLength;
1066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipEntry->extraField = NULL;
1067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipEntry->fileCommentPointer = 0;
1068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipEntry->fileComment = NULL;
1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipEntry->data = NULL;
1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (sig == ZIP_CentralHeader)
1072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      U_8 buf[2];
1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      U_8 *buf2 = buf;
1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      U_16 lost;
1076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Also, we know where the comment is */
1077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipEntry->fileCommentPointer = currentEntryPointer + headerSize +
1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        zipEntry->filenameLength + zipEntry->extraFieldLength;
1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (hyfile_seek (zipFile->fd, localEntryPointer + 28, HySeekSet) ==
1080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          localEntryPointer + 28)
1081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (hyfile_read (zipFile->fd, buf, 2) == 2)
1083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              ZIP_NEXT_U16 (lost, buf2);
1085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              zipEntry->dataPointer = zipEntry->extraFieldPointer + lost;
1086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              zipFile->pointer = localEntryPointer + 30;
1087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((sig == ZIP_LocalHeader)
1092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      && (zipEntry->compressionMethod == ZIP_CM_Deflated)
1093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      && (zipEntry->flags & 0x8))
1094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* What we just read doesn't tell us how big the compressed data is.  We have to do a heuristic search for a
1096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         valid data descriptor at the end of the compressed text */
1097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = scanForDataDescriptor (portLib, zipFile, zipEntry);
1098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (result < 0)
1099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto finished;
1100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Entry read successfully */
1103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (enumerationPointer)
1105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Work out where the next entry is supposed to be */
1107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      *enumerationPointer =
1108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        zipEntry->fileCommentPointer + zipEntry->fileCommentLength;
1109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (readBuffer)
1112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    hymem_free_memory (readBuffer);
1113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return 0;
1114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfinished:
1116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (readBuffer)
1117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      hymem_free_memory (readBuffer);
1119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((zipEntry->filename)
1121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      && (zipEntry->filename != zipEntry->internalFilename))
1122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      hymem_free_memory (zipEntry->filename);
1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipEntry->filename = NULL;
1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (result == ZIP_ERR_FILE_READ_ERROR)
1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer = -1;
1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return result;
1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zip_closeZipFile
1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Attempt to close the zipfile.
1138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] portLib the port library
1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] zipFile The zip file to be closed
1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 0 on success
1143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_FILE_CLOSE_ERROR if there is an error closing the file
1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_INTERNAL_ERROR if there is an internal error
1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32 VMCALL
1148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzip_closeZipFile (HyPortLibrary * portLib, struct HyZipFile * zipFile)
1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
1151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(HY_NO_THR)
1152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  THREAD_ACCESS_FROM_PORT(portLib);
1153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif /* HY_NO_THR */
1154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA fd;
1155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ENTER ();
1157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  fd = zipFile->fd;
1159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipFile->fd = -1;
1160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipFile->cache && zipFile->cachePool)
1162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipCachePool_release (zipFile->cachePool, zipFile->cache);
1164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->cache = NULL;
1165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((zipFile->filename) && (zipFile->filename != zipFile->internalFilename))
1167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      hymem_free_memory (zipFile->filename);
1169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipFile->filename = NULL;
1171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (fd == -1)
1173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      EXIT ();
1175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return ZIP_ERR_INTERNAL_ERROR;
1176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (hyfile_close (fd))
1178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      EXIT ();
1180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return ZIP_ERR_FILE_CLOSE_ERROR;
1181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  EXIT ();
1183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return 0;
1184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
1187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zip_establishCache
1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
1190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Called to set up a cache when a zip file is opened with a cachePool but without a cache, or when the
1191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	current cache is found to be invalid in some way.
1192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] portLib the port library
1194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] zipFile the zip file for which we want to establish a cache
1195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * The current cache is marked as invalid such that new instances of zip files
1197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * won't try to use it and an attempt is made to establish a new cache.
1198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 0 on success
1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_FILE_READ_ERROR if there is an error reading from zipFile
1201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_FILE_OPEN_ERROR if is there is an error opening the file
1202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_UNKNOWN_FILE_TYPE if the file type is unknown
1203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_UNSUPPORTED_FILE_TYPE if the file type is unsupported
1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_OUT_OF_MEMORY  if there is not enough memory to complete this call
1205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_INTERNAL_ERROR if there was an internal error
1206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32
1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzip_establishCache (HyPortLibrary * portLib, HyZipFile * zipFile)
1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_32 result;
1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_64 timeStamp, actualFileSize;
1214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA fileSize, filenameLength;
1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipFile->cache)
1217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (zipFile->cachePool)
1219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          /* Whack cache timestamp to keep other people from starting to use it (we will create a new one for them
1221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             to start to use instead).  Once all the current users of the cache have stopped using it, it will go away */
1222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->cache->zipTimeStamp = -2;
1223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipCachePool_release (zipFile->cachePool, zipFile->cache);
1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->cache = NULL;
1226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (!zipFile->cachePool)
1228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return ZIP_ERR_INTERNAL_ERROR;
1230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Check the cachePool for a suitable cache. */
1233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  filenameLength = strlen ((const char *) zipFile->filename);
1234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//  timeStamp = hyfile_lastmod ((const char *) zipFile->filename);
1236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//  actualFileSize = hyfile_length ((const char *) zipFile->filename);
1237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  {
1238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    struct stat st;
1239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    tzset ();
1240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    stat ((mcSignednessBull)zipFile->filename, &st);
1241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    timeStamp = (U_64)st.st_mtime * 1000;
1242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    actualFileSize = (I_64) st.st_size;
1243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  }
1244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((actualFileSize < 0) || (actualFileSize > HYCONST64 (0x7FFFFFFF)))
1246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return ZIP_ERR_INTERNAL_ERROR;
1248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  fileSize = (IDATA) actualFileSize;
1250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipFile->cache =
1252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    zipCachePool_findCache (zipFile->cachePool,
1253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            (const char *) zipFile->filename, filenameLength,
1254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                            fileSize, timeStamp);
1255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (!zipFile->cache)
1256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Build a new cache.  Because caller asked for a cache, fail if we can't provide one */
1258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->cache =
1259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        zipCache_new (portLib, (char *) zipFile->filename, filenameLength);
1260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (!zipFile->cache)
1261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return ZIP_ERR_OUT_OF_MEMORY;
1262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->cache->zipFileSize = fileSize;
1264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->cache->zipTimeStamp = timeStamp;
1265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = zip_populateCache (portLib, zipFile);
1267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (result != 0)
1268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipCache_kill (zipFile->cache);
1270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->cache = NULL;
1271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return result;
1272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (!zipCachePool_addCache (zipFile->cachePool, zipFile->cache))
1274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipCache_kill (zipFile->cache);
1276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->cache = NULL;
1277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_OUT_OF_MEMORY;
1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return 0;
1281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
1284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zip_initZipEntry
1286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
1287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Initialize a zip entry.
1288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Should be called before the entry is passed to any other zip support functions
1290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] portLib the port library
1292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] entry the zip entry to init
1293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return none
1295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
1296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid
1298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzip_initZipEntry (HyPortLibrary * portLib, HyZipEntry * entry)
1299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  memset (entry, 0, sizeof (*entry));
1301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
1304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zip_freeZipEntry
1306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
1307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free any memory associated with a zip entry.
1308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] portLib the port library
1310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] entry the zip entry we are freeing
1311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return none
1313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @note This does not free the entry itself.
1315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
1316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid
1318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzip_freeZipEntry (HyPortLibrary * portLib, HyZipEntry * entry)
1319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
1321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((entry->filename) && (entry->filename != entry->internalFilename))
1323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      hymem_free_memory (entry->filename);
1325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  entry->filename = NULL;
1327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (entry->extraField)
1328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      hymem_free_memory (entry->extraField);
1330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      entry->extraField = NULL;
1331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (entry->data)
1333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      hymem_free_memory (entry->data);
1335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      entry->data = NULL;
1336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (entry->fileComment)
1338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      hymem_free_memory (entry->fileComment);
1340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      entry->fileComment = NULL;
1341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
1345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zip_getNextZipEntry
1347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
1348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	Read the next zip entry at nextEntryPointer into zipEntry.
1349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Any memory held onto by zipEntry may be lost, and therefore
1351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	MUST be freed with @ref zip_freeZipEntry first.
1352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] portLib the port library
1354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] zipFile The zip file being read
1355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[out] zipEntry compressed data is placed here
1356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] nextEntryPointer
1357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 0 on success
1359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_FILE_READ_ERROR if there is an error reading zipFile
1360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return ZIP_ERR_FILE_CORRUPT if zipFile is corrupt
1361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_NO_MORE_ENTRIES if there are no more entries in zipFile
1362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_OUT_OF_MEMORY if there is not enough memory to complete this call
1363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see zip_freeZipEntry
1365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
1367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32
1368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzip_getNextZipEntry (HyPortLibrary * portLib, HyZipFile * zipFile,
1369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     HyZipEntry * zipEntry, IDATA * nextEntryPointer)
1370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
1372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(HY_NO_THR)
1373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  THREAD_ACCESS_FROM_PORT(portLib);
1374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif /* HY_NO_THR */
1375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA result;
1376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  BOOLEAN retryAllowed = TRUE;
1377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA pointer;
1378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA entryStart;
1379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_64 seekResult;
1380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ENTER ();
1382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectretry:
1384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  pointer = *nextEntryPointer;
1385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Seek to the entry's position in the file. */
1387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (pointer != zipFile->pointer)
1388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      seekResult = hyfile_seek (zipFile->fd, pointer, HySeekSet);
1390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if ((seekResult < 0) || (seekResult > HYCONST64 (0x7FFFFFFF)))
1391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
1393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          EXIT ();
1394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_FILE_READ_ERROR;
1395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer = (I_32) seekResult;
1397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (pointer != zipFile->pointer)
1399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
1401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          EXIT ();
1402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_FILE_READ_ERROR;
1403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Read the entry */
1407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  entryStart = *nextEntryPointer;
1408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  result =
1409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    readZipEntry (portLib, zipFile, zipEntry, NULL, &pointer, &entryStart,
1410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  FALSE);
1411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (result != 0)
1412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (!retryAllowed || (result == ZIP_ERR_NO_MORE_ENTRIES))
1414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          EXIT ();
1416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return result;
1417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zip_establishCache (portLib, zipFile);
1419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      retryAllowed = FALSE;
1420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      goto retry;
1421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipFile->cache)
1424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Validity check: look up filename in the cache... */
1426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result =
1427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        (IDATA) zipCache_findElement (zipFile->cache,
1428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                      (const char *) zipEntry->filename,
1429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                      FALSE);
1430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (result != entryStart)
1431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (result >= zipFile->cache->startCentralDir)
1433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* ! Cache contents are not valid.  Invalidate it and make a new one */
1435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (!retryAllowed)
1436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
1437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  EXIT ();
1438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  return ZIP_ERR_FILE_CORRUPT;  /* should never happen! */
1439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
1440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              result = zip_establishCache (portLib, zipFile);
1441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (result)
1442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
1443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  /* (silently start operating without a cache if we couldn't make a new one) */
1444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
1445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              else
1446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
1447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  retryAllowed = FALSE;
1448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  goto retry;
1449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
1450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          else
1452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              /* We know that the central header for this entry contains info that the
1454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 local header is missing (comment length and/or uncompressed size) */
1455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              zipEntry->fileCommentPointer = -1;
1456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  *nextEntryPointer = pointer;
1461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  EXIT ();
1462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return 0;
1463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
1466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zip_getZipEntry
1468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
1469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	Attempt to find and read the zip entry corresponding to filename.
1470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	If found, read the entry into the parameter entry.
1471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If an uncached entry is found, the filename field will be filled in. This
1473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * memory will have to be freed with @ref zip_freeZipEntry.
1474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] portLib the port library
1476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] zipFile the file being read from
1477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[out] entry the zip entry found in zipFile is read to here
1478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] filename the name of the file that corresponds to entry
1479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] findDirectory when true, match a directory even if filename does not end in '/'.
1480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *			Note findDirectory is only supported (for the JCL) when there is a cache
1481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 0 on success or one of the following:
1483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_FILE_READ_ERROR if there is an error reading from zipFile
1484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_FILE_CORRUPT if zipFile is corrupt
1485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_ENTRY_NOT_FOUND if a zip entry with name filename was not found
1486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_OUT_OF_MEMORY if there is not enough memory to complete this call
1487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see zip_freeZipEntry
1489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
1490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32
1492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzip_getZipEntry (HyPortLibrary * portLib, HyZipFile * zipFile,
1493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 HyZipEntry * entry, const char *filename,
1494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 BOOLEAN findDirectory)
1495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
1497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(HY_NO_THR)
1498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  THREAD_ACCESS_FROM_PORT(portLib);
1499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif /* HY_NO_THR */
1500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA result, position;
1501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  BOOLEAN retryAllowed = TRUE;
1502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_64 seekResult;
1503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ENTER ();
1505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectretry:
1507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipFile->cache)
1508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Look up filename in the cache. */
1510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      position =
1511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        (IDATA) zipCache_findElement (zipFile->cache, filename,
1512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                      findDirectory);
1513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (position == -1)
1514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          /* Note: we assume the cache is still valid here */
1516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          EXIT ();
1517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_ENTRY_NOT_FOUND;
1518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Seek to the entry's position in the file. */
1521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (zipFile->pointer != position)
1522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          seekResult = hyfile_seek (zipFile->fd, position, HySeekSet);
1524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if ((seekResult < 0) || (seekResult > HYCONST64 (0x7FFFFFFF)))
1525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              zipFile->pointer = -1;
1527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              EXIT ();
1528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              return ZIP_ERR_FILE_READ_ERROR;
1529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = (I_32) seekResult;
1531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (zipFile->pointer != position)
1533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              zipFile->pointer = -1;
1535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              EXIT ();
1536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              return ZIP_ERR_FILE_READ_ERROR;
1537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Read the entry */
1541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result =
1542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        readZipEntry (portLib, zipFile, entry, filename, NULL, NULL,
1543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                      findDirectory);
1544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (result != 0)
1545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (!retryAllowed)
1547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              EXIT ();
1549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              return result;
1550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = zip_establishCache (portLib, zipFile);       /* invalidate existing cache */
1552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (result)
1553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              EXIT ();
1555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              return result;
1556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          retryAllowed = FALSE;
1558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto retry;
1559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      EXIT ();
1561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return 0;
1562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  else
1564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Uh oh -- random access without a cache (SLOW!) */
1566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      position = 0;
1567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zip_resetZipFile (PORTLIB, zipFile, &position);
1568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      while (TRUE)
1569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (zipFile->pointer != position)
1572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              seekResult = hyfile_seek (zipFile->fd, position, HySeekSet);
1574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if ((seekResult < 0) || (seekResult > HYCONST64 (0x7FFFFFFF)))
1575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
1576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  zipFile->pointer = -1;
1577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  EXIT ();
1578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  return ZIP_ERR_FILE_READ_ERROR;
1579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
1580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              zipFile->pointer = (I_32) seekResult;
1581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              if (zipFile->pointer != position)
1583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                {
1584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  zipFile->pointer = -1;
1585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  EXIT ();
1586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  return ZIP_ERR_FILE_READ_ERROR;
1587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
1588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result =
1591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            readZipEntry (portLib, zipFile, entry, NULL, &position, NULL,
1592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                          FALSE);
1593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (result || !strcmp ((const char *) entry->filename, filename))
1594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              EXIT ();
1596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              return result;
1597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          /* No match.  Reset for next entry */
1600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zip_freeZipEntry (portLib, entry);
1601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zip_initZipEntry (portLib, entry);
1602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
1607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zip_getZipEntryData
1609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
1610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	Attempt to read and uncompress the data for the zip entry entry.
1611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	If buffer is non-NULL it is used, but not explicitly held onto by the entry.
1613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	If buffer is NULL, memory is allocated and held onto by the entry, and thus
1614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	should later be freed with @ref zip_freeZipEntry.
1615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] portLib the port library
1617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] zipFile the zip file being read from.
1618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in,out] entry the zip entry
1619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] buffer may or may not be NULL
1620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] bufferSize
1621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 0 on success
1623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_FILE_READ_ERROR if there is an error reading from zipEntry
1624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_FILE_CORRUPT if zipFile is corrupt
1625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_ENTRY_NOT_FOUND if entry is not found
1626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_OUT_OF_MEMORY  if there is not enough memory to complete this call
1627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_BUFFER_TOO_SMALL if buffer is too small to hold the comment for zipFile
1628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see zip_freeZipEntry
1630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
1632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32
1633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzip_getZipEntryData (HyPortLibrary * portLib, HyZipFile * zipFile,
1634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     HyZipEntry * entry, U_8 * buffer, U_32 bufferSize)
1635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
1637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(HY_NO_THR)
1638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  THREAD_ACCESS_FROM_PORT(portLib);
1639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif /* HY_NO_THR */
1640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_32 result;
1642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_8 *dataBuffer;
1643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  struct workBuffer wb;
1644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_64 seekResult;
1645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ENTER ();
1647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  wb.portLib = portLib;
1649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  wb.bufferStart = wb.bufferEnd = wb.currentAlloc = 0;
1650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (buffer)
1652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (bufferSize < entry->uncompressedSize)
1654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          EXIT ();
1656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_BUFFER_TOO_SMALL;
1657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      dataBuffer = buffer;
1659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  else
1661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Note that this is the first zalloc. This memory must be available to the calling method and is freed explicitly in zip_freeZipEntry. */
1663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Note that other allocs freed in zip_freeZipEntry are not alloc'd using zalloc */
1664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      dataBuffer = zdataalloc (&wb, 1, entry->uncompressedSize);
1665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (!dataBuffer)
1666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          EXIT ();
1668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_OUT_OF_MEMORY;
1669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      entry->data = dataBuffer;
1671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (entry->compressionMethod == ZIP_CM_Stored)
1674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* No compression - just read the data in. */
1676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (zipFile->pointer != entry->dataPointer)
1677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          seekResult =
1679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            hyfile_seek (zipFile->fd, entry->dataPointer, HySeekSet);
1680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if ((seekResult < 0) || (seekResult > HYCONST64 (0x7FFFFFFF)))
1681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              zipFile->pointer = -1;
1683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              result = ZIP_ERR_FILE_READ_ERROR;
1684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              goto finished;
1685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = (I_32) seekResult;
1687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (zipFile->pointer != entry->dataPointer)
1689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              result = ZIP_ERR_FILE_READ_ERROR;
1691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              goto finished;
1692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = hyfile_read (zipFile->fd, dataBuffer, entry->compressedSize);
1695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (result != (I_32) entry->compressedSize)
1696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_FILE_READ_ERROR;
1698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
1699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer += result;
1701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      EXIT ();
1702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return 0;
1703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (entry->compressionMethod == ZIP_CM_Deflated)
1706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      U_8 *readBuffer;
1708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Ensure that the library is loaded. */
1710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     if (checkZipLibrary (portLib))
1711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_UNSUPPORTED_FILE_TYPE;
1713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
1714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Read the file contents. */
1717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      readBuffer = zdataalloc (&wb, 1, entry->compressedSize);
1718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (!readBuffer)
1719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_OUT_OF_MEMORY;
1721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
1722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (zipFile->pointer != entry->dataPointer)
1724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          seekResult =
1726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            hyfile_seek (zipFile->fd, entry->dataPointer, HySeekSet);
1727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if ((seekResult < 0) || (seekResult > HYCONST64 (0x7FFFFFFF)))
1728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              zipFile->pointer = -1;
1730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              zdatafree (&wb, readBuffer);
1731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              result = ZIP_ERR_FILE_READ_ERROR;
1732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              goto finished;
1733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = (I_32) seekResult;
1735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (zipFile->pointer != entry->dataPointer)
1737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            {
1738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              zdatafree (&wb, readBuffer);
1739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              result = ZIP_ERR_FILE_READ_ERROR;
1740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project              goto finished;
1741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
1742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (hyfile_read (zipFile->fd, readBuffer, entry->compressedSize) !=
1744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          (I_32) entry->compressedSize)
1745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zdatafree (&wb, readBuffer);
1747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_FILE_READ_ERROR;
1748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
1749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer += (I_32) entry->compressedSize;
1751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* Deflate the data. */
1753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result =
1754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        inflateData (&wb, readBuffer, entry->compressedSize, dataBuffer,
1755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                     entry->uncompressedSize);
1756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zdatafree (&wb, readBuffer);
1757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (result)
1758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        goto finished;
1759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      EXIT ();
1760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return 0;
1761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Whatever this is, we can't decompress it */
1764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  result = ZIP_ERR_UNSUPPORTED_FILE_TYPE;
1765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfinished:
1767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (!buffer)
1768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      entry->data = NULL;
1770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zdatafree (&wb, dataBuffer);
1771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (result == ZIP_ERR_FILE_READ_ERROR)
1773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer = -1;
1775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  EXIT ();
1777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return result;
1778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
1781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zip_getZipEntryExtraField
1783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
1784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	Read the extra field of entry from the zip file filename.
1785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * buffer is used if non-NULL, but is not held onto by entry.
1787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If buffer is NULL, memory is allocated and held onto by entry, and MUST be freed later with
1789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	@ref zip_freeZipEntry.
1790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] portLib the port library
1792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] zipFile the zip file being read from.
1793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in,out] entry the zip entry concerned
1794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] buffer may or may not be NULL
1795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] bufferSize
1796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 0 on success or one of the following:
1798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return ZIP_ERR_FILE_READ_ERROR if there is an error reading from zipFile
1799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_FILE_CORRUPT if zipFile is corrupt
1800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_OUT_OF_MEMORY if there is not enough memory to complete this call
1801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_BUFFER_TOO_SMALL if the buffer was non-Null but not large enough to hold the contents of entry
1802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see zip_freeZipEntry
1804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
1805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32
1806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzip_getZipEntryExtraField (HyPortLibrary * portLib, HyZipFile * zipFile,
1807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                           HyZipEntry * entry, U_8 * buffer, U_32 bufferSize)
1808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
1810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(HY_NO_THR)
1811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  THREAD_ACCESS_FROM_PORT(portLib);
1812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif /* HY_NO_THR */
1813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_32 result;
1815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_8 *extraFieldBuffer;
1816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_64 seekResult;
1817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ENTER ();
1819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (entry->extraFieldLength == 0)
1821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      EXIT ();
1823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return 0;
1824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (buffer)
1827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (bufferSize < entry->extraFieldLength)
1829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          EXIT ();
1831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_BUFFER_TOO_SMALL;
1832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      extraFieldBuffer = buffer;
1834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  else
1836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      extraFieldBuffer = hymem_allocate_memory (entry->extraFieldLength);
1838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (!extraFieldBuffer)
1839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          EXIT ();
1841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_OUT_OF_MEMORY;
1842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      entry->extraField = extraFieldBuffer;
1844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipFile->pointer != entry->extraFieldPointer)
1847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      seekResult =
1849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hyfile_seek (zipFile->fd, entry->extraFieldPointer, HySeekSet);
1850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if ((seekResult < 0) || (seekResult > HYCONST64 (0x7FFFFFFF)))
1851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
1853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_FILE_READ_ERROR;
1854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
1855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer = (I_32) seekResult;
1857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (zipFile->pointer != entry->extraFieldPointer)
1858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_FILE_READ_ERROR;
1860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
1861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  result =
1864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    hyfile_read (zipFile->fd, extraFieldBuffer, entry->extraFieldLength);
1865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (result != (I_32) entry->extraFieldLength)
1866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = ZIP_ERR_FILE_READ_ERROR;
1868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      goto finished;
1869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipFile->pointer += result;
1871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  EXIT ();
1872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return 0;
1873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfinished:
1875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (!buffer)
1876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      entry->extraField = NULL;
1878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      hymem_free_memory (extraFieldBuffer);
1879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (result == ZIP_ERR_FILE_READ_ERROR)
1881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    zipFile->pointer = -1;
1882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  EXIT ();
1883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return result;
1884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
1888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zip_getZipEntryFilename
1890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
1892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zip_getZipEntryComment
1894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
1895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	Read the file comment for entry.
1896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If buffer is non-NULL, it is used, but not held onto by entry.
1898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If buffer is NULL, memory is allocated and
1900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	held onto by entry, and thus should later be freed with @ref zip_freeZipEntry.
1901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
1902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] portLib the port library
1903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] zipFile the zip file concerned
1904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] entry the entry who's comment we want
1905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] buffer may or may not be NULL
1906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] bufferSize
1907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 0 on success or one of the following
1909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_FILE_READ_ERROR if there is an error reading the file comment from zipEntry
1910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_FILE_CORRUPT if zipFile is corrupt
1911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_ENTRY_NOT_FOUND if entry is not found
1912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_OUT_OF_MEMORY  if there is not enough memory to complete this call
1913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_BUFFER_TOO_SMALL if buffer is too small to hold the comment for zipFile
1914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
1915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32
1917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzip_getZipEntryComment (HyPortLibrary * portLib, HyZipFile * zipFile,
1918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                        HyZipEntry * entry, U_8 * buffer, U_32 bufferSize)
1919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
1921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(HY_NO_THR)
1922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  THREAD_ACCESS_FROM_PORT(portLib);
1923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif /* HY_NO_THR */
1924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_32 result;
1926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_8 *fileCommentBuffer;
1927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_64 seekResult;
1928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ENTER ();
1930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (entry->fileCommentLength == 0)
1932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (entry->fileCommentPointer == -1)
1934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          /* TODO: we don't know where the comment is (or even if there is one)! This only happens if you're running
1936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             without a cache, so too bad for now */
1937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      EXIT ();
1939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return 0;
1940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (buffer)
1943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (bufferSize < entry->fileCommentLength)
1945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          EXIT ();
1947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_BUFFER_TOO_SMALL;
1948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      fileCommentBuffer = buffer;
1950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  else
1952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      fileCommentBuffer = hymem_allocate_memory (entry->fileCommentLength);
1954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (!fileCommentBuffer)
1955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          EXIT ();
1957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_OUT_OF_MEMORY;
1958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      entry->fileComment = fileCommentBuffer;
1960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipFile->pointer != entry->fileCommentPointer)
1963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      seekResult =
1965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        hyfile_seek (zipFile->fd, entry->fileCommentPointer, HySeekSet);
1966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if ((seekResult < 0) || (seekResult > HYCONST64 (0x7FFFFFFF)))
1967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
1969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_FILE_READ_ERROR;
1970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
1971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer = (I_32) seekResult;
1973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (zipFile->pointer != entry->fileCommentPointer)
1975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
1976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_FILE_READ_ERROR;
1977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
1978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  result =
1981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    hyfile_read (zipFile->fd, fileCommentBuffer, entry->fileCommentLength);
1982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (result != (I_32) entry->fileCommentLength)
1983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = ZIP_ERR_FILE_READ_ERROR;
1985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      goto finished;
1986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipFile->pointer += result;
1988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  EXIT ();
1989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return 0;
1990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfinished:
1992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (!buffer)
1993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      entry->fileComment = NULL;
1995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      hymem_free_memory (fileCommentBuffer);
1996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (result == ZIP_ERR_FILE_READ_ERROR)
1998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer = -1;
2000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  EXIT ();
2002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return result;
2003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
2007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zip_openZipFile
2009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
2010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Attempt to open a zip file.
2011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * If the cache pool is non-NULL, the cachePool will be used to find a suitable cache, and if none can be found it will create one and add it to cachePool.
2013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Zip support is responsible for managing the lifetime of the cache.
2014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @note If cachePool is NULL, zipFile will be opened without a cache.
2016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] portLib the port library
2018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] filename the zip file to open
2019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[out] zipFile the zip file structure to populate
2020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] cachePool the cache pool
2021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 0 on success
2023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_FILE_OPEN_ERROR if is there is an error opening the file
2024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_FILE_READ_ERROR if there is an error reading the file
2025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_FILE_CORRUPT if the file is corrupt
2026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_UNKNOWN_FILE_TYPE if the file type is not known
2027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_UNSUPPORTED_FILE_TYPE if the file type is unsupported
2028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return	ZIP_ERR_OUT_OF_MEMORY if we are out of memory
2029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
2030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32
2031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzip_openZipFile (HyPortLibrary * portLib, char *filename, HyZipFile * zipFile,
2032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 HyZipCachePool * cachePool)
2033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
2035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(HY_NO_THR)
2036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  THREAD_ACCESS_FROM_PORT(portLib);
2037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif /* HY_NO_THR */
2038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  IDATA fd = -1;
2040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_32 result = 0;
2041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_64 seekResult;
2042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_8 buffer[4];
2043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_32 len;
2044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ENTER ();
2046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  len = strlen (filename);
2048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipFile->fd = -1;
2049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipFile->type = ZIP_Unknown;
2050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipFile->cache = NULL;
2051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipFile->cachePool = NULL;
2052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipFile->pointer = -1;
2053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Allocate space for filename */
2054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (len >= ZIP_INTERNAL_MAX)
2055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->filename = hymem_allocate_memory (len + 1);
2057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (!zipFile->filename)
2058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
2059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          EXIT ();
2060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_OUT_OF_MEMORY;
2061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  else
2064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->filename = zipFile->internalFilename;
2066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  strcpy ((char *) zipFile->filename, filename);
2069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  fd = hyfile_open (filename, HyOpenRead, 0);
2071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (fd == -1)
2072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = ZIP_ERR_FILE_OPEN_ERROR;
2074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      goto finished;
2075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (hyfile_read (fd, buffer, 4) != 4)
2078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = ZIP_ERR_FILE_READ_ERROR;
2080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      goto finished;
2081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((buffer[0] == 'P') && (buffer[1] == 'K'))
2084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* If not the central header or local file header, its corrupt */
2086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (!
2087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          ((buffer[2] == 1 && buffer[3] == 2)
2088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project           || (buffer[2] == 3 && buffer[3] == 4)))
2089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
2090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_FILE_CORRUPT;
2091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
2092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* PKZIP file. Back up the pointer to the beginning. */
2094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      seekResult = hyfile_seek (fd, 0, HySeekSet);
2095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (seekResult != 0)
2096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
2097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = ZIP_ERR_FILE_READ_ERROR;
2098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          goto finished;
2099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->fd = fd;
2102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->type = ZIP_PKZIP;
2103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer = 0;
2104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((buffer[0] == 0x1F) && (buffer[1] == 0x8B))
2107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      /* GZIP - currently unsupported.
2109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         zipFile->fd = fd;
2110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         zipFile->type = ZIP_GZIP;
2111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         zipFile->pointer = 2;
2112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project       */
2113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = ZIP_ERR_UNSUPPORTED_FILE_TYPE;
2114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      goto finished;
2115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipFile->type == ZIP_Unknown)
2118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = ZIP_ERR_UNKNOWN_FILE_TYPE;
2120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      goto finished;
2121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  result = 0;
2124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (cachePool)
2126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->cachePool = cachePool;
2128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      result = zip_establishCache (portLib, zipFile);
2129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfinished:
2132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (result == 0)
2133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->fd = fd;
2135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      EXIT ();
2136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      return 0;
2137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (fd != -1)
2139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      hyfile_close (fd);
2141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((zipFile->filename) && (zipFile->filename != zipFile->internalFilename))
2143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      hymem_free_memory (zipFile->filename);
2145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  zipFile->filename = NULL;
2147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  EXIT ();
2148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return result;
2149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
2152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zip_resetZipFile
2154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
2155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Reset nextEntryPointer to the first entry in the file.
2156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] portLib the port library
2158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] zipFile the zip being read from
2159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[out] nextEntryPointer will be reset to the first entry in the file
2160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return none
2162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
2165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid
2166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzip_resetZipFile (HyPortLibrary * portLib, HyZipFile * zipFile,
2167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                  IDATA * nextEntryPointer)
2168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  *nextEntryPointer = 0;
2170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipFile)
2171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (zipFile->cache)
2173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *nextEntryPointer = zipFile->cache->startCentralDir;
2174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      else
2175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
2176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          I_32 result;
2177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          HyZipCentralEnd endEntry;
2178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          result = scanForCentralEnd (portLib, zipFile, &endEntry);
2179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          if (result != 0)
2180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
2181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          *nextEntryPointer = (IDATA) ((UDATA) endEntry.dirOffset);
2182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
2187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zip_getZipEntryFromOffset
2189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
2190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Attempt to read a zip entry at offset from the zip file provided.
2191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	If found, read into entry.
2192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @note If an uncached entry is found, the filename field will be filled in. This
2194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *	memory MUST be freed with @ref zip_freeZipEntry.
2195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] portLib the port library
2197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] zipFile the zip file being read
2198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[in] offset the offset into the zipFile of the desired zip entry
2199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @param[out] entry the compressed data
2200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 0 on success
2202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return ZIP_ERR_FILE_READ_ERROR if there is an error reading from @ref zipFile
2203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_FILE_CORRUPT if @ref zipFile is corrupt
2204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_ENTRY_NOT_FOUND if the entry is not found
2205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @return 	ZIP_ERR_OUT_OF_MEMORY if there is not enough memory to complete this call
2206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
2207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * @see zip_freeZipEntry
2208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
2209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectI_32
2210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzip_getZipEntryFromOffset (HyPortLibrary * portLib, HyZipFile * zipFile,
2211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                           HyZipEntry * entry, IDATA offset)
2212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (portLib);
2214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#if defined(HY_NO_THR)
2215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  THREAD_ACCESS_FROM_PORT(portLib);
2216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif /* HY_NO_THR */
2217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_32 result;
2218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  I_64 seekResult;
2219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  ENTER ();
2221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (zipFile->pointer != offset)
2223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      seekResult = hyfile_seek (zipFile->fd, offset, HySeekSet);
2225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if ((seekResult < 0) || (seekResult > HYCONST64 (0x7FFFFFFF)))
2226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
2227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
2228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          EXIT ();
2229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_FILE_READ_ERROR;
2230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      zipFile->pointer = (I_32) seekResult;
2232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (zipFile->pointer != offset)
2233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
2234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          zipFile->pointer = -1;
2235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          EXIT ();
2236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          return ZIP_ERR_FILE_READ_ERROR;
2237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  result = readZipEntry (portLib, zipFile, entry, NULL, NULL, NULL, FALSE);
2241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  EXIT ();
2242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return result;
2243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
2246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zdataalloc
2248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	cached alloc management for zip_getZipEntryData.
2250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
2251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid *
2252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzdataalloc (void *opaque, U_32 items, U_32 size)
2253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  UDATA *returnVal = 0;
2255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_32 byteSize = items * size;
2256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  U_32 allocSize = WORK_BUFFER_SIZE;
2257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  struct workBuffer *wb = (struct workBuffer *) opaque;
2258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (wb->portLib);
2260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  /* Round to UDATA multiple */
2262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  byteSize = (byteSize + (sizeof (UDATA) - 1)) & ~(sizeof (UDATA) - 1);
2263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if (wb->bufferStart == 0)
2265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (byteSize > WORK_BUFFER_SIZE)
2267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
2268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          allocSize = byteSize;
2269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      wb->bufferStart = hymem_allocate_memory (allocSize);
2271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      if (wb->bufferStart)
2272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
2273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          wb->bufferEnd = (UDATA *) ((UDATA) wb->bufferStart + allocSize);
2274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          wb->currentAlloc = wb->bufferStart;
2275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project          wb->cntr = 0;
2276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((wb->bufferStart == 0)
2280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      || (((UDATA) wb->currentAlloc + byteSize) > (UDATA) wb->bufferEnd))
2281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      returnVal = hymem_allocate_memory (byteSize);
2283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  else
2285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      ++(wb->cntr);
2287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      returnVal = wb->currentAlloc;
2288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      wb->currentAlloc = (UDATA *) ((UDATA) wb->currentAlloc + byteSize);
2289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  return returnVal;
2291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
2294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CDEV_CURRENT_FUNCTION zdatafree
2296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project	cached alloc management for zip_getZipEntryData.
2298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project*/
2299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid
2300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectzdatafree (void *opaque, void *address)
2301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  struct workBuffer *wb = (struct workBuffer *) opaque;
2303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  PORT_ACCESS_FROM_PORT (wb->portLib);
2305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  if ((address < (void *) wb->bufferStart)
2307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      || (address >= (void *) wb->bufferEnd))
2308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      hymem_free_memory (address);
2310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project  else if (--(wb->cntr) == 0)
2312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
2313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      hymem_free_memory (wb->bufferStart);
2314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project      wb->bufferStart = wb->bufferEnd = wb->currentAlloc = 0;
2315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef CDEV_CURRENT_FUNCTION
2320