-
Notifications
You must be signed in to change notification settings - Fork 3
/
libpartial.h
223 lines (187 loc) · 5.32 KB
/
libpartial.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
/* OpenSn0w
* Open source equivalent of redsn0w
* Brought to you by rms, acfrazier & Maximus
* Special thanks to iH8sn0w & MuscleNerd
* libpartial is Copyright (C) 2010 David Wang
*
* this version of libpartial has been modified by:
* Copyright (C) 2010 Joshua Hill
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LIBPARTIAL_H
#define LIBPARTIAL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <inttypes.h>
#include <curl/curl.h>
#ifdef _MSC_VER
#define STATIC_INLINE static __inline
#else
#define STATIC_INLINE static inline
#endif
#ifdef _WIN32
#define fseeko fseeko64
#define ftello ftello64
#define off_t off64_t
#define mkdir(x, y) mkdir(x)
#define PATH_SEPARATOR "\\"
#define sleep(n) Sleep(1000 * n)
#else
#define PATH_SEPARATOR "/"
#endif
#define TRUE 1
#define FALSE 0
#define FLIPENDIAN(x) flipEndian((unsigned char *)(&(x)), sizeof(x))
#define FLIPENDIANLE(x) flipEndianLE((unsigned char *)(&(x)), sizeof(x))
#define IS_BIG_ENDIAN 0
#define IS_LITTLE_ENDIAN 1
#define TIME_OFFSET_FROM_UNIX 2082844800L
#define APPLE_TO_UNIX_TIME(x) ((x) - TIME_OFFSET_FROM_UNIX)
#define UNIX_TO_APPLE_TIME(x) ((x) + TIME_OFFSET_FROM_UNIX)
#define ASSERT(x, m) if(!(x)) { fflush(stdout); fprintf(stderr, "error: %s\n", m); perror("error"); fflush(stderr); exit(1); }
extern char endianness;
STATIC_INLINE void flipEndian(unsigned char* x, int length) {
int i;
unsigned char tmp;
if(endianness == IS_BIG_ENDIAN) {
return;
} else {
for(i = 0; i < (length / 2); i++) {
tmp = x[i];
x[i] = x[length - i - 1];
x[length - i - 1] = tmp;
}
}
}
STATIC_INLINE void flipEndianLE(unsigned char* x, int length) {
int i;
unsigned char tmp;
if(endianness == IS_LITTLE_ENDIAN) {
return;
} else {
for(i = 0; i < (length / 2); i++) {
tmp = x[i];
x[i] = x[length - i - 1];
x[length - i - 1] = tmp;
}
}
}
STATIC_INLINE void hexToBytes(const char* hex, uint8_t** buffer, size_t* bytes) {
size_t i;
*bytes = strlen(hex) / 2;
*buffer = (uint8_t*) malloc(*bytes);
for(i = 0; i < *bytes; i++) {
uint32_t byte;
sscanf(hex, "%2x", &byte);
(*buffer)[i] = byte;
hex += 2;
}
}
STATIC_INLINE void hexToInts(const char* hex, unsigned int** buffer, size_t* bytes) {
size_t i;
*bytes = strlen(hex) / 2;
*buffer = (unsigned int*) malloc((*bytes) * sizeof(int));
for(i = 0; i < *bytes; i++) {
sscanf(hex, "%2x", &((*buffer)[i]));
hex += 2;
}
}
struct io_func_struct;
typedef int (*readFunc)(struct io_func_struct* io, off_t location, size_t size, void *buffer);
typedef int (*writeFunc)(struct io_func_struct* io, off_t location, size_t size, void *buffer);
typedef void (*closeFunc)(struct io_func_struct* io);
typedef struct io_func_struct {
void* data;
readFunc read;
writeFunc write;
closeFunc close;
} io_func;
#ifdef _MSC_VER
#define ATTRIBUTE_PACKED
#pragma pack(push)
#pragma pack(1)
#else
#define ATTRIBUTE_PACKED __attribute__ ((packed))
#endif
typedef struct EndOfCD {
uint32_t signature;
uint16_t diskNo;
uint16_t CDDiskNo;
uint16_t CDDiskEntries;
uint16_t CDEntries;
uint32_t CDSize;
uint32_t CDOffset;
uint16_t lenComment;
} ATTRIBUTE_PACKED EndOfCD;
typedef struct CDFile {
uint32_t signature;
uint16_t version;
uint16_t versionExtract;
uint16_t flags;
uint16_t method;
uint16_t modTime;
uint16_t modDate;
uint32_t crc32;
uint32_t compressedSize;
uint32_t size;
uint16_t lenFileName;
uint16_t lenExtra;
uint16_t lenComment;
uint16_t diskStart;
uint16_t internalAttr;
uint32_t externalAttr;
uint32_t offset;
} ATTRIBUTE_PACKED CDFile;
typedef struct LocalFile {
uint32_t signature;
uint16_t versionExtract;
uint16_t flags;
uint16_t method;
uint16_t modTime;
uint16_t modDate;
uint32_t crc32;
uint32_t compressedSize;
uint32_t size;
uint16_t lenFileName;
uint16_t lenExtra;
} ATTRIBUTE_PACKED LocalFile;
#ifdef _MSC_VER
#pragma pack(pop)
#endif
typedef struct ZipInfo ZipInfo;
typedef void (*PartialZipProgressCallback)(ZipInfo* info, CDFile* file, size_t progress);
struct ZipInfo {
char* url;
uint64_t length;
CURL* hIPSW;
char* centralDirectory;
size_t centralDirectoryRecvd;
EndOfCD* centralDirectoryDesc;
char centralDirectoryEnd[0xffff + sizeof(EndOfCD)];
size_t centralDirectoryEndRecvd;
PartialZipProgressCallback progressCallback;
};
int download_file_from_zip(const char* url, const char* path, const char* output, PartialZipProgressCallback progressCallback);
ZipInfo* PartialZipInit(const char* url);
CDFile* PartialZipFindFile(ZipInfo* info, const char* fileName);
CDFile* PartialZipListFiles(ZipInfo* info);
unsigned char* PartialZipGetFile(ZipInfo* info, CDFile* file);
void PartialZipRelease(ZipInfo* info);
void PartialZipSetProgressCallback(ZipInfo* info, PartialZipProgressCallback progressCallback);
#ifdef __cplusplus
}
#endif
#endif