13 typedef unsigned long long UINT64;
14 typedef unsigned long UINT32;
16 #define BUF_SIZE 65536
28 off_t find_string(unsigned char *buf, size_t buf_size, char *search)
30 size_t length = strlen(search);
33 for (result = 0; result < (buf_size - length); result++)
35 if (!memcmp(&buf[result], search, length))
41 off_t parse_data_block(off_t offset, unsigned char *buf, size_t buf_size)
43 /* Parse the contents of this data block... */
47 printf("\nDATA block found at offset %lld\n", offset);
48 dataLen = (UINT64)buf[4];
49 dataLen |= (UINT64)buf[5] << 8;
50 dataLen |= (UINT64)buf[6] << 16;
51 dataLen |= (UINT64)buf[7] << 24;
52 dataLen |= (UINT64)buf[8] << 32;
53 dataLen |= (UINT64)buf[9] << 40;
54 printf(" compressed block size %llu bytes\n", dataLen);
56 dataUnc = (UINT64)buf[10];
57 dataUnc |= (UINT64)buf[11] << 8;
58 dataUnc |= (UINT64)buf[12] << 16;
59 dataUnc |= (UINT64)buf[13] << 24;
60 dataUnc |= (UINT64)buf[14] << 32;
61 dataUnc |= (UINT64)buf[15] << 40;
62 printf(" uncompressed block size %llu bytes\n", dataUnc);
67 void base64_dump(unsigned char *buf, size_t buf_size)
69 const char *b64_enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
74 for (i = 0; i < buf_size ; i++)
76 value = (value << 8) | buf[i];
78 printf("%c", b64_enc[(value >> bits) & 63U]);
81 printf("%c", b64_enc[(value >> bits) & 63U]);
87 printf("%c", b64_enc[(value >> bits) & 63U]);
91 off_t parse_desc_block(off_t offset, unsigned char *buf, size_t buf_size)
93 /* Parse the contents of this data block... */
96 printf("\nDESC block found at offset %lld\n", offset);
97 descLen = (UINT64)buf[4];
98 descLen |= (UINT64)buf[5] << 8;
99 descLen |= (UINT64)buf[6] << 16;
100 descLen |= (UINT64)buf[7] << 24;
101 descLen |= (UINT64)buf[8] << 32;
102 descLen |= (UINT64)buf[9] << 40;
103 printf(" DESC block size is %llu bytes\n", descLen);
108 off_t parse_desc_data(off_t offset, unsigned char *buf, size_t buf_size)
111 printf(" DESC entry: block type %d\n", type);
118 skipLen = (UINT64)buf[1];
119 skipLen |= (UINT64)buf[2] << 8;
120 skipLen |= (UINT64)buf[3] << 16;
121 skipLen |= (UINT64)buf[4] << 24;
122 skipLen |= (UINT64)buf[5] << 32;
123 skipLen |= (UINT64)buf[6] << 40;
124 printf(" Unmatched data, %llu bytes\n", skipLen);
133 imglen = (UINT64)buf[1];
134 imglen |= (UINT64)buf[2] << 8;
135 imglen |= (UINT64)buf[3] << 16;
136 imglen |= (UINT64)buf[4] << 24;
137 imglen |= (UINT64)buf[5] << 32;
138 imglen |= (UINT64)buf[6] << 40;
140 blocklen = (UINT32)buf[23];
141 blocklen |= (UINT32)buf[24] << 8;
142 blocklen |= (UINT32)buf[25] << 16;
143 blocklen |= (UINT32)buf[26] << 24;
145 printf(" Original image length %llu bytes\n", imglen);
146 printf(" Image MD5: ");
147 for (i = 7; i < 23; i++)
148 printf("%2.2x", buf[i]);
150 base64_dump(&buf[7], 16);
152 printf("\n MD5 block length %lu bytes\n", blocklen);
153 return 0; /* i.e. we're finished! */
160 fileLen = (UINT64)buf[1];
161 fileLen |= (UINT64)buf[2] << 8;
162 fileLen |= (UINT64)buf[3] << 16;
163 fileLen |= (UINT64)buf[4] << 24;
164 fileLen |= (UINT64)buf[5] << 32;
165 fileLen |= (UINT64)buf[6] << 40;
167 printf(" File, length %llu bytes\n", fileLen);
168 printf(" file rsyncsum: ");
169 for (i = 7; i < 15; i++)
170 printf("%2.2x", buf[i]);
171 printf("\n file md5: ");
172 for (i = 15; i < 31; i++)
173 printf("%2.2x", buf[i]);
175 base64_dump(&buf[15], 16);
187 int main(int argc, char **argv)
189 char *filename = NULL;
191 unsigned char *buf = NULL;
194 e_state state = STARTING;
198 printf("No filename specified! Try again...\n");
204 fd = open(filename, O_RDONLY);
207 printf("Failed to open file %s, error %d!. Try again...\n", filename, errno);
211 buf = malloc(BUF_SIZE);
214 printf("Failed to malloc %d bytes. Abort!\n", BUF_SIZE);
218 /* Find the beginning of the data - read the first chunk, including the header */
219 while (STARTING == state)
221 off_t start_offset = -1;
223 bytes = read(fd, buf, BUF_SIZE);
229 start_offset = find_string(buf, bytes, "DATA");
230 if (start_offset >= 0)
232 offset += start_offset;
239 while (DONE != state && ERROR != state)
241 off_t start_offset = -1;
242 lseek(fd, offset, SEEK_SET);
243 bytes = read(fd, buf, BUF_SIZE);
249 if (IN_DATA == state)
251 if (!find_string(buf, bytes, "DATA"))
253 if (!find_string(buf, bytes, "DESC"))
259 start_offset = parse_data_block(offset, buf, bytes);
260 offset += start_offset;
263 start_offset = parse_desc_block(offset, buf, bytes);
264 offset += start_offset;
268 start_offset = parse_desc_data(offset, buf, bytes);
269 offset += start_offset;
270 if (0 == start_offset)