Mercurial > libpst
comparison archive/patch1 @ 57:de3753c3160a
add archive directory with history of alioth versions that have been merged here
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Sat, 02 Feb 2008 12:54:07 -0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
56:b504411ad213 | 57:de3753c3160a |
---|---|
1 diff -Naur ../orig/libpst-0.5.1/define.h libpst64-060926/define.h | |
2 --- ../orig/libpst-0.5.1/define.h 2004-11-17 07:48:03.000000000 -0700 | |
3 +++ libpst64-060926/define.h 2006-09-26 14:09:55.000000000 -0600 | |
4 @@ -5,7 +5,7 @@ | |
5 * dave.s@earthcorp.com | |
6 */ | |
7 | |
8 -//#define DEBUG_ALL | |
9 +#define DEBUG_ALL | |
10 #ifndef DEFINEH_H | |
11 #define DEFINEH_H | |
12 | |
13 diff -Naur ../orig/libpst-0.5.1/generic.c libpst64-060926/generic.c | |
14 --- ../orig/libpst-0.5.1/generic.c 1969-12-31 17:00:00.000000000 -0700 | |
15 +++ libpst64-060926/generic.c 2006-09-26 14:09:55.000000000 -0600 | |
16 @@ -0,0 +1,110 @@ | |
17 +// {{{ includes | |
18 + | |
19 +#include <ctype.h> | |
20 +#include <errno.h> | |
21 +#include <malloc.h> | |
22 +#include <signal.h> | |
23 +#include <stdarg.h> | |
24 +#include <stdio.h> | |
25 +#include <stdlib.h> | |
26 +#include <string.h> | |
27 +#include "generic.h" | |
28 + | |
29 +#ifdef WITH_DMALLOC | |
30 +#include <dmalloc.h> | |
31 +#endif | |
32 + | |
33 +// }}} | |
34 + | |
35 +// {{{ Macros: ASSERT(), DIE(), F_MALLOC() | |
36 +void pDIE( char *fmt, ... ) // {{{ Cough...cough | |
37 +{ | |
38 + va_list ap; | |
39 + va_start( ap, fmt ); | |
40 + //fprintf( stderr, "Fatal error (will segfault): "); | |
41 + vfprintf( stderr, fmt, ap ); | |
42 + fprintf( stderr, "\n" ); | |
43 + va_end(ap); | |
44 + raise( SIGSEGV ); | |
45 +} | |
46 +// }}} | |
47 +void pWARN( char *fmt, ... ) // {{{ Cough...cough | |
48 +{ | |
49 + va_list ap; | |
50 + va_start( ap, fmt ); | |
51 + fprintf( stderr, "WARNING: "); | |
52 + vfprintf( stderr, fmt, ap ); | |
53 + fprintf( stderr, "\n" ); | |
54 + va_end(ap); | |
55 +} | |
56 +// }}} | |
57 +void *F_MALLOC( size_t size ) // {{{ malloc() but dumps core when it fails | |
58 +{ | |
59 + void *result; | |
60 + | |
61 + result = malloc( size ); | |
62 + ASSERT( NULL != result, "malloc() failure." ); | |
63 + | |
64 + return result; | |
65 +} | |
66 +// }}} | |
67 +void *F_REALLOC( void *p, size_t size ) // {{{ realloc() but dumps core when it fails | |
68 +{ | |
69 + void *result; | |
70 + | |
71 + //if( NULL != p ) hexdump((char*)p - 128, 0, 128, 1 ); | |
72 + if(!p) { | |
73 + ASSERT( NULL != ( result = malloc( size ) ), "malloc() failure." ); | |
74 + } | |
75 + else { | |
76 + ASSERT( NULL != ( result = realloc( p, size ) ), "realloc() failure." ); | |
77 + } | |
78 + | |
79 + //hexdump((char*)result - 128, 0, 128, 1 ); | |
80 + fflush(stderr); | |
81 + return result; | |
82 +} | |
83 +// }}} | |
84 +// }}} | |
85 +// {{{ Program logging/debug output | |
86 +int DEBUG_LEVEL = DB_INFO; | |
87 + | |
88 +void db_default( char *file, int line, int level, char *fmt, ... ) // {{{ | |
89 +{ | |
90 + va_list ap; | |
91 + if( level <= DEBUG_LEVEL ) { | |
92 + switch( level ) { | |
93 + case DB_CRASH: | |
94 + fprintf(stderr, "CRASH"); | |
95 + break; | |
96 + case DB_ERR: | |
97 + fprintf(stderr, "ERROR"); | |
98 + break; | |
99 + case DB_WARN: | |
100 + fprintf(stderr, "WARNING"); | |
101 + break; | |
102 + case DB_INFO: | |
103 + case DB_VERB: | |
104 + break; | |
105 + default: | |
106 + fprintf(stderr, "DEBUG(%d)", level ); | |
107 + } | |
108 + | |
109 + if( level <= DB_WARN ) | |
110 + fprintf(stderr, " (%s:%d)", file, line ); | |
111 + | |
112 + if( DB_INFO != level && DB_VERB != level ) | |
113 + fprintf(stderr, ": "); | |
114 + | |
115 + va_start( ap, fmt ); | |
116 + vfprintf(stderr, fmt, ap ); | |
117 + fprintf(stderr, "\n" ); | |
118 + va_end( ap ); | |
119 + } | |
120 +} // }}} | |
121 + | |
122 +void (*dbfunc)(char *file, int line, int level, char *fmt, ...) = &db_default; | |
123 + | |
124 +//#define DEBUG(x) { x; } | |
125 +//#define DEBUG(x) ; | |
126 +// }}} | |
127 diff -Naur ../orig/libpst-0.5.1/generic.h libpst64-060926/generic.h | |
128 --- ../orig/libpst-0.5.1/generic.h 1969-12-31 17:00:00.000000000 -0700 | |
129 +++ libpst64-060926/generic.h 2006-09-26 14:09:55.000000000 -0600 | |
130 @@ -0,0 +1,48 @@ | |
131 +/* {{{ Generic.h - thigns every program does: | |
132 + * | |
133 + * - user output (log, debug, etc) | |
134 + * - crash and burn | |
135 + * - allocate memory (or explode) | |
136 + * }}} */ | |
137 +#ifndef GENERIC_H | |
138 +#define GENERIC_H | |
139 +#include <stdlib.h> | |
140 +#include <stdio.h> | |
141 +#include <stdarg.h> | |
142 +/***************************************************/ | |
143 + | |
144 +#define LOAD_DEBUG 1 | |
145 + | |
146 +#define DIE(...) { fprintf(stderr, "Fatal Error at %s,%d: ", __FILE__, __LINE__); pDIE(__VA_ARGS__); } | |
147 + | |
148 +//#define WARN(...) { fprintf(stderr, "WARN: %s,%d: ", __FILE__, __LINE__); pWARN(__VA_ARGS__); } | |
149 +void pDIE( char *fmt, ... ); | |
150 +//void pWARN( char *fmt, ... ); | |
151 + | |
152 +#define WARN(...) DB( DB_WARN, __VA_ARGS__ ) | |
153 +#define ASSERT(x,...) { if( !(x) ) DIE( __VA_ARGS__ ); } | |
154 + | |
155 +void *F_MALLOC( size_t size ); | |
156 +void *F_REALLOC( void *p, size_t size ); | |
157 + | |
158 +#define DO_DEBUG 0 | |
159 +#define DEBUG(x) if( DO_DEBUG ) { x; } | |
160 +#define STUPID_CR "\r\n" | |
161 + | |
162 +#define DB_CRASH 0 // crashing | |
163 +#define DB_ERR 1 // error | |
164 +#define DB_WARN 2 // warning | |
165 +#define DB_INFO 3 // normal, but significant, condition | |
166 +#define DB_VERB 4 // verbose information | |
167 +#define DB_0 5 // debug-level message | |
168 +#define DB_1 6 // debug-level message | |
169 +#define DB_2 7 // debug-level message | |
170 + | |
171 +extern int DEBUG_LEVEL; | |
172 +extern void (*dbfunc)(char *file, int line, int level, char *fmt, ...); | |
173 + | |
174 +#define DB(...) { dbfunc( __FILE__, __LINE__, __VA_ARGS__ ); } | |
175 + | |
176 +int set_db_function( void (*func)( char *file, int line, int level, char *fmt, ...) ); | |
177 + | |
178 +#endif | |
179 diff -Naur ../orig/libpst-0.5.1/libpst.c libpst64-060926/libpst.c | |
180 --- ../orig/libpst-0.5.1/libpst.c 2004-11-17 07:48:04.000000000 -0700 | |
181 +++ libpst64-060926/libpst.c 2006-09-26 14:09:55.000000000 -0600 | |
182 @@ -4,6 +4,7 @@ | |
183 * Written by David Smith | |
184 * dave.s@earthcorp.com | |
185 */ | |
186 +//{{{ | |
187 #include <stdio.h> | |
188 #include <stdlib.h> | |
189 #include <time.h> | |
190 @@ -12,11 +13,15 @@ | |
191 #include <limits.h> | |
192 #include <wchar.h> | |
193 | |
194 +#include <signal.h> | |
195 #include <errno.h> | |
196 #include <sys/stat.h> //mkdir | |
197 #include <fcntl.h> // for Win32 definition of _O_BINARY | |
198 #include "define.h" | |
199 #include "libstrfunc.h" | |
200 +#include "vbuf.h" | |
201 + | |
202 +#define ASSERT(x) { if(!(x)) raise( SIGSEGV ); } | |
203 | |
204 #ifdef _MSC_VER | |
205 # include <windows.h> | |
206 @@ -45,30 +50,54 @@ | |
207 //#define LE32_CPU(x) {} | |
208 //#define LE16_CPU(x) {} | |
209 //#endif // _MSC_VER | |
210 - | |
211 -#define FILE_SIZE_POINTER 0xA8 | |
212 -#define INDEX_POINTER 0xC4 | |
213 -#define SECOND_POINTER 0xBC | |
214 +// }}} | |
215 +#define FILE_SIZE_POINTER32 0xA8 | |
216 +#define INDEX_POINTER32 0xC4 | |
217 +#define INDEX_COUNT32 0xC0 | |
218 +#define SECOND_POINTER32 0xBC | |
219 +#define SECOND_COUNT32 0xB8 | |
220 #define INDEX_DEPTH 0x4C | |
221 #define SECOND_DEPTH 0x5C | |
222 // the encryption setting could be at 0x1CC. Will require field testing | |
223 -#define ENC_OFFSET 0x1CD | |
224 +#define ENC_OFFSET32 0x1CD | |
225 // says the type of index we have | |
226 -#define INDEX_TYPE_OFFSET 0x0A | |
227 +#define INDEX_TYPE_OFFSET32 0x0A | |
228 +#define INDEX_TYPE32 0x0E | |
229 +#define INDEX_TYPE64 0x17 //I think this is wrong | |
230 | |
231 // for the 64bit 2003 outlook PST we need new file offsets | |
232 // perhaps someone can figure out the header format for the pst files... | |
233 -#define FILE_SIZE_POINTER_64 0xB8 | |
234 -#define INDEX_POINTER_64 0xF0 | |
235 -#define SECOND_POINTER_64 0xE0 | |
236 +#define FILE_SIZE_POINTER64 0xB8 | |
237 +#define INDEX_POINTER64 0xF0 | |
238 +#define INDEX_COUNT64 0xE8 | |
239 +#define SECOND_POINTER64 0xE0 | |
240 +#define SECOND_COUNT64 0xD8 | |
241 +#define INDEX_TYPE_OFFSET64 0x0A | |
242 +#define ENC_OFFSET64 0x201 | |
243 + | |
244 +#define FILE_SIZE_POINTER ((do_read64)?FILE_SIZE_POINTER64:FILE_SIZE_POINTER32) | |
245 +#define INDEX_POINTER ((do_read64)?INDEX_POINTER64:INDEX_POINTER32) | |
246 +#define INDEX_TYPE_OFFSET ((do_read64)?INDEX_TYPE_OFFSET64:INDEX_TYPE_OFFSET32) | |
247 +#define INDEX_TYPE ((do_read64)?INDEX_TYPE64:INDEX_TYPE32) | |
248 +#define SECOND_POINTER ((do_read64)?SECOND_POINTER64:SECOND_POINTER32) | |
249 +#define SECOND_COUNT ((do_read64)?SECOND_COUNT64:SECOND_COUNT32) | |
250 +#define ENC_OFFSET ((do_read64)?ENC_OFFSET64:ENC_OFFSET32) | |
251 +#define INDEX_COUNT ((do_read64)?INDEX_COUNT64:INDEX_COUNT32) | |
252 | |
253 #define PST_SIGNATURE 0x4E444221 | |
254 | |
255 -struct _pst_table_ptr_struct{ | |
256 +int do_read64 = 0; //set this to 1 in order to try and read 64-bit pst files (Outlook 2003) | |
257 + | |
258 +struct _pst_table_ptr_struct32{ | |
259 int32_t start; | |
260 int32_t u1; | |
261 int32_t offset; | |
262 }; | |
263 +struct _pst_table_ptr_structn{ | |
264 + int64_t start; | |
265 + int64_t u1; | |
266 + int64_t offset; | |
267 +}; | |
268 | |
269 typedef struct _pst_block_header { | |
270 int16_t type; | |
271 @@ -119,6 +148,26 @@ | |
272 0xd4, 0xe1, 0x11, 0xd0, 0x08, 0x8b, 0x2a, 0xf2, | |
273 0xed, 0x9a, 0x64, 0x3f, 0xc1, 0x6c, 0xf9, 0xec}; /*0xff*/ | |
274 | |
275 +void set_read64() { do_read64 = 1; } | |
276 + | |
277 +void dump_desc( off_t off, int depth, int i, pst_descn *desc_rec ) { // {{{ | |
278 + | |
279 + //desc_rec->d_id = 0x0102030405060708; | |
280 + DEBUG_INDEX(("%08x [%i] Item(%#x) = [d_id = %#llx, desc_id = %#llx, " | |
281 + "list_id = %#llx, parent_id = %#x, u1 = %#x] %#x %p %p\n", | |
282 + off, | |
283 + depth, i, desc_rec->d_id, | |
284 + desc_rec->desc_id, desc_rec->list_id, desc_rec->parent_id, desc_rec->u1)); | |
285 + DEBUG_HEXDUMPC( (char*)desc_rec, sizeof( pst_descn ), 0x10 ); | |
286 + DEBUG_INDEX(("WTF? %d %x %x %x %x %x\n", | |
287 + sizeof( u_int32_t ), | |
288 + (int)(&desc_rec->d_id) - (int)desc_rec, | |
289 + (int)(&desc_rec->desc_id) - (int)desc_rec, | |
290 + (int)(&desc_rec->list_id) - (int)desc_rec, | |
291 + (int)(&desc_rec->parent_id) - (int)desc_rec, | |
292 + (int)(&desc_rec->u1) - (int)desc_rec )); | |
293 +} // }}} | |
294 + | |
295 int32_t pst_open(pst_file *pf, char *name, char *mode) { | |
296 u_int32_t sig; | |
297 // unsigned char ind_type; | |
298 @@ -158,9 +207,10 @@ | |
299 DEBUG_RET(); | |
300 return -1; | |
301 } | |
302 + | |
303 _pst_getAtPos(pf->fp, INDEX_TYPE_OFFSET, &(pf->ind_type), sizeof(unsigned char)); | |
304 DEBUG_INFO(("index_type = %i\n", pf->ind_type)); | |
305 - if (pf->ind_type != 0x0E) { | |
306 + if ( pf->ind_type != INDEX_TYPE) { | |
307 WARN(("unknown index structure. Could this be a new Outlook 2003 PST file?\n")); | |
308 DEBUG_RET(); | |
309 return -1; | |
310 @@ -170,23 +220,18 @@ | |
311 DEBUG_INFO(("encrypt = %i\n", pf->encryption)); | |
312 // pf->encryption = encrypt; | |
313 | |
314 - _pst_getAtPos(pf->fp, SECOND_POINTER-4, &(pf->index2_count), sizeof(pf->index2_count)); | |
315 - _pst_getAtPos(pf->fp, SECOND_POINTER, &(pf->index2), sizeof(pf->index2)); | |
316 - LE32_CPU(pf->index2_count); | |
317 - LE32_CPU(pf->index2); | |
318 + pf->index2_count = _pst_getIntAtPos(pf->fp, SECOND_COUNT); | |
319 + pf->index2 = _pst_getIntAtPos(pf->fp, SECOND_POINTER ); | |
320 | |
321 - _pst_getAtPos(pf->fp, FILE_SIZE_POINTER, &(pf->size), sizeof(pf->size)); | |
322 - LE32_CPU(pf->size); | |
323 + pf->size = _pst_getIntAtPos( pf->fp, FILE_SIZE_POINTER ); | |
324 | |
325 // very tempting to leave these values set way too high and let the exploration of the tables set them... | |
326 pf->index1_depth = pf->index2_depth = 255; | |
327 | |
328 DEBUG_INFO(("Pointer2 is %#X, count %i[%#x], depth %#x\n", | |
329 pf->index2, pf->index2_count, pf->index2_count, pf->index2_depth)); | |
330 - _pst_getAtPos(pf->fp, INDEX_POINTER-4, &(pf->index1_count), sizeof(pf->index1_count)); | |
331 - _pst_getAtPos(pf->fp, INDEX_POINTER, &(pf->index1), sizeof(pf->index1)); | |
332 - LE32_CPU(pf->index1_count); | |
333 - LE32_CPU(pf->index1); | |
334 + pf->index1_count = _pst_getIntAtPos(pf->fp, INDEX_COUNT); | |
335 + pf->index1 = _pst_getIntAtPos(pf->fp, INDEX_POINTER); | |
336 | |
337 DEBUG_INFO(("Pointer1 is %#X, count %i[%#x], depth %#x\n", | |
338 pf->index1, pf->index1_count, pf->index1_count, pf->index1_depth)); | |
339 @@ -495,18 +540,110 @@ | |
340 } | |
341 | |
342 #define BLOCK_SIZE 516 | |
343 +int _pst_decode_desc( pst_descn *desc, char *buf ) { // {{{ | |
344 + int r; | |
345 + if( do_read64 ) { | |
346 + | |
347 + DEBUG_INDEX(("Decoding desc64 ")); | |
348 + DEBUG_HEXDUMPC(buf, sizeof( pst_descn ), 0x10); | |
349 + memcpy(desc, buf, sizeof( pst_descn )); | |
350 + LE64_CPU(desc->d_id); | |
351 + LE64_CPU(desc->desc_id); | |
352 + LE64_CPU(desc->list_id); | |
353 + LE32_CPU(desc->parent_id); | |
354 + LE32_CPU(desc->u1); | |
355 + r = sizeof( pst_descn ); | |
356 + } | |
357 + else { | |
358 + pst_desc32 d32; | |
359 + DEBUG_INDEX(("Decoding desc32 ")); | |
360 + DEBUG_HEXDUMPC(buf, sizeof( d32 ), 0x10); | |
361 + memcpy(&d32, buf, sizeof(d32)); | |
362 + LE32_CPU(d32.d_id); | |
363 + LE32_CPU(d32.desc_id); | |
364 + LE32_CPU(d32.list_id); | |
365 + LE32_CPU(d32.parent_id); | |
366 + | |
367 + desc->d_id = d32.d_id; | |
368 + desc->desc_id = d32.desc_id; | |
369 + desc->list_id = d32.list_id; | |
370 + desc->parent_id = d32.parent_id; | |
371 + desc->u1 = 0; | |
372 + | |
373 + r = sizeof( d32 ); | |
374 + } | |
375 + | |
376 + return r; | |
377 +} // }}} | |
378 +int _pst_decode_table( struct _pst_table_ptr_structn *table, char *buf ) { // {{{ | |
379 + | |
380 + if( do_read64 ) { | |
381 + | |
382 + DEBUG_INDEX(("Decoding table64")); | |
383 + DEBUG_HEXDUMPC(buf, sizeof( struct _pst_table_ptr_structn ), 0x10); | |
384 + memcpy(table, buf, sizeof( struct _pst_table_ptr_structn ) ); | |
385 + LE64_CPU(table->start); | |
386 + LE64_CPU(table->u1); | |
387 + LE64_CPU(table->offset); | |
388 + | |
389 + return sizeof( struct _pst_table_ptr_structn ); | |
390 + } | |
391 + else { | |
392 + struct _pst_table_ptr_struct32 t32; | |
393 + memcpy(&t32, buf, sizeof(t32)); | |
394 + LE32_CPU(t32.start); | |
395 + LE32_CPU(t32.u1); | |
396 + LE32_CPU(t32.offset); | |
397 + table->start = t32.start; | |
398 + table->u1 = t32.u1; | |
399 + table->offset = t32.offset; | |
400 + | |
401 + return sizeof( struct _pst_table_ptr_struct32 ); | |
402 + } | |
403 + return 0; | |
404 +} // }}} | |
405 +int _pst_decode_index( pst_index *index, char *buf ) { // {{{ | |
406 + if( do_read64 ) { | |
407 + | |
408 + DEBUG_INDEX(("Decoding index64")); | |
409 + DEBUG_HEXDUMPC(buf, sizeof( pst_index ), 0x10); | |
410 + memcpy(index, buf, sizeof(pst_index)); | |
411 + LE64_CPU(index->id); | |
412 + LE64_CPU(index->offset); | |
413 + LE16_CPU(index->size); | |
414 + LE16_CPU(index->u0); | |
415 + LE16_CPU(index->u1); | |
416 + return sizeof( pst_index ); | |
417 + } else { | |
418 + pst_index32 index32; | |
419 + memcpy(&index32, buf, sizeof(pst_index32)); | |
420 + LE32_CPU(index32->id); | |
421 + LE32_CPU(index32->offset); | |
422 + LE16_CPU(index32->size); | |
423 + LE16_CPU(index32->u1); | |
424 + index->id = index32.id; | |
425 + index->offset = index32.offset; | |
426 + index->size = index32.size; | |
427 + index->u1 = index32.u1; | |
428 + | |
429 + return sizeof( pst_index32 ); | |
430 + } | |
431 | |
432 -int32_t _pst_build_id_ptr(pst_file *pf, int32_t offset, int32_t depth, int32_t start_val, int32_t end_val) { | |
433 - struct _pst_table_ptr_struct table, table2; | |
434 + return 0; | |
435 +} // }}} | |
436 + | |
437 +int32_t _pst_build_id_ptr(pst_file *pf, off_t offset, int32_t depth, int32_t start_val, int32_t end_val) { | |
438 + struct _pst_table_ptr_structn table, table2; | |
439 pst_index_ll *i_ptr=NULL; | |
440 pst_index index; | |
441 // int fpos = ftell(pf->fp); | |
442 int32_t x, ret; | |
443 int32_t old = start_val; | |
444 + off_t roff; | |
445 char *buf = NULL, *bptr = NULL; | |
446 | |
447 DEBUG_ENT("_pst_build_id_ptr"); | |
448 - if (pf->index1_depth - depth == 0) { | |
449 + if (pf->index1_depth - depth == 0) { // {{{ Leaf table, add indexes to linked list | |
450 // we must be at a leaf table. These are index items | |
451 DEBUG_INDEX(("Reading Items\n")); | |
452 // fseek(pf->fp, offset, SEEK_SET); | |
453 @@ -519,15 +656,14 @@ | |
454 } | |
455 bptr = buf; | |
456 // DEBUG_HEXDUMPC(buf, BLOCK_SIZE, 12); | |
457 - memcpy(&index, bptr, sizeof(index)); | |
458 - LE32_CPU(index.id); | |
459 - LE32_CPU(index.offset); | |
460 - LE16_CPU(index.size); | |
461 - LE16_CPU(index.u1); | |
462 - bptr += sizeof(index); | |
463 + roff = offset; | |
464 + bptr += _pst_decode_index( &index, bptr ); | |
465 | |
466 - while(index.id != 0 && x < 42 && bptr < buf+BLOCK_SIZE && index.id < end_val) { | |
467 - DEBUG_INDEX(("[%i]%i Item [id = %#x, offset = %#x, u1 = %#x, size = %i(%#x)]\n", depth, ++x, index.id, index.offset, index.u1, index.size, index.size)); | |
468 + while(index.id != 0 && x < 42 && bptr < buf+BLOCK_SIZE && index.id < end_val) { // {{{ | |
469 + DEBUG_INDEX(("%08x [%i]%i Item [ id = %#llx, offset = %#llx, u1 = %#x, size = %i(%#x)] %p %p\n", | |
470 + roff, | |
471 + depth, ++x, index.id, index.offset, index.u1, | |
472 + index.size, index.size, buf, bptr )); | |
473 if (index.id & 0x02) { | |
474 DEBUG_INDEX(("two-bit set!!\n")); | |
475 } | |
476 @@ -543,7 +679,7 @@ | |
477 pf->id_depth_ok = 1; | |
478 } | |
479 // u1 could be a flag. if bit 0x2 is not set, it might be deleted | |
480 - // if (index.u1 & 0x2 || index.u1 & 0x4) { | |
481 + // if (index.u1 & 0x2 || index.u1 & 0x4) | |
482 // ignore the above condition. it doesn't appear to hold | |
483 if (old > index.id) { // then we have back-slid on the new values | |
484 DEBUG_INDEX(("Back slider detected - Old value [%#x] greater than new [%#x]. Progressing to next table\n", old, index.id)); | |
485 @@ -551,6 +687,7 @@ | |
486 return 2; | |
487 } | |
488 old = index.id; | |
489 + // {{{ Add index to linked list | |
490 i_ptr = (pst_index_ll*) xmalloc(sizeof(pst_index_ll)); | |
491 i_ptr->id = index.id; | |
492 i_ptr->offset = index.offset; | |
493 @@ -562,15 +699,12 @@ | |
494 if (pf->i_head == NULL) | |
495 pf->i_head = i_ptr; | |
496 pf->i_tail = i_ptr; | |
497 - memcpy(&index, bptr, sizeof(index)); | |
498 - LE32_CPU(index.id); | |
499 - LE32_CPU(index.offset); | |
500 - LE16_CPU(index.size); | |
501 - LE16_CPU(index.u1); | |
502 - bptr += sizeof(index); | |
503 - } | |
504 - // fseek(pf->fp, fpos, SEEK_SET); | |
505 - if (x < 42) { // we have stopped prematurley. Why? | |
506 + // }}} | |
507 + | |
508 + roff = offset + (bptr - buf); | |
509 + bptr +=_pst_decode_index( &index, bptr ); | |
510 + } // }}} | |
511 + if (x < 42) { // {{{ we have stopped prematurley. Why? | |
512 if (index.id == 0) { | |
513 DEBUG_INDEX(("Found index.id == 0\n")); | |
514 } else if (!(bptr < buf+BLOCK_SIZE)) { | |
515 @@ -581,12 +715,12 @@ | |
516 } else { | |
517 DEBUG_INDEX(("Stopped for unknown reason\n")); | |
518 } | |
519 - } | |
520 + } // }}} | |
521 if (buf) free (buf); | |
522 DEBUG_RET(); | |
523 return 2; | |
524 - } else { | |
525 - // this is then probably a table of offsets to more tables. | |
526 + } // }}} | |
527 + else { // {{{ probably a table of offsets to tables, recurse | |
528 DEBUG_INDEX(("Reading Table Items\n")); | |
529 | |
530 x = 0; | |
531 @@ -600,15 +734,10 @@ | |
532 bptr = buf; | |
533 // DEBUG_HEXDUMPC(buf, BLOCK_SIZE, 12); | |
534 | |
535 - memcpy(&table, bptr, sizeof(table)); | |
536 - LE32_CPU(table.start); | |
537 - LE32_CPU(table.u1); | |
538 - LE32_CPU(table.offset); | |
539 - bptr += sizeof(table); | |
540 - memcpy(&table2, bptr, sizeof(table)); | |
541 - LE32_CPU(table2.start); | |
542 - LE32_CPU(table2.u1); | |
543 - LE32_CPU(table2.offset); | |
544 + | |
545 + roff = offset; | |
546 + bptr += _pst_decode_table( &table, bptr ); | |
547 + _pst_decode_table( &table2, bptr ); | |
548 | |
549 if (start_val != -1 && table.start != start_val) { | |
550 DEBUG_WARN(("This table isn't right. Must be corruption, or I got it wrong!\n")); | |
551 @@ -619,7 +748,9 @@ | |
552 } | |
553 | |
554 while (table.start != 0 && bptr < buf+BLOCK_SIZE && table.start < end_val) { | |
555 - DEBUG_INDEX(("[%i] %i Table [start id = %#x, u1 = %#x, offset = %#x]\n", depth, ++x, table.start, table.u1, table.offset)); | |
556 + DEBUG_INDEX(("%08x [%i] %i Table [start id = %#x, u1 = %#x, offset = %#x]\n", | |
557 + roff, | |
558 + depth, ++x, table.start, table.u1, table.offset)); | |
559 | |
560 if (table2.start <= table.start) | |
561 // this should only be the case when we come to the end of the table | |
562 @@ -643,15 +774,9 @@ | |
563 } else { | |
564 DEBUG_INDEX(("child has returned without a known error [%i]\n", ret)); | |
565 } | |
566 - memcpy(&table, bptr, sizeof(table)); | |
567 - LE32_CPU(table.start); | |
568 - LE32_CPU(table.u1); | |
569 - LE32_CPU(table.offset); | |
570 - bptr += sizeof(table); | |
571 - memcpy(&table2, bptr, sizeof(table)); | |
572 - LE32_CPU(table2.start); | |
573 - LE32_CPU(table2.u1); | |
574 - LE32_CPU(table2.offset); | |
575 + bptr += _pst_decode_table( &table, bptr ); | |
576 + roff = offset + ( bptr - buf ); | |
577 + _pst_decode_table( &table2, bptr ); | |
578 } | |
579 | |
580 if (table.start == 0) { | |
581 @@ -669,21 +794,23 @@ | |
582 DEBUG_INDEX(("End of table of pointers\n")); | |
583 DEBUG_RET(); | |
584 return 3; | |
585 - } | |
586 + } // }}} | |
587 DEBUG_WARN(("ERROR ** Shouldn't be here!\n")); | |
588 | |
589 DEBUG_RET(); | |
590 return 1; | |
591 } | |
592 | |
593 + | |
594 #define DESC_BLOCK_SIZE 520 | |
595 -int32_t _pst_build_desc_ptr (pst_file *pf, int32_t offset, int32_t depth, int32_t *high_id, int32_t start_id, | |
596 +int32_t _pst_build_desc_ptr (pst_file *pf, off_t offset, int32_t depth, int32_t *high_id, int32_t start_id, | |
597 int32_t end_val) { | |
598 - struct _pst_table_ptr_struct table, table2; | |
599 - pst_desc desc_rec; | |
600 + struct _pst_table_ptr_structn table, table2; | |
601 + pst_descn desc_rec; | |
602 pst_desc_ll *d_ptr=NULL, *d_par=NULL; | |
603 int32_t i = 0, y, prev_id=-1; | |
604 char *buf = NULL, *bptr; | |
605 + off_t roff; | |
606 | |
607 struct _pst_d_ptr_ll { | |
608 pst_desc_ll * ptr; | |
609 @@ -696,8 +823,7 @@ | |
610 | |
611 int32_t d_ptr_count = 0; | |
612 DEBUG_ENT("_pst_build_desc_ptr"); | |
613 - if (pf->index2_depth-depth == 0) { | |
614 - // leaf node | |
615 + if (pf->index2_depth-depth == 0) { // {{{ leaf node, index it | |
616 if (_pst_read_block_size(pf, offset, DESC_BLOCK_SIZE, &buf, 0, 0) < DESC_BLOCK_SIZE) { | |
617 DEBUG_WARN(("I didn't get all the index that I wanted. _pst_read_block_size returned less than requested\n")); | |
618 DEBUG_RET(); | |
619 @@ -707,22 +833,17 @@ | |
620 | |
621 //DEBUG_HEXDUMPC(buf, DESC_BLOCK_SIZE, 16); | |
622 | |
623 - memcpy(&desc_rec, bptr, sizeof(desc_rec)); | |
624 - LE32_CPU(desc_rec.d_id); | |
625 - LE32_CPU(desc_rec.desc_id); | |
626 - LE32_CPU(desc_rec.list_id); | |
627 - LE32_CPU(desc_rec.parent_id); | |
628 - bptr+= sizeof(desc_rec); | |
629 + roff = offset; | |
630 + bptr += _pst_decode_desc( &desc_rec, bptr ); | |
631 | |
632 if (end_val <= start_id) { | |
633 DEBUG_WARN(("The end value is BEFORE the start value. This function will quit. Soz. [start:%#x, end:%#x]\n", | |
634 start_id, end_val)); | |
635 } | |
636 | |
637 - while (i < 0x1F && desc_rec.d_id < end_val && (prev_id == -1 || desc_rec.d_id > prev_id)) { | |
638 - DEBUG_INDEX(("[%i] Item(%#x) = [d_id = %#x, desc_id = %#x, " | |
639 - "list_id = %#x, parent_id = %#x]\n", depth, i, desc_rec.d_id, | |
640 - desc_rec.desc_id, desc_rec.list_id, desc_rec.parent_id)); | |
641 + while (i < 0x1F && desc_rec.d_id < end_val && (prev_id == -1 || desc_rec.d_id > prev_id)) { // {{{ | |
642 + DEBUG_INDEX(("Bliss %d: %llx %p %p %p ", i, offset, buf, bptr, bptr )); | |
643 + dump_desc( roff, depth, i, &desc_rec ); | |
644 i++; | |
645 | |
646 if (start_id != -1 && desc_rec.d_id != start_id) { | |
647 @@ -737,20 +858,16 @@ | |
648 } | |
649 | |
650 if (desc_rec.d_id == 0) { | |
651 - memcpy(&desc_rec, bptr, sizeof(desc_rec)); | |
652 - LE32_CPU(desc_rec.d_id); | |
653 - LE32_CPU(desc_rec.desc_id); | |
654 - LE32_CPU(desc_rec.list_id); | |
655 - LE32_CPU(desc_rec.parent_id); | |
656 - bptr+=sizeof(desc_rec); | |
657 - continue; | |
658 + roff = offset + ( bptr - buf ); | |
659 + bptr+=_pst_decode_desc( &desc_rec, bptr ); | |
660 + continue; | |
661 } | |
662 prev_id = desc_rec.d_id; | |
663 | |
664 // When duplicates found, just update the info.... perhaps this is correct functionality | |
665 DEBUG_INDEX(("Searching for existing record\n")); | |
666 | |
667 - if (desc_rec.d_id <= *high_id && (d_ptr = _pst_getDptr(pf, desc_rec.d_id)) != NULL) { | |
668 + if (desc_rec.d_id <= *high_id && (d_ptr = _pst_getDptr(pf, desc_rec.d_id)) != NULL) { // {{{ | |
669 DEBUG_INDEX(("Updating Existing Values\n")); | |
670 d_ptr->list_index = _pst_getID(pf, desc_rec.list_id); | |
671 d_ptr->desc = _pst_getID(pf, desc_rec.desc_id); | |
672 @@ -802,7 +919,7 @@ | |
673 d_ptr_ptr = d_ptr_ptr->next; | |
674 } | |
675 | |
676 - if (d_ptr_ptr == NULL && (d_par = _pst_getDptr(pf, desc_rec.parent_id)) == NULL) { | |
677 + if (d_ptr_ptr == NULL && (d_par = _pst_getDptr(pf, desc_rec.parent_id)) == NULL) { // {{{ | |
678 // check in the lost/found list | |
679 lf_ptr = lf_head; | |
680 while (lf_ptr != NULL && lf_ptr->ptr->id != desc_rec.parent_id) { | |
681 @@ -820,7 +937,7 @@ | |
682 d_par = lf_ptr->ptr; | |
683 DEBUG_INDEX(("Found parent (%#x) in Lost and Found\n", d_par->id)); | |
684 } | |
685 - } | |
686 + } // }}} | |
687 | |
688 if (d_ptr_ptr != NULL || d_par != NULL) { | |
689 if (d_ptr_ptr != NULL) | |
690 @@ -857,7 +974,8 @@ | |
691 } | |
692 } | |
693 | |
694 - } else { | |
695 + } // }}} | |
696 + else { | |
697 if (*high_id < desc_rec.d_id) { | |
698 DEBUG_INDEX(("Updating New High\n")); | |
699 *high_id = desc_rec.d_id; | |
700 @@ -866,8 +984,10 @@ | |
701 d_ptr = (pst_desc_ll*) xmalloc(sizeof(pst_desc_ll)); | |
702 // DEBUG_INDEX(("Item pointer is %p\n", d_ptr)); | |
703 d_ptr->id = desc_rec.d_id; | |
704 + DEBUG_INDEX(("Weird %llx moo", desc_rec.list_id )); | |
705 d_ptr->list_index = _pst_getID(pf, desc_rec.list_id); | |
706 d_ptr->desc = _pst_getID(pf, desc_rec.desc_id); | |
707 + //ASSERT( d_ptr->desc != NULL ); | |
708 d_ptr->prev = NULL; | |
709 d_ptr->next = NULL; | |
710 d_ptr->parent = NULL; | |
711 @@ -876,7 +996,7 @@ | |
712 d_ptr->no_child = 0; | |
713 | |
714 DEBUG_INDEX(("Searching for parent\n")); | |
715 - if (desc_rec.parent_id == 0 || desc_rec.parent_id == desc_rec.d_id) { | |
716 + if (desc_rec.parent_id == 0 || desc_rec.parent_id == desc_rec.d_id) { // {{{ | |
717 if (desc_rec.parent_id == 0) { | |
718 DEBUG_INDEX(("No Parent\n")); | |
719 } else { | |
720 @@ -888,7 +1008,8 @@ | |
721 pf->d_head = d_ptr; | |
722 d_ptr->prev = pf->d_tail; | |
723 pf->d_tail = d_ptr; | |
724 - } else { | |
725 + } // }}} | |
726 + else { // {{{ | |
727 d_ptr_ptr = d_ptr_head; | |
728 while (d_ptr_ptr != NULL && d_ptr_ptr->ptr->id != desc_rec.parent_id) { | |
729 d_ptr_ptr = d_ptr_ptr->next; | |
730 @@ -947,7 +1068,7 @@ | |
731 d_ptr->prev = d_par->child_tail; | |
732 d_par->child_tail = d_ptr; | |
733 } | |
734 - } | |
735 + } // }}} | |
736 } | |
737 // check here to see if d_ptr is the parent of any of the items in the lost / found list | |
738 lf_ptr = lf_head; lf_shd = NULL; | |
739 @@ -977,16 +1098,13 @@ | |
740 lf_ptr = lf_ptr->next; | |
741 } | |
742 } | |
743 - memcpy(&desc_rec, bptr, sizeof(desc_rec)); | |
744 - LE32_CPU(desc_rec.d_id); | |
745 - LE32_CPU(desc_rec.desc_id); | |
746 - LE32_CPU(desc_rec.list_id); | |
747 - LE32_CPU(desc_rec.parent_id); | |
748 - bptr+= sizeof(desc_rec); | |
749 - } | |
750 + | |
751 + roff = offset + ( bptr - buf ); | |
752 + bptr+= _pst_decode_desc( &desc_rec, bptr ); | |
753 + } // }}} | |
754 // fseek(pf->fp, fpos, SEEK_SET); | |
755 - } else { | |
756 - // hopefully a table of offsets to more tables | |
757 + } // }}} | |
758 + else { // {{{ table of offsets to more tables, recurse | |
759 if (_pst_read_block_size(pf, offset, DESC_BLOCK_SIZE, &buf, 0, 0) < DESC_BLOCK_SIZE) { | |
760 DEBUG_WARN(("didn't read enough desc index. _pst_read_block_size returned less than requested\n")); | |
761 DEBUG_RET(); | |
762 @@ -995,15 +1113,8 @@ | |
763 bptr = buf; | |
764 // DEBUG_HEXDUMPC(buf, DESC_BLOCK_SIZE, 12); | |
765 | |
766 - memcpy(&table, bptr, sizeof(table)); | |
767 - LE32_CPU(table.start); | |
768 - LE32_CPU(table.u1); | |
769 - LE32_CPU(table.offset); | |
770 - bptr+=sizeof(table); | |
771 - memcpy(&table2, bptr, sizeof(table)); | |
772 - LE32_CPU(table2.start); | |
773 - LE32_CPU(table2.u1); | |
774 - LE32_CPU(table2.offset); | |
775 + bptr+=_pst_decode_table( &table, bptr ); | |
776 + _pst_decode_table( &table2, bptr ); | |
777 | |
778 if (start_id != -1 && table.start != start_id) { | |
779 DEBUG_WARN(("This table isn't right. Perhaps we are too deep, or corruption\n")); | |
780 @@ -1034,20 +1145,13 @@ | |
781 _pst_build_desc_ptr(pf, table.offset, depth+1, high_id, table.start, table2.start); | |
782 } | |
783 | |
784 - memcpy(&table, bptr, sizeof(table)); | |
785 - LE32_CPU(table.start); | |
786 - LE32_CPU(table.u1); | |
787 - LE32_CPU(table.offset); | |
788 - bptr+=sizeof(table); | |
789 - memcpy(&table2, bptr, sizeof(table)); | |
790 - LE32_CPU(table2.start); | |
791 - LE32_CPU(table2.u1); | |
792 - LE32_CPU(table2.offset); | |
793 + bptr+=_pst_decode_table( &table, bptr ); | |
794 + _pst_decode_table( &table2, bptr ); | |
795 } | |
796 if (buf) free(buf); | |
797 DEBUG_RET(); | |
798 return 3; | |
799 - } | |
800 + } // }}} | |
801 // ok, lets try freeing the d_ptr_head cache here | |
802 while (d_ptr_head != NULL) { | |
803 d_ptr_ptr = d_ptr_head->next; | |
804 @@ -1183,7 +1287,7 @@ | |
805 return item; | |
806 } | |
807 | |
808 -pst_num_array * _pst_parse_block(pst_file *pf, u_int32_t block_id, pst_index2_ll *i2_head) { | |
809 +pst_num_array * _pst_parse_block(pst_file *pf, u_int32_t block_id, pst_index2_ll *i2_head) { // {{{ | |
810 unsigned char *buf = NULL; | |
811 pst_num_array *na_ptr = NULL, *na_head = NULL; | |
812 pst_block_offset block_offset; | |
813 @@ -1194,6 +1298,7 @@ | |
814 size_t read_size=0; | |
815 pst_x_attrib_ll *mapptr; | |
816 | |
817 + | |
818 struct { | |
819 u_int16_t type; | |
820 u_int16_t ref_type; | |
821 @@ -1238,13 +1343,13 @@ | |
822 | |
823 // DEBUG_EMAIL(("About to read %i bytes from offset %#x\n", block->size, block->offset)); | |
824 | |
825 - if ((read_size = _pst_ff_getIDblock_dec(pf, block_id, &buf)) == 0) { | |
826 - // if (_pst_read_block_size(pf, block->offset, block->size, &buf, PST_ENC, 0) < block->size) { | |
827 + if ((read_size = _pst_ff_getIDblock_dec(pf, block_id, &buf)) == 0) { // {{{ error | |
828 + // if (_pst_read_block_size(pf, block->offset, block->size, &buf, PST_ENC, 0) < block->size) | |
829 WARN(("Error reading block id %#x\n", block_id)); | |
830 if (buf) free (buf); | |
831 DEBUG_RET(); | |
832 return NULL; | |
833 - } | |
834 + } // }}} | |
835 DEBUG_EMAIL(("pointer to buf is %p\n", buf)); | |
836 | |
837 memcpy(&block_hdr, &(buf[0]), sizeof(block_hdr)); | |
838 @@ -1255,7 +1360,7 @@ | |
839 | |
840 ind_ptr = block_hdr.index_offset; | |
841 | |
842 - if (block_hdr.type == 0xBCEC) { //type 1 | |
843 + if (block_hdr.type == 0xBCEC) { // {{{ type 1, populate block_offset | |
844 block_type = 1; | |
845 | |
846 _pst_getBlockOffset(buf, ind_ptr, block_hdr.offset, &block_offset); | |
847 @@ -1281,7 +1386,8 @@ | |
848 num_list = (to_ptr - fr_ptr)/sizeof(table_rec); | |
849 num_recs = 1; // only going to one object in these blocks | |
850 rec_size = 0; // doesn't matter cause there is only one object | |
851 - } else if (block_hdr.type == 0x7CEC) { //type 2 | |
852 + } // }}} | |
853 + else if (block_hdr.type == 0x7CEC) { // {{{ type 2, populate block_offset from seven_c_blk | |
854 block_type = 2; | |
855 | |
856 _pst_getBlockOffset(buf, ind_ptr, block_hdr.offset, &block_offset); | |
857 @@ -1340,16 +1446,17 @@ | |
858 | |
859 _pst_getBlockOffset(buf, ind_ptr, seven_c_blk.ind2_offset, &block_offset); | |
860 ind2_ptr = block_offset.from; | |
861 - } else { | |
862 + } // }}} | |
863 + else { // {{{ error | |
864 WARN(("ERROR: Unknown block constant - %#X for id %#x\n", block_hdr.type, block_id)); | |
865 DEBUG_HEXDUMPC(buf, read_size,0x10); | |
866 if (buf) free(buf); | |
867 DEBUG_RET(); | |
868 return NULL; | |
869 - } | |
870 + } // }}} | |
871 | |
872 DEBUG_EMAIL(("Mallocing number of items %i\n", num_recs)); | |
873 - while (count_rec < num_recs) { | |
874 + while (count_rec < num_recs) { // {{{ | |
875 na_ptr = (pst_num_array*) xmalloc(sizeof(pst_num_array)); | |
876 memset(na_ptr, 0, sizeof(pst_num_array)); | |
877 if (na_head == NULL) { | |
878 @@ -1371,13 +1478,14 @@ | |
879 fr_ptr = list_start; // init fr_ptr to the start of the list. | |
880 cur_list = 0; | |
881 stop = 0; | |
882 - while (!stop && cur_list < num_list) { //we will increase fr_ptr as we progress through index | |
883 - if (block_type == 1) { | |
884 + while (!stop && cur_list < num_list) { //{{{ we will increase fr_ptr as we progress through index | |
885 + if (block_type == 1) { // {{{ | |
886 memcpy(&table_rec, &(buf[fr_ptr]), sizeof(table_rec)); | |
887 LE16_CPU(table_rec.type); | |
888 LE16_CPU(table_rec.ref_type); | |
889 fr_ptr += sizeof(table_rec); | |
890 - } else if (block_type == 2) { | |
891 + } // }}} | |
892 + else if (block_type == 2) { // {{{ | |
893 // we will copy the table2_rec values into a table_rec record so that we can keep the rest of the code | |
894 memcpy(&table2_rec, &(buf[fr_ptr]), sizeof(table2_rec)); | |
895 LE16_CPU(table2_rec.ref_type); | |
896 @@ -1398,12 +1506,13 @@ | |
897 } | |
898 | |
899 fr_ptr += sizeof(table2_rec); | |
900 - } else { | |
901 + } // }}} | |
902 + else { // {{{ ERROR | |
903 WARN(("Missing code for block_type %i\n", block_type)); | |
904 if (buf) free(buf); | |
905 DEBUG_RET(); | |
906 return NULL; | |
907 - } | |
908 + } // }}} | |
909 cur_list++; // get ready to read next bit from list | |
910 DEBUG_EMAIL(("reading block %i (type=%#x, ref_type=%#x, value=%#x)\n", | |
911 x, table_rec.type, table_rec.ref_type, table_rec.value)); | |
912 @@ -1466,10 +1575,10 @@ | |
913 || table_rec.ref_type == 0x001E || table_rec.ref_type == 0x0102 | |
914 || table_rec.ref_type == 0x0040 || table_rec.ref_type == 0x101E | |
915 || table_rec.ref_type == 0x0048 || table_rec.ref_type == 0x1102 | |
916 - || table_rec.ref_type == 0x1014) { | |
917 + || table_rec.ref_type == 0x1014 || table_rec.ref_type == 0x001F ) { | |
918 //contains index_ref to data | |
919 LE32_CPU(table_rec.value); | |
920 - if ((table_rec.value & 0x0000000F) == 0xF) { | |
921 + if ((table_rec.value & 0x0000000F) == 0xF) { // {{{ | |
922 // if value ends in 'F' then this should be an id2 value | |
923 DEBUG_EMAIL(("Found id2 [%#x] value. Will follow it\n", | |
924 table_rec.value)); | |
925 @@ -1483,7 +1592,8 @@ | |
926 } | |
927 DEBUG_EMAIL(("Read %i bytes to a buffer at %p\n", | |
928 na_ptr->items[x]->size, na_ptr->items[x]->data)); | |
929 - } else if (table_rec.value != 0) { | |
930 + } // }}} | |
931 + else if (table_rec.value != 0) { | |
932 if ((table_rec.value >> 4)+ind_ptr > read_size) { | |
933 // check that we will not be outside the buffer we have read | |
934 DEBUG_WARN(("table_rec.value [%#x] is outside of block [%#x]\n", | |
935 @@ -1507,10 +1617,30 @@ | |
936 } | |
937 | |
938 // plus one for good luck (and strings) we will null terminate all reads | |
939 - na_ptr->items[x]->data = (char*) xmalloc(size+1); | |
940 - memcpy(na_ptr->items[x]->data, &(buf[t_ptr]), size); | |
941 - na_ptr->items[x]->data[size] = '\0'; // null terminate buffer | |
942 + if( 0x001F == table_rec.ref_type ) { | |
943 + VBUF_STATIC( strbuf, 1024 ); | |
944 + VBUF_STATIC( unibuf, 1024 ); | |
945 + //need UTF-16 zero-termination | |
946 + vbset( strbuf, &(buf[t_ptr]), size ); | |
947 + vbappend( strbuf, "\0\0", 2 ); | |
948 + DEBUG_INDEX(("Iconv in: ")); | |
949 + DEBUG_HEXDUMPC( strbuf->b, strbuf->dlen, 0x10 ); | |
950 + vb_utf16to8( unibuf, strbuf->b, strbuf->dlen ); | |
951 + na_ptr->items[x]->data = (char*) xmalloc(unibuf->dlen); | |
952 + memcpy(na_ptr->items[x]->data, unibuf->b, unibuf->dlen); | |
953 + na_ptr->items[x]->size = unibuf->dlen; | |
954 + DEBUG_INDEX(("Iconv out: ")); | |
955 + DEBUG_HEXDUMPC(na_ptr->items[x]->data, na_ptr->items[x]->size, 0x10 ); | |
956 + } | |
957 + else { | |
958 + na_ptr->items[x]->data = (char*) xmalloc(size+1); | |
959 + memcpy(na_ptr->items[x]->data, &(buf[t_ptr]), size); | |
960 + na_ptr->items[x]->data[size] = '\0'; // null terminate buffer | |
961 + } | |
962 | |
963 + DEBUG_INDEX(("Item Puke: type: %x, ref_type: %x, value: %x\n", | |
964 + table_rec.type, table_rec.ref_type, table_rec.value )); | |
965 + DEBUG_HEXDUMPC(na_ptr->items[x]->data, size, 0x10 ); | |
966 if (table_rec.ref_type == 0xd) { | |
967 // there is still more to do for the type of 0xD | |
968 type_d_rec = (struct _type_d_rec*) na_ptr->items[x]->data; | |
969 @@ -1526,7 +1656,6 @@ | |
970 } | |
971 DEBUG_EMAIL(("Read %i bytes into a buffer at %p\n", | |
972 na_ptr->items[x]->size, na_ptr->items[x]->data)); | |
973 - // } | |
974 } | |
975 } else { | |
976 DEBUG_EMAIL(("Ignoring 0 value in offset\n")); | |
977 @@ -1548,18 +1677,18 @@ | |
978 return NULL; | |
979 } | |
980 x++; | |
981 - } | |
982 + } // }}} | |
983 DEBUG_EMAIL(("increasing ind2_ptr by %i [%#x] bytes. Was %#x, Now %#x\n", | |
984 rec_size, rec_size, ind2_ptr, | |
985 ind2_ptr+rec_size)); | |
986 ind2_ptr += rec_size; | |
987 count_rec++; | |
988 - } | |
989 + } // }}} | |
990 if (buf != NULL) | |
991 free(buf); | |
992 DEBUG_RET(); | |
993 return na_head; | |
994 -} | |
995 +} // }}} | |
996 | |
997 // check if item->email is NULL, and init if so | |
998 #define MALLOC_EMAIL(x) { if (x->email == NULL) { x->email = (pst_item_email*) xmalloc(sizeof(pst_item_email)); memset (x->email, 0, sizeof(pst_item_email));} } | |
999 @@ -3384,7 +3513,7 @@ | |
1000 } | |
1001 if (_pst_read_block_size(pf, list->offset, list->size, &buf, PST_NO_ENC,0) < list->size) { | |
1002 //an error occured in block read | |
1003 - WARN(("block read error occured. offset = %#x, size = %#x\n", list->offset, list->size)); | |
1004 + WARN(("block read error occured. offset = %#llx, size = %#llx\n", list->offset, list->size)); | |
1005 DEBUG_RET(); | |
1006 return NULL; | |
1007 } | |
1008 @@ -3394,7 +3523,7 @@ | |
1009 LE16_CPU(block_head.count); | |
1010 | |
1011 if (block_head.type != 0x0002) { // some sort of constant? | |
1012 - WARN(("Unknown constant [%#x] at start of id2 values [offset %#x].\n", block_head.type, list->offset)); | |
1013 + WARN(("Unknown constant [%#x] at start of id2 values [offset %#llx].\n", block_head.type, list->offset)); | |
1014 DEBUG_RET(); | |
1015 return NULL; | |
1016 } | |
1017 @@ -3678,7 +3807,7 @@ | |
1018 return 0; | |
1019 } | |
1020 | |
1021 -pst_index_ll * _pst_getID(pst_file* pf, u_int32_t id) { | |
1022 +pst_index_ll * _pst_getID(pst_file* pf, u_int64_t id) { | |
1023 // static pst_index_ll *old_val = NULL; //this should make it quicker | |
1024 pst_index_ll *ptr = NULL; | |
1025 DEBUG_ENT("_pst_getID"); | |
1026 @@ -3693,9 +3822,10 @@ | |
1027 // Dave: I don't think I should do this. next bit. I really think it doesn't work | |
1028 // it isn't based on sound principles either. | |
1029 // update: seems that the last two sig bits are flags. u tell me! | |
1030 - id &= 0xFFFFFFFE; // remove least sig. bit. seems that it might work if I do this | |
1031 + //id &= 0xFFFFFFFE; // remove least sig. bit. seems that it might work if I do this | |
1032 + id -= (id & 1 ); | |
1033 | |
1034 - DEBUG_INDEX(("Trying to find %#x\n", id)); | |
1035 + DEBUG_INDEX(("Trying to find %#llx\n", id)); | |
1036 | |
1037 if (ptr == NULL) | |
1038 ptr = pf->i_head; | |
1039 @@ -3927,6 +4057,9 @@ | |
1040 return -1; | |
1041 } | |
1042 | |
1043 + DEBUG_INDEX(("_pst_decrypt()")); | |
1044 + DEBUG_HEXDUMPC(buf, size, 0x10 ); | |
1045 + | |
1046 if (type == PST_COMP_ENCRYPT) { | |
1047 x = 0; | |
1048 while (x < size) { | |
1049 @@ -3935,6 +4068,9 @@ | |
1050 buf[x] = comp_enc[y]; // transpose from encrypt array | |
1051 x++; | |
1052 } | |
1053 + | |
1054 + DEBUG_INDEX(("_pst_decrypt() result")); | |
1055 + DEBUG_HEXDUMPC(buf, size, 0x10 ); | |
1056 } else { | |
1057 WARN(("Unknown encryption: %i. Cannot decrypt\n", type)); | |
1058 DEBUG_RET(); | |
1059 @@ -3944,7 +4080,23 @@ | |
1060 return 0; | |
1061 } | |
1062 | |
1063 -int32_t _pst_getAtPos(FILE *fp, int32_t pos, void* buf, u_int32_t size) { | |
1064 +int64_t _pst_getIntAtPos(FILE *fp, off_t pos ) { | |
1065 + int64_t buf64; | |
1066 + int32_t buf32; | |
1067 + | |
1068 + if(do_read64) { | |
1069 + _pst_getAtPos(fp, pos, &buf64, sizeof( buf64 ) ); | |
1070 + LE64_CPU(buf64); | |
1071 + return buf64; | |
1072 + } | |
1073 + else { | |
1074 + _pst_getAtPos(fp, pos, &buf32, sizeof( buf32 ) ); | |
1075 + LE32_CPU(buf32); | |
1076 + return buf32; | |
1077 + } | |
1078 +} | |
1079 + | |
1080 +int32_t _pst_getAtPos(FILE *fp, off_t pos, void* buf, u_int32_t size) { | |
1081 DEBUG_ENT("_pst_getAtPos"); | |
1082 if (fseek(fp, pos, SEEK_SET) == -1) { | |
1083 DEBUG_RET(); | |
1084 diff -Naur ../orig/libpst-0.5.1/libpst.h libpst64-060926/libpst.h | |
1085 --- ../orig/libpst-0.5.1/libpst.h 2004-11-17 07:48:03.000000000 -0700 | |
1086 +++ libpst64-060926/libpst.h 2006-09-26 14:09:55.000000000 -0600 | |
1087 @@ -117,6 +117,8 @@ | |
1088 #define PST_APP_LABEL_ANNIVERSARY 9 // Anniversary | |
1089 #define PST_APP_LABEL_PHONE_CALL 10// Phone Call | |
1090 | |
1091 +extern int do_read64; | |
1092 + | |
1093 typedef struct _pst_misc_6_struct { | |
1094 int32_t i1; | |
1095 int32_t i2; | |
1096 @@ -132,26 +134,72 @@ | |
1097 int32_t id; | |
1098 } pst_entryid; | |
1099 | |
1100 -typedef struct _pst_desc_struct { | |
1101 +typedef struct _pst_desc_struct32 { | |
1102 u_int32_t d_id; | |
1103 u_int32_t desc_id; | |
1104 u_int32_t list_id; | |
1105 u_int32_t parent_id; | |
1106 -} pst_desc; | |
1107 +} pst_desc32; | |
1108 | |
1109 -typedef struct _pst_index_struct{ | |
1110 +typedef struct _pst_desc_structn { | |
1111 + u_int64_t d_id; | |
1112 + u_int64_t desc_id; | |
1113 + u_int64_t list_id; | |
1114 +// u_int64_t parent_id; | |
1115 + u_int32_t parent_id; | |
1116 + u_int32_t u1; | |
1117 +} pst_descn; | |
1118 + | |
1119 +typedef struct _pst_index_struct32{ | |
1120 u_int32_t id; | |
1121 int32_t offset; | |
1122 u_int16_t size; | |
1123 int16_t u1; | |
1124 +} pst_index32; | |
1125 + | |
1126 +/* | |
1127 +typedef struct _pst_index_struct64{ | |
1128 + u_int64_t id; | |
1129 + int64_t offset; | |
1130 + u_int16_t size; | |
1131 + int16_t u1; | |
1132 +} pst_index64; | |
1133 +*/ | |
1134 + | |
1135 +typedef struct _pst_index_struct{ | |
1136 + u_int64_t id; | |
1137 + int64_t offset; | |
1138 + u_int16_t size; | |
1139 + int16_t u0; | |
1140 + int32_t u1; | |
1141 } pst_index; | |
1142 | |
1143 -typedef struct _pst_index_tree { | |
1144 +/* | |
1145 +typedef union _pst_index_struct { | |
1146 + pst_index32 i32; | |
1147 + pst_index64 i64; | |
1148 +} pst_index; | |
1149 + | |
1150 +#define INDEX_ID(x) ((do_read64)?x.i64.id:x.i32.id) | |
1151 +#define INDEX_OFFSET(x) ((do_read64)?x.i64.offset:x.i32.offset) | |
1152 +#define INDEX_SIZE(x) ((do_read64)?x.i64.size:x.i32.size) | |
1153 +#define INDEX_U1(x) ((do_read64)?x.i64.u1:x.i32.u1) | |
1154 +*/ | |
1155 + | |
1156 +typedef struct _pst_index_tree32 { | |
1157 u_int32_t id; | |
1158 int32_t offset; | |
1159 - size_t size; | |
1160 + int32_t size; | |
1161 int32_t u1; | |
1162 struct _pst_index_tree * next; | |
1163 +} pst_index_ll32; | |
1164 + | |
1165 +typedef struct _pst_index_tree { | |
1166 + u_int64_t id; | |
1167 + int64_t offset; | |
1168 + int64_t size; | |
1169 + int64_t u1; | |
1170 + struct _pst_index_tree * next; | |
1171 } pst_index_ll; | |
1172 | |
1173 typedef struct _pst_index2_tree { | |
1174 @@ -421,6 +469,10 @@ | |
1175 int32_t index1_count; | |
1176 int32_t index2; | |
1177 int32_t index2_count; | |
1178 + int64_t index1_64; | |
1179 + int64_t index1_count_64; | |
1180 + int64_t index2_64; | |
1181 + int64_t index2_count_64; | |
1182 FILE * fp; | |
1183 size_t size; | |
1184 unsigned char index1_depth; | |
1185 @@ -460,6 +512,7 @@ | |
1186 }; | |
1187 | |
1188 // prototypes | |
1189 +void set_read64(); | |
1190 int32_t pst_open(pst_file *pf, char *name, char *mode); | |
1191 int32_t pst_close(pst_file *pf); | |
1192 pst_desc_ll * pst_getTopOfFolders(pst_file *pf, pst_item *root); | |
1193 @@ -470,8 +523,8 @@ | |
1194 pst_desc_ll* pst_getNextDptr(pst_desc_ll* d); | |
1195 int32_t pst_load_extended_attributes(pst_file *pf); | |
1196 | |
1197 -int32_t _pst_build_id_ptr(pst_file *pf, int32_t offset, int32_t depth, int32_t start_val, int32_t end_val); | |
1198 -int32_t _pst_build_desc_ptr (pst_file *pf, int32_t offset, int32_t depth, int32_t *high_id, | |
1199 +int32_t _pst_build_id_ptr(pst_file *pf, off_t offset, int32_t depth, int32_t start_val, int32_t end_val); | |
1200 +int32_t _pst_build_desc_ptr (pst_file *pf, off_t offset, int32_t depth, int32_t *high_id, | |
1201 int32_t start_id, int32_t end_val); | |
1202 pst_item* _pst_getItem(pst_file *pf, pst_desc_ll *d_ptr); | |
1203 void * _pst_parse_item (pst_file *pf, pst_desc_ll *d_ptr); | |
1204 @@ -485,13 +538,14 @@ | |
1205 int32_t _pst_free_xattrib(pst_x_attrib_ll *x); | |
1206 int32_t _pst_getBlockOffset(char *buf, int32_t i_offset, int32_t offset, pst_block_offset *p); | |
1207 pst_index2_ll * _pst_build_id2(pst_file *pf, pst_index_ll* list, pst_index2_ll* head_ptr); | |
1208 -pst_index_ll * _pst_getID(pst_file* pf, u_int32_t id); | |
1209 +pst_index_ll * _pst_getID(pst_file* pf, u_int64_t id); | |
1210 pst_index_ll * _pst_getID2(pst_index2_ll * ptr, u_int32_t id); | |
1211 pst_desc_ll * _pst_getDptr(pst_file *pf, u_int32_t id); | |
1212 size_t _pst_read_block_size(pst_file *pf, int32_t offset, size_t size, char ** buf, int32_t do_enc, | |
1213 unsigned char is_index); | |
1214 int32_t _pst_decrypt(unsigned char *buf, size_t size, int32_t type); | |
1215 -int32_t _pst_getAtPos(FILE *fp, int32_t pos, void* buf, u_int32_t size); | |
1216 +int64_t _pst_getIntAtPos(FILE *fp, off_t pos); | |
1217 +int32_t _pst_getAtPos(FILE *fp, off_t pos, void* buf, u_int32_t size); | |
1218 int32_t _pst_get (FILE *fp, void *buf, u_int32_t size); | |
1219 size_t _pst_ff_getIDblock_dec(pst_file *pf, u_int32_t id, unsigned char **b); | |
1220 size_t _pst_ff_getIDblock(pst_file *pf, u_int32_t id, unsigned char** b); | |
1221 diff -Naur ../orig/libpst-0.5.1/libstrfunc.c libpst64-060926/libstrfunc.c | |
1222 --- ../orig/libpst-0.5.1/libstrfunc.c 2004-11-17 07:48:03.000000000 -0700 | |
1223 +++ libpst64-060926/libstrfunc.c 2006-09-26 14:09:55.000000000 -0600 | |
1224 @@ -67,3 +67,30 @@ | |
1225 return _sf_b64_buf=output; | |
1226 }; | |
1227 | |
1228 +void hexdump(char *hbuf, int start, int stop, int ascii) /* {{{ HexDump all or a part of some buffer */ | |
1229 +{ | |
1230 + char c; | |
1231 + int diff,i; | |
1232 + | |
1233 + while (start < stop ) { | |
1234 + diff = stop - start; | |
1235 + if (diff > 16) diff = 16; | |
1236 + | |
1237 + fprintf(stderr, ":%08X ",start); | |
1238 + | |
1239 + for (i = 0; i < diff; i++) { | |
1240 + if( 8 == i ) fprintf( stderr, " " ); | |
1241 + fprintf(stderr, "%02X ",(unsigned char)*(hbuf+start+i)); | |
1242 + } | |
1243 + if (ascii) { | |
1244 + for (i = diff; i < 16; i++) fprintf(stderr, " "); | |
1245 + for (i = 0; i < diff; i++) { | |
1246 + c = *(hbuf+start+i); | |
1247 + fprintf(stderr, "%c", isprint(c) ? c : '.'); | |
1248 + } | |
1249 + } | |
1250 + fprintf(stderr, "\n"); | |
1251 + start += 16; | |
1252 + } | |
1253 +} | |
1254 +// }}} | |
1255 diff -Naur ../orig/libpst-0.5.1/libstrfunc.h libpst64-060926/libstrfunc.h | |
1256 --- ../orig/libpst-0.5.1/libstrfunc.h 2004-11-17 07:48:03.000000000 -0700 | |
1257 +++ libpst64-060926/libstrfunc.h 2006-09-26 14:09:55.000000000 -0600 | |
1258 @@ -1,2 +1,4 @@ | |
1259 | |
1260 char * base64_encode(void *data, size_t size); | |
1261 + | |
1262 +void hexdump(char *hbuf, int start, int stop, int ascii); | |
1263 diff -Naur ../orig/libpst-0.5.1/lspst.c libpst64-060926/lspst.c | |
1264 --- ../orig/libpst-0.5.1/lspst.c 2004-11-17 07:48:03.000000000 -0700 | |
1265 +++ libpst64-060926/lspst.c 2006-09-26 14:09:55.000000000 -0600 | |
1266 @@ -37,6 +37,7 @@ | |
1267 char *rfc2426_escape(char *str); | |
1268 char *rfc2445_datetime_format(FILETIME *ft); | |
1269 // }}}1 | |
1270 +#undef DEBUG_MAIN | |
1271 #define DEBUG_MAIN(x) debug_print x; | |
1272 // int main(int argc, char** argv) {{{1 | |
1273 int main(int argc, char** argv) { | |
1274 diff -Naur ../orig/libpst-0.5.1/Makefile libpst64-060926/Makefile | |
1275 --- ../orig/libpst-0.5.1/Makefile 2004-11-17 09:16:02.000000000 -0700 | |
1276 +++ libpst64-060926/Makefile 2006-09-26 14:09:55.000000000 -0600 | |
1277 @@ -1,9 +1,12 @@ | |
1278 #!/usr/bin/make -f | |
1279 | |
1280 -CFLAGS ?= -g -Wall | |
1281 +CFLAGS ?= -g -Wall | |
1282 PREFIX ?= /usr/local | |
1283 INSTALL ?= install | |
1284 | |
1285 +# You might need this | |
1286 +#LDLIBS ?= -liconv | |
1287 + | |
1288 #---------------- Do not modify below this point ------------------ | |
1289 | |
1290 INSTALL_DIR := $(INSTALL) -p -d -o root -g root -m 0755 | |
1291 @@ -39,9 +42,11 @@ | |
1292 readpstlog.o: XGetopt.h define.h | |
1293 testdebug.o: define.h | |
1294 timeconv.o: timeconv.h common.h | |
1295 +vbuf.o: vbuf.h | |
1296 +generic.o: generic.h | |
1297 | |
1298 -readpst: readpst.o libpst.o timeconv.o libstrfunc.o debug.o lzfu.o | |
1299 -lspst: debug.o libpst.o libstrfunc.o lspst.o timeconv.o | |
1300 +readpst: readpst.o libpst.o timeconv.o libstrfunc.o debug.o lzfu.o vbuf.o generic.o | |
1301 +lspst: debug.o libpst.o libstrfunc.o lspst.o timeconv.o vbuf.o generic.o | |
1302 getidblock: getidblock.o libpst.o debug.o libstrfunc.o | |
1303 testdebug: testdebug.o debug.o | |
1304 readpstlog: readpstlog.o debug.o | |
1305 diff -Naur ../orig/libpst-0.5.1/readpst.c libpst64-060926/readpst.c | |
1306 --- ../orig/libpst-0.5.1/readpst.c 2004-11-17 07:48:03.000000000 -0700 | |
1307 +++ libpst64-060926/readpst.c 2006-09-26 14:09:55.000000000 -0600 | |
1308 @@ -13,6 +13,8 @@ | |
1309 #include <limits.h> | |
1310 #include <errno.h> | |
1311 | |
1312 +#include "vbuf.h" | |
1313 + | |
1314 #ifndef _WIN32 | |
1315 # include <unistd.h> | |
1316 # include <sys/stat.h> //mkdir | |
1317 @@ -70,19 +72,19 @@ | |
1318 // Function Declarations {{{1 | |
1319 void write_email_body(FILE *f, char *body); | |
1320 char *removeCR (char *c); | |
1321 -int32_t usage(); | |
1322 -int32_t version(); | |
1323 +int usage(); | |
1324 +int version(); | |
1325 char *mk_kmail_dir(char*); | |
1326 -int32_t close_kmail_dir(); | |
1327 +int close_kmail_dir(); | |
1328 char *mk_recurse_dir(char*); | |
1329 -int32_t close_recurse_dir(); | |
1330 +int close_recurse_dir(); | |
1331 char *mk_seperate_dir(char *dir, int overwrite); | |
1332 -int32_t close_seperate_dir(); | |
1333 -int32_t mk_seperate_file(struct file_ll *f); | |
1334 +int close_seperate_dir(); | |
1335 +int mk_seperate_file(struct file_ll *f); | |
1336 char *my_stristr(char *haystack, char *needle); | |
1337 char *check_filename(char *fname); | |
1338 char *rfc2426_escape(char *str); | |
1339 -int32_t chr_count(char *str, char x); | |
1340 +int chr_count(char *str, char x); | |
1341 char *rfc2425_datetime_format(FILETIME *ft); | |
1342 char *rfc2445_datetime_format(FILETIME *ft); | |
1343 char *skip_header_prologue(char *headers); | |
1344 @@ -107,6 +109,8 @@ | |
1345 // saved as email_no-filename (e.g. 1-samplefile.doc or 000001-Attachment2.zip) | |
1346 #define MODE_SEPERATE 3 | |
1347 | |
1348 +// Decrypt the whole file (even the parts that aren't encrypted) and ralph it to stdout | |
1349 +#define MODE_DECSPEW 4 | |
1350 | |
1351 // Output Normal just prints the standard information about what is going on | |
1352 #define OUTPUT_NORMAL 0 | |
1353 @@ -153,7 +157,7 @@ | |
1354 prog_name = argv[0]; | |
1355 // }}}2 | |
1356 | |
1357 - while ((c = getopt(argc, argv, "d:hko:qrSVwc:"))!= -1) { | |
1358 + while ((c = getopt(argc, argv, "C6d:hko:qrSVwc:"))!= -1) { | |
1359 switch (c) { | |
1360 case 'c': | |
1361 if (optarg!=NULL && optarg[0]=='v') | |
1362 @@ -168,6 +172,9 @@ | |
1363 case 'd': | |
1364 d_log = optarg; | |
1365 break; | |
1366 + case '6': | |
1367 + set_read64(); | |
1368 + break; | |
1369 case 'h': | |
1370 usage(); | |
1371 exit(0); | |
1372 @@ -191,6 +198,9 @@ | |
1373 case 'S': | |
1374 mode = MODE_SEPERATE; | |
1375 break; | |
1376 + case 'C': | |
1377 + mode = MODE_DECSPEW; | |
1378 + break; | |
1379 case 'w': | |
1380 overwrite = 1; | |
1381 break; | |
1382 @@ -201,6 +211,8 @@ | |
1383 } | |
1384 } | |
1385 | |
1386 + unicode_init(); | |
1387 + | |
1388 #ifdef DEBUG_ALL | |
1389 // initialize log file | |
1390 if (d_log == NULL) | |
1391 @@ -218,6 +230,29 @@ | |
1392 exit(2); | |
1393 } | |
1394 | |
1395 + | |
1396 + if ( mode == MODE_DECSPEW ) { | |
1397 + FILE *fp; | |
1398 + char buf[1024]; | |
1399 + int l=0; | |
1400 + if( NULL == ( fp = fopen(fname, "rb" ) ) ) { | |
1401 + fprintf(stderr, "Couldn't open file %s\n", fname ); | |
1402 + return 1; | |
1403 + } | |
1404 + | |
1405 + while( 0 != ( l = fread( buf, 1, 1024, fp ) ) ) { | |
1406 + if( 0 != _pst_decrypt( buf, l, PST_COMP_ENCRYPT ) ) | |
1407 + fprintf(stderr, "_pst_decrypt() failed (I'll try to continue)\n"); | |
1408 + | |
1409 + if( l != fwrite( buf, 1, l, stdout ) ) { | |
1410 + fprintf(stderr, "Couldn't output to stdout?\n"); | |
1411 + return 1; | |
1412 + } | |
1413 + } | |
1414 + | |
1415 + return 0; | |
1416 + } | |
1417 + | |
1418 if (output_mode != OUTPUT_QUIET) printf("Opening PST file and indexes...\n"); | |
1419 | |
1420 DEBUG_MAIN(("main: Opening PST file '%s'\n", fname)); | |
1421 @@ -1139,6 +1174,8 @@ | |
1422 printf("\t-S\t- Seperate. Write emails in the seperate format\n"); | |
1423 printf("\t-V\t- Version. Display program version\n"); | |
1424 printf("\t-w\t- Overwrite any output mbox files\n"); | |
1425 + printf("\t-6\t- Attempt to read 64-bit Outlook file (Outlook 2003)\n"); | |
1426 + printf("\t-C\t- Decrypt the entire file and output on stdout (not typically useful)\n"); | |
1427 DEBUG_RET(); | |
1428 return 0; | |
1429 } | |
1430 diff -Naur ../orig/libpst-0.5.1/vbuf.c libpst64-060926/vbuf.c | |
1431 --- ../orig/libpst-0.5.1/vbuf.c 1969-12-31 17:00:00.000000000 -0700 | |
1432 +++ libpst64-060926/vbuf.c 2006-09-26 14:09:55.000000000 -0600 | |
1433 @@ -0,0 +1,932 @@ | |
1434 +// {{{ includes | |
1435 + | |
1436 +#include <ctype.h> | |
1437 +//#include "defines.h" | |
1438 +#include <errno.h> | |
1439 +#include <iconv.h> | |
1440 +#include <malloc.h> | |
1441 +#include <signal.h> | |
1442 +#include <stdarg.h> | |
1443 +#include <stdio.h> | |
1444 +#include <stdlib.h> | |
1445 +#include <string.h> | |
1446 +#include "vbuf.h" | |
1447 +#include "generic.h" | |
1448 + | |
1449 +#ifdef WITH_DMALLOC | |
1450 +#include <dmalloc.h> | |
1451 +#endif | |
1452 + | |
1453 +// }}} | |
1454 + | |
1455 +int skip_nl( char *s ) // {{{ returns the width of the newline at s[0] | |
1456 +{ | |
1457 + if( s[0] == '\n' ) return 1; | |
1458 + if( s[0] == '\r' && s[1] == '\n' ) return 2; | |
1459 + if( s[0] == '\0' ) return 0; | |
1460 + return -1; | |
1461 +} // }}} | |
1462 +int find_nl( vstr *vs ) // {{{ find newline of type type in b | |
1463 +{ | |
1464 + char *nextr, *nextn; | |
1465 + | |
1466 + nextr = memchr( vs->b, '\r', vs->dlen ); | |
1467 + nextn = memchr( vs->b, '\n', vs->dlen ); | |
1468 + | |
1469 + //case 1: UNIX, we find \n first | |
1470 + if( nextn && (nextr == NULL || nextr > nextn ) ) { | |
1471 + return nextn - vs->b; | |
1472 + } | |
1473 + | |
1474 + //case 2: DOS, we find \r\n | |
1475 + if( NULL != nextr && NULL != nextn && 1 == (char*)nextn - (char*)nextr ) { | |
1476 + return nextr - vs->b; | |
1477 + } | |
1478 + | |
1479 + //case 3: we find nothing | |
1480 + | |
1481 + return -1; | |
1482 +} // }}} | |
1483 + | |
1484 +// {{{ UTF8 <-> UTF16 <-> ISO8859 Character set conversion functions and (ack) their globals | |
1485 + | |
1486 +//TODO: the following should not be | |
1487 +char *wwbuf=NULL; | |
1488 +size_t nwwbuf=0; | |
1489 +static int unicode_up=0; | |
1490 +iconv_t i16to8, i8to16, i8859_1to8, i8toi8859_1; | |
1491 + | |
1492 +void unicode_init() // {{{ | |
1493 +{ | |
1494 + char *wipe = ""; | |
1495 + char dump[4]; | |
1496 + | |
1497 + if( unicode_up ) unicode_close(); | |
1498 + | |
1499 + if( (iconv_t)-1 == (i16to8 = iconv_open( "UTF-8", "UTF-16" ) ) ) { | |
1500 + fprintf(stderr, "doexport(): Couldn't open iconv descriptor for UTF-16 to UTF-8.\n"); | |
1501 + exit( 1 ); | |
1502 + } | |
1503 + | |
1504 + if( (iconv_t)-1 == (i8to16 = iconv_open( "UTF-16", "UTF-8" ) ) ) { | |
1505 + fprintf(stderr, "doexport(): Couldn't open iconv descriptor for UTF-8 to UTF-16.\n"); | |
1506 + exit( 2 ); | |
1507 + } | |
1508 + | |
1509 + //iconv will prefix output with an FF FE (utf-16 start seq), the following dumps that. | |
1510 + memset( dump, 'x', 4 ); | |
1511 + ASSERT( 0 == utf8to16( wipe, 1, dump, 4 ), "unicode_init(): attempt to dump FF FE failed." ); | |
1512 + | |
1513 + if( (iconv_t)-1 == (i8859_1to8 = iconv_open( "UTF-8", "ISO_8859-1" ) ) ) { | |
1514 + fprintf(stderr, "doexport(): Couldn't open iconv descriptor for ASCII to UTF-8.\n"); | |
1515 + exit( 1 ); | |
1516 + } | |
1517 + | |
1518 + | |
1519 + if( (iconv_t)-1 == (i8toi8859_1 = iconv_open( "ISO_8859-1", "UTF-8" ) ) ) { | |
1520 + fprintf(stderr, "doexport(): Couldn't open iconv descriptor for UTF-8 to ASCII.\n"); | |
1521 + exit( 1 ); | |
1522 + } | |
1523 + | |
1524 + unicode_up = 1; | |
1525 +} | |
1526 +// }}} | |
1527 +void unicode_close() // {{{ | |
1528 +{ | |
1529 + unicode_up = 0; | |
1530 + iconv_close( i8to16 ); | |
1531 + iconv_close( i16to8 ); | |
1532 + iconv_close( i8859_1to8 ); | |
1533 + iconv_close( i8toi8859_1 ); | |
1534 +} | |
1535 +// }}} | |
1536 + | |
1537 +//int utf16_write( FILE* stream, const void *buf, size_t count ) // {{{ write utf-8 or iso_8869-1 to stream after converting it to utf-16 | |
1538 +//{ | |
1539 +// | |
1540 +// //TODO: if anything big comes through here we are sunk, should do it | |
1541 +// //bit-by-bit, not one-big-gulp | |
1542 +// | |
1543 +// size_t inbytesleft, outbytesleft; | |
1544 +// char *inbuf, *outbuf; | |
1545 +// size_t icresult; | |
1546 +// size_t rl; | |
1547 +// | |
1548 +// //do we have enough buffer space? | |
1549 +// if( !wwbuf || nwwbuf < (count * 2 + 2) ) { | |
1550 +// wwbuf = F_REALLOC( wwbuf, count * 2 +2 ); | |
1551 +// | |
1552 +// nwwbuf = count * 2 + 2; | |
1553 +// } | |
1554 +// | |
1555 +// inbytesleft = count; outbytesleft = nwwbuf; | |
1556 +// inbuf = (char*)buf; outbuf = wwbuf; | |
1557 +// | |
1558 +//// fprintf(stderr, "X%s, %dX", (char*)buf, strlen( buf )); | |
1559 +//// fflush(stderr); | |
1560 +// | |
1561 +// if( (rl = strlen( buf ) + 1) != count ) { | |
1562 +// fprintf(stderr, "utf16_write(): reported buffer size (%d) does not match string length (%d)\n", | |
1563 +// count, | |
1564 +// rl); | |
1565 +// | |
1566 +// //hexdump( (char*)buf, 0, count, 1 ); | |
1567 +// | |
1568 +// raise( SIGSEGV ); | |
1569 +// inbytesleft = rl; | |
1570 +// } | |
1571 +// | |
1572 +//// fprintf(stderr, " attempting to convert:\n"); | |
1573 +//// hexdump( (char*)inbuf, 0, count, 1 ); | |
1574 +// | |
1575 +// icresult = iconv( i8to16, &inbuf, &inbytesleft, &outbuf, &outbytesleft ); | |
1576 +// | |
1577 +//// fprintf(stderr, " converted:\n"); | |
1578 +//// hexdump( (char*)buf, 0, count, 1 ); | |
1579 +// | |
1580 +//// fprintf(stderr, " to:\n"); | |
1581 +//// hexdump( (char*)wwbuf, 0, nwwbuf, 1 ); | |
1582 +// | |
1583 +// if( (size_t)-1 == icresult ) { | |
1584 +// fprintf(stderr, "utf16_write(): iconv failure(%d): %s\n", errno, strerror( errno ) ); | |
1585 +// fprintf(stderr, " attempted to convert:\n"); | |
1586 +// hexdump( (char*)inbuf, 0, count, 1 ); | |
1587 +// | |
1588 +// fprintf(stderr, " result:\n"); | |
1589 +// hexdump( (char*)outbuf, 0, count, 1 ); | |
1590 +// | |
1591 +// fprintf(stderr, "I'm going to segfault now.\n"); | |
1592 +// raise( SIGSEGV ); | |
1593 +// exit(1); | |
1594 +// } | |
1595 +// | |
1596 +// if( inbytesleft > 0 ) { | |
1597 +// fprintf(stderr, "utf16_write(): iconv returned a short count.\n"); | |
1598 +// exit(1); | |
1599 +// } | |
1600 +// | |
1601 +// return fwrite( wwbuf, nwwbuf - outbytesleft - 2, 1, stream ); | |
1602 +//} | |
1603 +// }}} | |
1604 + | |
1605 +//char *utf16buf = NULL; | |
1606 +//int utf16buf_len = 0; | |
1607 +// | |
1608 +//int utf16_fprintf( FILE* stream, const char *fmt, ... ) // {{{ | |
1609 +//{ | |
1610 +// int result=0; | |
1611 +// va_list ap; | |
1612 +// | |
1613 +// if( utf16buf == NULL ) { | |
1614 +// utf16buf = (char*)F_MALLOC( SZ_MAX + 1 ); | |
1615 +// | |
1616 +// utf16buf_len = SZ_MAX + 1; | |
1617 +// } | |
1618 +// | |
1619 +// va_start( ap, fmt ); | |
1620 +// | |
1621 +// result = vsnprintf( utf16buf, utf16buf_len, fmt, ap ); | |
1622 +// | |
1623 +// if( result + 1 > utf16buf_len ) { //didn't have space, realloc() and try again | |
1624 +// fprintf(stderr, "utf16_fprintf(): buffer too small (%d), F_MALLOC(%d)\n", utf16buf_len, result); | |
1625 +// free( utf16buf ); | |
1626 +// utf16buf_len = result + 1; | |
1627 +// utf16buf = (char*)F_MALLOC( utf16buf_len ); | |
1628 +// | |
1629 +// result = vsnprintf( utf16buf, utf16buf_len, fmt, ap ); | |
1630 +// } | |
1631 +// | |
1632 +// | |
1633 +// //didn't have space...again...something weird is going on... | |
1634 +// ASSERT( result + 1 <= utf16buf_len, "utf16_fprintf(): Unpossible error!\n"); | |
1635 +// | |
1636 +// if( 1 != utf16_write( stream, utf16buf, result + 1 ) ) | |
1637 +// DIE( "Write error? -> %s or %s\n", strerror( errno ), uerr_str( uerr_get() ) ); | |
1638 +// | |
1639 +// return result; | |
1640 +//} | |
1641 +//// }}} | |
1642 +//int utf16to8( char *inbuf_o, char *outbuf_o, int length ) // {{{ | |
1643 +//{ | |
1644 +// int inbytesleft = length; | |
1645 +// int outbytesleft = length; | |
1646 +// char *inbuf = inbuf_o; | |
1647 +// char *outbuf = outbuf_o; | |
1648 +// int rlen = -1, tlen; | |
1649 +// int icresult = -1; | |
1650 +// | |
1651 +// int i, strlen=-1; | |
1652 +// | |
1653 +// DEBUG( | |
1654 +// fprintf(stderr, " utf16to8(): attempting to convert:\n"); | |
1655 +// //hexdump( (char*)inbuf_o, 0, length, 1 ); | |
1656 +// fflush(stderr); | |
1657 +// ); | |
1658 +// | |
1659 +// for( i=0; i<length ; i+=2 ) { | |
1660 +// if( inbuf_o[i] == 0 && inbuf_o[i + 1] == 0 ) { | |
1661 +// //fprintf(stderr, "End of string found at: %d\n", i ); | |
1662 +// strlen = i; | |
1663 +// } | |
1664 +// } | |
1665 +// | |
1666 +// //hexdump( (char*)inbuf_o, 0, strlen, 1 ); | |
1667 +// | |
1668 +// if( -1 == strlen ) WARN("String is not zero-terminated."); | |
1669 +// | |
1670 +// //iconv does not like it when the inbytesleft > actual string length | |
1671 +// //enum: zero terminated, length valid | |
1672 +// // zero terminated, length short //we won't go beyond length ever, so this is same as NZT case | |
1673 +// // zero terminated, length long | |
1674 +// // not zero terminated | |
1675 +// // TODO: MEMORY BUG HERE! | |
1676 +// for( tlen = 0; tlen <= inbytesleft - 2; tlen+=2 ) { | |
1677 +// if( inbuf_o[tlen] == 0 && inbuf_o[tlen+1] == 0 ){ | |
1678 +// rlen = tlen + 2; | |
1679 +// tlen = rlen; | |
1680 +// break; | |
1681 +// } | |
1682 +// if( tlen == inbytesleft )fprintf(stderr, "Space allocated for string > actual string length. Go windows!\n"); | |
1683 +// } | |
1684 +// | |
1685 +// if( rlen >= 0 ) | |
1686 +// icresult = iconv( i16to8, &inbuf, &rlen, &outbuf, &outbytesleft ); | |
1687 +// | |
1688 +// if( icresult == (size_t)-1 ) { | |
1689 +// fprintf(stderr, "utf16to8(): iconv failure(%d): %s\n", errno, strerror( errno ) ); | |
1690 +// fprintf(stderr, " attempted to convert:\n"); | |
1691 +// hexdump( (char*)inbuf_o, 0, length, 1 ); | |
1692 +// fprintf(stderr, " result:\n"); | |
1693 +// hexdump( (char*)outbuf_o, 0, length, 1 ); | |
1694 +// fprintf(stderr, " MyDirtyOut:\n"); | |
1695 +// for( i=0; i<length; i++) { | |
1696 +// if( inbuf_o[i] != '\0' ) fprintf(stderr, "%c", inbuf_o[i] ); | |
1697 +// } | |
1698 +// | |
1699 +// fprintf( stderr, "\n" ); | |
1700 +// raise( SIGSEGV ); | |
1701 +// exit(1); | |
1702 +// } | |
1703 +// | |
1704 +// DEBUG( | |
1705 +// fprintf(stderr, " result:\n"); | |
1706 +// hexdump( (char*)outbuf_o, 0, length, 1 ); | |
1707 +// ) | |
1708 +// | |
1709 +// //fprintf(stderr, "utf16to8() returning %s\n", outbuf ); | |
1710 +// | |
1711 +// return icresult; | |
1712 +//} | |
1713 +//// }}} | |
1714 +int utf16_is_terminated( char *str, int length ) // {{{ | |
1715 +{ | |
1716 + VSTR_STATIC( errbuf, 100 ); | |
1717 + int len = -1; | |
1718 + int i; | |
1719 + for( i=0; i<length ; i+=2 ) { | |
1720 + if( str[i] == 0 && str[i + 1] == 0 ) { | |
1721 + //fprintf(stderr, "End of string found at: %d\n", i ); | |
1722 + len = i; | |
1723 + } | |
1724 + } | |
1725 + | |
1726 + //hexdump( (char*)inbuf_o, 0, len, 1 ); | |
1727 + | |
1728 + if( -1 == len ) { | |
1729 + vshexdump( errbuf, str, 0, length, 1 ); | |
1730 + WARN("String is not zero terminated (probably broken data from registry) %s.", errbuf->b); | |
1731 + } | |
1732 + | |
1733 + return (-1 == len )?0:1; | |
1734 +} // }}} | |
1735 +int vb_utf16to8( vbuf *dest, char *buf, int len ) // {{{ | |
1736 +{ | |
1737 + int inbytesleft = len; | |
1738 + char *inbuf = buf; | |
1739 + //int rlen = -1, tlen; | |
1740 + int icresult = -1; | |
1741 + VBUF_STATIC( dumpster, 100 ); | |
1742 + | |
1743 + //int i; //, strlen=-1; | |
1744 + int outbytesleft; | |
1745 + char *outbuf; | |
1746 + | |
1747 + ASSERT( unicode_up, "vb_utf16to8() called before unicode started." ); | |
1748 + | |
1749 + if( 2 > dest->blen ) vbresize( dest, 2 ); | |
1750 + dest->dlen = 0; | |
1751 + | |
1752 + //Bad Things can happen if a non-zero-terminated utf16 string comes through here | |
1753 + if( !utf16_is_terminated( buf, len ) ) return -1; | |
1754 + | |
1755 + do { | |
1756 + outbytesleft = dest->blen - dest->dlen; | |
1757 + outbuf = dest->b + dest->dlen; | |
1758 + icresult = iconv( i16to8, &inbuf, &inbytesleft, &outbuf, &outbytesleft ); | |
1759 + dest->dlen = outbuf - dest->b; | |
1760 + vbgrow( dest, inbytesleft); | |
1761 + } while( (size_t)-1 == icresult && E2BIG == errno ); | |
1762 + | |
1763 + if( 0 != vb_utf8to16T( dumpster, dest->b, dest->dlen ) ) | |
1764 + DIE("Reverse conversion failed."); | |
1765 + | |
1766 + if( icresult == (size_t)-1 ) { | |
1767 + //TODO: error | |
1768 + //ERR_UNIX( errno, "vb_utf16to8():iconv failure: %s", strerror( errno ) ); | |
1769 + unicode_init(); | |
1770 + return -1; | |
1771 + /* | |
1772 + fprintf(stderr, " attempted to convert:\n"); | |
1773 + hexdump( (char*)cin, 0, inlen, 1 ); | |
1774 + fprintf(stderr, " result:\n"); | |
1775 + hexdump( (char*)bout->b, 0, bout->dlen, 1 ); | |
1776 + fprintf(stderr, " MyDirtyOut:\n"); | |
1777 + for( i=0; i<inlen; i++) { | |
1778 + if( inbuf[i] != '\0' ) fprintf(stderr, "%c", inbuf[i] ); | |
1779 + } | |
1780 + | |
1781 + fprintf( stderr, "\n" ); | |
1782 + raise( SIGSEGV ); | |
1783 + exit(1); | |
1784 + */ | |
1785 + } | |
1786 + | |
1787 + if( icresult ) { | |
1788 + //ERR_UNIX( EILSEQ, "Uhhhh...vb_utf16to8() returning icresult == %d", icresult ); | |
1789 + return -1; | |
1790 + } | |
1791 + return icresult; | |
1792 +} | |
1793 +// }}} | |
1794 + | |
1795 +int utf8to16( char *inbuf_o, int iblen, char *outbuf_o, int oblen) // {{{ iblen, oblen: bytes including \0 | |
1796 +{ | |
1797 + //TODO: this is *only* used to dump the utf16 preamble now... | |
1798 + //TODO: This (and 8to16) are the most horrible things I have ever seen... | |
1799 + int inbytesleft; | |
1800 + int outbytesleft = oblen; | |
1801 + char *inbuf = inbuf_o; | |
1802 + char *outbuf = outbuf_o; | |
1803 + //int rlen = -1, tlen; | |
1804 + int icresult = -1; | |
1805 + | |
1806 + char *stend; | |
1807 + | |
1808 + //int i; //, strlen=-1; | |
1809 + | |
1810 + DEBUG( | |
1811 + fprintf(stderr, " utf8to16(): attempting to convert:\n"); | |
1812 + //hexdump( (char*)inbuf_o, 0, length, 1 ); | |
1813 + fflush(stderr); | |
1814 + ); | |
1815 + | |
1816 + stend = memchr( inbuf_o, '\0', iblen ); | |
1817 + ASSERT( NULL != stend, "utf8to16(): in string not zero terminated." ); | |
1818 + | |
1819 + inbytesleft = ( stend - inbuf_o + 1 < iblen )? stend - inbuf_o + 1: iblen; | |
1820 + | |
1821 + //iconv does not like it when the inbytesleft > actual string length | |
1822 + //enum: zero terminated, length valid | |
1823 + // zero terminated, length short //we won't go beyond length ever, so this is same as NZT case | |
1824 + // zero terminated, length long | |
1825 + // not zero terminated | |
1826 + // TODO: MEMORY BUG HERE! | |
1827 + // | |
1828 + /* | |
1829 + for( tlen = 0; tlen <= inbytesleft - 2; tlen+=2 ) { | |
1830 + if( inbuf_o[tlen] == 0 && inbuf_o[tlen+1] == 0 ){ | |
1831 + rlen = tlen + 2; | |
1832 + tlen = rlen; | |
1833 + break; | |
1834 + } | |
1835 + if( tlen == inbytesleft )fprintf(stderr, "Space allocated for string > actual string length. Go windows!\n"); | |
1836 + } | |
1837 + */ | |
1838 + | |
1839 + //if( rlen >= 0 ) | |
1840 + icresult = iconv( i8to16, &inbuf, &inbytesleft, &outbuf, &outbytesleft ); | |
1841 + | |
1842 + if( icresult == (size_t)-1 ) { | |
1843 + DIE("iconv failure(%d): %s\n", errno, strerror( errno ) ); | |
1844 + //fprintf(stderr, " attempted to convert:\n"); | |
1845 + //hexdump( (char*)inbuf_o, 0, iblen, 1 ); | |
1846 + //fprintf(stderr, " result:\n"); | |
1847 + //hexdump( (char*)outbuf_o, 0, oblen, 1 ); | |
1848 + //fprintf(stderr, " MyDirtyOut:\n"); | |
1849 +// for( i=0; i<iblen; i++) { | |
1850 +// if( inbuf_o[i] != '\0' ) fprintf(stderr, "%c", inbuf_o[i] ); | |
1851 +// } | |
1852 +// | |
1853 +// fprintf( stderr, "\n" ); | |
1854 +// raise( SIGSEGV ); | |
1855 +// exit(1); | |
1856 + } | |
1857 + | |
1858 +// DEBUG( | |
1859 +// fprintf(stderr, " result:\n"); | |
1860 +// hexdump( (char*)outbuf_o, 0, oblen, 1 ); | |
1861 +// ) | |
1862 + | |
1863 + //fprintf(stderr, "utf8to16() returning %s\n", outbuf ); | |
1864 + | |
1865 + //TODO: error | |
1866 + if( icresult ) printf("Uhhhh...utf8to16() returning icresult == %d\n", icresult ); | |
1867 + return icresult; | |
1868 +} | |
1869 +// }}} | |
1870 + | |
1871 +int vb_utf8to16T( vbuf *bout, char *cin, int inlen ) // {{{ | |
1872 +{ | |
1873 + //TODO: This (and 8to16) are the most horrible things I have ever seen... | |
1874 + int inbytesleft = inlen; | |
1875 + char *inbuf = cin; | |
1876 + //int rlen = -1, tlen; | |
1877 + int icresult = -1; | |
1878 + | |
1879 + //int i; //, strlen=-1; | |
1880 + | |
1881 + //if( rlen >= 0 ) | |
1882 + int outbytesleft; | |
1883 + char *outbuf; | |
1884 + if( 2 > bout->blen ) vbresize( bout, 2 ); | |
1885 + bout->dlen = 0; | |
1886 + | |
1887 + do { | |
1888 + outbytesleft = bout->blen - bout->dlen; | |
1889 + outbuf = bout->b + bout->dlen; | |
1890 + icresult = iconv( i8to16, &inbuf, &inbytesleft, &outbuf, &outbytesleft ); | |
1891 + bout->dlen = outbuf - bout->b; | |
1892 + vbgrow( bout, 20 ); | |
1893 + } while( (size_t)-1 == icresult && E2BIG == errno ); | |
1894 + | |
1895 + if( icresult == (size_t)-1 ) { | |
1896 + WARN("iconv failure: %s", strerror( errno ) ); | |
1897 + //ERR_UNIX( errno, "vb_utf8to16():iconv failure: %s", strerror( errno ) ); | |
1898 + unicode_init(); | |
1899 + return -1; | |
1900 + /* | |
1901 + fprintf(stderr, "vb_utf8to16(): iconv failure(%d == %d?): %s\n", errno, E2BIG, strerror( errno ) ); | |
1902 + fprintf(stderr, " attempted to convert:\n"); | |
1903 + hexdump( (char*)cin, 0, inlen, 1 ); | |
1904 + fprintf(stderr, " result:\n"); | |
1905 + hexdump( (char*)bout->b, 0, bout->dlen, 1 ); | |
1906 + fprintf(stderr, " MyDirtyOut:\n"); | |
1907 + for( i=0; i<inlen; i++) { | |
1908 + if( inbuf[i] != '\0' ) fprintf(stderr, "%c", inbuf[i] ); | |
1909 + } | |
1910 + | |
1911 + fprintf( stderr, "\n" ); | |
1912 + raise( SIGSEGV ); | |
1913 + exit(1); | |
1914 + */ | |
1915 + } | |
1916 + | |
1917 + //TODO: error | |
1918 + if( icresult ) printf("Uhhhh...vb_utf8to16() returning icresult == %d\n", icresult ); | |
1919 + return icresult; | |
1920 +} | |
1921 +// }}} | |
1922 +#if 1 | |
1923 +void cheap_uni2ascii(char *src, char *dest, int l) /* {{{ Quick and dirty UNICODE to std. ascii */ | |
1924 +{ | |
1925 + | |
1926 + for (; l > 0; l -=2) { | |
1927 + *dest = *src; | |
1928 + dest++; src +=2; | |
1929 + } | |
1930 + *dest = 0; | |
1931 +} | |
1932 +// }}} | |
1933 +#endif | |
1934 + | |
1935 +void cheap_ascii2uni(char *src, char *dest, int l) /* {{{ Quick and dirty ascii to unicode */ | |
1936 +{ | |
1937 + for (; l > 0; l--) { | |
1938 + *dest++ = *src++; | |
1939 + *dest++ = 0; | |
1940 + | |
1941 + } | |
1942 +} | |
1943 +// }}} | |
1944 + | |
1945 +// }}} | |
1946 +// {{{ VARBUF Functions | |
1947 +vbuf *vballoc( size_t len ) // {{{ | |
1948 +{ | |
1949 + struct varbuf *result; | |
1950 + | |
1951 + result = F_MALLOC( sizeof( struct varbuf ) ); | |
1952 + | |
1953 + result->dlen = 0; | |
1954 + result->blen = 0; | |
1955 + result->buf = NULL; | |
1956 + | |
1957 + vbresize( result, len ); | |
1958 + | |
1959 + return result; | |
1960 + | |
1961 +} // }}} | |
1962 +void vbcheck( vbuf *vb ) // {{{ | |
1963 +{ | |
1964 + ASSERT( vb->b - vb->buf <= vb->blen, "vbcheck(): vb->b outside of buffer range."); | |
1965 + ASSERT( vb->dlen <= vb->blen, "vbcheck(): data length > buffer length."); | |
1966 + | |
1967 + ASSERT( vb->blen < 1024*1024, "vbcheck(): blen is a bit large...hmmm."); | |
1968 +} // }}} | |
1969 +void vbfree( vbuf *vb ) // {{{ | |
1970 +{ | |
1971 + free( vb->buf ); | |
1972 + free( vb ); | |
1973 +} // }}} | |
1974 +void vbclear( struct varbuf *vb ) // {{{ditch the data, keep the buffer | |
1975 +{ | |
1976 + vbresize( vb, 0 ); | |
1977 +} // }}} | |
1978 +void vbresize( struct varbuf *vb, size_t len ) // {{{ DESTRUCTIVELY grow or shrink buffer | |
1979 +{ | |
1980 + vb->dlen = 0; | |
1981 + | |
1982 + if( vb->blen >= len ) { | |
1983 + vb->b = vb->buf; | |
1984 + return; | |
1985 + } | |
1986 + | |
1987 + vb->buf = F_REALLOC( vb->buf, len ); | |
1988 + vb->b = vb->buf; | |
1989 + vb->blen = len; | |
1990 +} // }}} | |
1991 +int vbavail( vbuf *vb ) // {{{ | |
1992 +{ | |
1993 + return vb->blen - ((char*)vb->b - (char*)vb->buf + vb->dlen); | |
1994 +} // }}} | |
1995 +//void vbdump( vbuf *vb ) // {{{ TODO: to stdout? Yuck | |
1996 +//{ | |
1997 +// printf("vb dump-------------\n"); | |
1998 +// printf("dlen: %d\n", vb->dlen ); | |
1999 +// printf("blen: %d\n", vb->blen ); | |
2000 +// printf("b - buf: %d\n", vb->b - vb->buf ); | |
2001 +// printf("buf:\n"); | |
2002 +// hexdump( vb->buf, 0, vb->blen, 1 ); | |
2003 +// printf("b:\n"); | |
2004 +// hexdump( vb->b, 0, vb->dlen, 1 ); | |
2005 +// printf("^^^^^^^^^^^^^^^^^^^^\n"); | |
2006 +//} // }}} | |
2007 +void vbgrow( struct varbuf *vb, size_t len ) // {{{ out: vbavail(vb) >= len, data are preserved | |
2008 +{ | |
2009 + if( 0 == len ) return; | |
2010 + | |
2011 + if( 0 == vb->blen ) { | |
2012 + vbresize( vb, len ); | |
2013 + return; | |
2014 + } | |
2015 + | |
2016 + if( vb->dlen + len > vb->blen ) { | |
2017 + if( vb->dlen + len < vb->blen * 1.5 ) len = vb->blen * 1.5; | |
2018 + char *nb = F_MALLOC( vb->blen + len ); | |
2019 + //printf("vbgrow() got %p back from malloc(%d)\n", nb, vb->blen + len); | |
2020 + vb->blen = vb->blen + len; | |
2021 + memcpy( nb, vb->b, vb->dlen ); | |
2022 + | |
2023 + //printf("vbgrow() I am going to free %p\n", vb->buf ); | |
2024 + free( vb->buf ); | |
2025 + vb->buf = nb; | |
2026 + vb->b = vb->buf; | |
2027 + } else { | |
2028 + if( vb->b != vb->buf ) | |
2029 + memcpy( vb->buf, vb->b, vb->dlen ); | |
2030 + } | |
2031 + | |
2032 + vb->b = vb->buf; | |
2033 + | |
2034 + ASSERT( vbavail( vb ) >= len, "vbgrow(): I have failed in my mission." ); | |
2035 +} // }}} | |
2036 +void vbset( vbuf *vb, void *b, size_t len ) // {{{ set vbuf b size=len, resize if necessary, relen = how much to over-allocate | |
2037 +{ | |
2038 + vbresize( vb, len ); | |
2039 + | |
2040 + memcpy( vb->b, b, len ); | |
2041 + vb->dlen = len; | |
2042 +} // }}} | |
2043 +void vsskipws( vstr *vs ) // {{{ | |
2044 +{ | |
2045 + char *p = vs->b; | |
2046 + while( p - vs->b < vs->dlen && isspace( p[0] ) ) p++; | |
2047 + | |
2048 + vbskip( (vbuf*)vs, p - vs->b ); | |
2049 +} // }}} | |
2050 +void vbappend( struct varbuf *vb, void *b, size_t len ) // {{{ append len bytes of b to vbuf, resize if necessary | |
2051 +{ | |
2052 + if( 0 == vb->dlen ) { | |
2053 + vbset( vb, b, len ); | |
2054 + return; | |
2055 + } | |
2056 + | |
2057 + vbgrow( vb, len ); | |
2058 + | |
2059 + memcpy( vb->b + vb->dlen, b, len ); | |
2060 + vb->dlen += len; | |
2061 + | |
2062 + //printf("vbappend() end: >%s/%d<\n", vbuf->b, vbuf->dlen ); | |
2063 +} // }}} | |
2064 +void vbskip( struct varbuf *vb, size_t skip ) // {{{ dumps the first skip bytes from vbuf | |
2065 +{ | |
2066 + ASSERT( skip <= vb->dlen, "vbskip(): Attempt to seek past end of buffer." ); | |
2067 + //memmove( vbuf->b, vbuf->b + skip, vbuf->dlen - skip ); | |
2068 + vb->b += skip; | |
2069 + vb->dlen -= skip; | |
2070 +} // }}} | |
2071 +void vboverwrite( struct varbuf *vbdest, struct varbuf *vbsrc ) // {{{ overwrite vbdest with vbsrc | |
2072 +{ | |
2073 + vbresize( vbdest, vbsrc->blen ); | |
2074 + memcpy( vbdest->b, vbsrc->b, vbsrc->dlen ); | |
2075 + vbdest->blen = vbsrc->blen; | |
2076 + vbdest->dlen = vbsrc->dlen; | |
2077 +} // }}} | |
2078 +// }}} | |
2079 +// {{{ VARSTR Functions | |
2080 +vstr *vsalloc( size_t len ) // {{{ | |
2081 +{ | |
2082 + vstr *result = (vstr*)vballoc( len + 1 ); | |
2083 + vsset( result, "" ); | |
2084 + return result; | |
2085 +} // }}} | |
2086 +char *vsstr( vstr *vs ) // {{{ | |
2087 +{ | |
2088 + return vs->b; | |
2089 +} // }}} | |
2090 +size_t vslen( vstr *vs ) // {{{ | |
2091 +{ | |
2092 + return strlen( vsstr( vs )); | |
2093 +} // }}} | |
2094 +void vsfree( vstr *vs ) // {{{ | |
2095 +{ | |
2096 + vbfree( (vbuf*)vs ); | |
2097 +} // }}} | |
2098 +void vscharcat( vstr *vb, int ch ) // {{{ | |
2099 +{ | |
2100 + vbgrow( (vbuf*)vb, 1); | |
2101 + vb->b[vb->dlen-1] = ch; | |
2102 + vb->b[vb->dlen] = '\0'; | |
2103 + vb->dlen++; | |
2104 +} // }}} | |
2105 +void vsnprepend( vstr *vb, char *str, size_t len ) // {{{ prependappend string str to vbuf, vbuf must already contain a valid string | |
2106 +{ | |
2107 + ASSERT( vb->b[vb->dlen-1] == '\0', "vsncat(): attempt to append string to non-string."); | |
2108 + int sl = strlen( str ); | |
2109 + int n = (sl<len)?sl:len; | |
2110 + //string append | |
2111 + vbgrow( (vbuf*)vb, n + 1 ); | |
2112 + memmove( vb->b + n, vb->b, vb->dlen - 1 ); | |
2113 + memcpy( vb->b, str, n ); | |
2114 + //strncat( vb->b, str, n ); | |
2115 + | |
2116 + vb->dlen += n; | |
2117 + vb->b[ vb->dlen - 1 ] = '\0'; | |
2118 +} // }}} | |
2119 +void vsskip( vstr *vs, size_t len ) // {{{ len < dlen-1 -> skip len chars, else DIE | |
2120 +{ | |
2121 + ASSERT( len < vs->dlen - 1, "Attempt to skip past end of string" ); | |
2122 + vbskip( (vbuf*)vs, len ); | |
2123 +} // }}} | |
2124 +int vsskipline( vstr *vs ) // {{{ in: vb->b == "stuff\nmore_stuff"; out: vb->b == "more_stuff" | |
2125 +{ | |
2126 + int nloff = find_nl( vs ); | |
2127 + int nll = skip_nl( vs->b + nloff ); | |
2128 + | |
2129 + if( nloff < 0 ) { | |
2130 + //TODO: error | |
2131 + printf("vb_skipline(): there seems to be no newline here.\n"); | |
2132 + return -1; | |
2133 + } | |
2134 + if( skip_nl < 0 ) { | |
2135 + //TODO: error | |
2136 + printf("vb_skipline(): there seems to be no newline here...except there should be. :P\n"); | |
2137 + return -1; | |
2138 + } | |
2139 + | |
2140 + memmove( vs->b, vs->b + nloff + nll, vs->dlen - nloff - nll ); | |
2141 + | |
2142 + vs->dlen -= nloff + nll; | |
2143 + | |
2144 + return 0; | |
2145 +} // }}} | |
2146 +int vscatprintf( vstr *vs, char *fmt, ... ) // {{{ | |
2147 +{ | |
2148 + int size; | |
2149 + va_list ap; | |
2150 + | |
2151 + /* Guess we need no more than 100 bytes. */ | |
2152 + //vsresize( vb, 100 ); | |
2153 + if(!vs->b || vs->dlen == 0) { | |
2154 + vsset( vs, "" ); | |
2155 + } | |
2156 + | |
2157 + while (1) { | |
2158 + /* Try to print in the allocated space. */ | |
2159 + va_start(ap, fmt); | |
2160 + size = vsnprintf (vs->b + vs->dlen - 1, vs->blen - vs->dlen, fmt, ap); | |
2161 + va_end(ap); | |
2162 + | |
2163 + /* If that worked, return the string. */ | |
2164 + if (size > -1 && size < vs->blen - vs->dlen ) { | |
2165 + vs->dlen += size; | |
2166 + return size; | |
2167 + } | |
2168 + /* Else try again with more space. */ | |
2169 + if ( size >= 0 ) /* glibc 2.1 */ | |
2170 + vbgrow( (vbuf*)vs, size+1 ); /* precisely what is needed */ | |
2171 + else /* glibc 2.0 */ | |
2172 + vbgrow( (vbuf*)vs, vs->blen); | |
2173 + } | |
2174 +} // }}} | |
2175 +int vslast( vstr *vs ) // {{{ returns the last character stored in a vstr | |
2176 +{ | |
2177 + if( vs->dlen < 1 ) return -1; | |
2178 + if( vs->b[vs->dlen-1] != '\0' ) return -1; | |
2179 + if( vs->dlen == 1 ) return '\0'; | |
2180 + return vs->b[vs->dlen-2]; | |
2181 +} // }}} | |
2182 +void vs_printf( vstr *vs, char *fmt, ... ) // {{{ print over vb | |
2183 +{ | |
2184 + int size; | |
2185 + va_list ap; | |
2186 + | |
2187 + /* Guess we need no more than 100 bytes. */ | |
2188 + vbresize( (vbuf*)vs, 100 ); | |
2189 + | |
2190 + while (1) { | |
2191 + /* Try to print in the allocated space. */ | |
2192 + va_start(ap, fmt); | |
2193 + size = vsnprintf (vs->b, vs->blen, fmt, ap); | |
2194 + va_end(ap); | |
2195 + | |
2196 + /* If that worked, return the string. */ | |
2197 + if (size > -1 && size < vs->blen) { | |
2198 + vs->dlen = size + 1; | |
2199 + return; | |
2200 + } | |
2201 + /* Else try again with more space. */ | |
2202 + if ( size >= 0 ) /* glibc 2.1 */ | |
2203 + vbresize( (vbuf*)vs, size+1 ); /* precisely what is needed */ | |
2204 + else /* glibc 2.0 */ | |
2205 + vbresize( (vbuf*)vs, vs->blen*2); | |
2206 + } | |
2207 +} // }}} | |
2208 +void vs_printfa( vstr *vs, char *fmt, ... ) // {{{ printf append to vs | |
2209 +{ | |
2210 + int size; | |
2211 + va_list ap; | |
2212 + | |
2213 + if( vs->blen - vs->dlen < 50 ) | |
2214 + vbgrow( (vbuf*)vs, 100 ); | |
2215 + | |
2216 + while (1) { | |
2217 + /* Try to print in the allocated space. */ | |
2218 + va_start(ap, fmt); | |
2219 + size = vsnprintf (vs->b + vs->dlen - 1, vs->blen - vs->dlen + 1, fmt, ap); | |
2220 + va_end(ap); | |
2221 + | |
2222 + /* If that worked, return the string. */ | |
2223 + if (size > -1 && size < vs->blen) { | |
2224 + vs->dlen += size; | |
2225 + return; | |
2226 + } | |
2227 + /* Else try again with more space. */ | |
2228 + if ( size >= 0 ) /* glibc 2.1 */ | |
2229 + vbgrow( (vbuf*)vs, size+1 - vs->dlen ); /* precisely what is needed */ | |
2230 + else /* glibc 2.0 */ | |
2231 + vbgrow( (vbuf*)vs, size ); | |
2232 + } | |
2233 +} // }}} | |
2234 +void vshexdump( vstr *vs, char *b, size_t start, size_t stop, int ascii ) // {{{ | |
2235 +{ | |
2236 + char c; | |
2237 + int diff,i; | |
2238 + | |
2239 + while (start < stop ) { | |
2240 + diff = stop - start; | |
2241 + if (diff > 16) diff = 16; | |
2242 + | |
2243 + vs_printfa(vs, ":%08X ",start); | |
2244 + | |
2245 + for (i = 0; i < diff; i++) { | |
2246 + if( 8 == i ) vs_printfa( vs, " " ); | |
2247 + vs_printfa(vs, "%02X ",(unsigned char)*(b+start+i)); | |
2248 + } | |
2249 + if (ascii) { | |
2250 + for (i = diff; i < 16; i++) vs_printfa(vs, " "); | |
2251 + for (i = 0; i < diff; i++) { | |
2252 + c = *(b+start+i); | |
2253 + vs_printfa(vs, "%c", isprint(c) ? c : '.'); | |
2254 + } | |
2255 + } | |
2256 + vs_printfa(vs, "\n"); | |
2257 + start += 16; | |
2258 + } | |
2259 +} // }}} | |
2260 +void vsset( vstr *vs, char *s ) // {{{ Store string s in vs | |
2261 +{ | |
2262 + vsnset( vs, s, strlen( s ) ); | |
2263 +} // }}} | |
2264 +void vsnset( vstr *vs, char *s, size_t n ) // {{{ Store string s in vs | |
2265 +{ | |
2266 + vbresize( (vbuf*)vs, n + 1 ); | |
2267 + memcpy( vs->b, s, n); | |
2268 + vs->b[n] = '\0'; | |
2269 + vs->dlen = n+1; | |
2270 +} // }}} | |
2271 +void vsgrow( vstr *vs, size_t len ) // {{{ grow buffer by len bytes, data are preserved | |
2272 +{ | |
2273 + vbgrow( (vbuf*)vs, len ); | |
2274 +} // }}} | |
2275 +size_t vsavail( vstr *vs ) // {{{ | |
2276 +{ | |
2277 + return vbavail( (vbuf*)vs ); | |
2278 +} // }}} | |
2279 +void vsnset16( vstr *vs, char *s, size_t len ) // {{{ Like vbstrnset, but for UTF16 | |
2280 +{ | |
2281 + vbresize( (vbuf*)vs, len+1 ); | |
2282 + memcpy( vs->b, s, len ); | |
2283 + | |
2284 + vs->b[len] = '\0'; | |
2285 + vs->dlen = len+1; | |
2286 + vs->b[len] = '\0'; | |
2287 +} // }}} | |
2288 +void vscat( vstr *vs, char *str ) // {{{ | |
2289 +{ | |
2290 + vsncat( vs, str, strlen(str ) ); | |
2291 +} // }}} | |
2292 +int vscmp( vstr *vs, char *str ) // {{{ | |
2293 +{ | |
2294 + return strcmp( vs->b, str ); | |
2295 +} // }}} | |
2296 +void vsncat( vstr *vs, char *str, size_t len ) // {{{ append string str to vstr, vstr must already contain a valid string | |
2297 +{ | |
2298 + ASSERT( vs->b[vs->dlen-1] == '\0', "vsncat(): attempt to append string to non-string."); | |
2299 + int sl = strlen( str ); | |
2300 + int n = (sl<len)?sl:len; | |
2301 + //string append | |
2302 + vbgrow( (vbuf*)vs, n + 1 ); | |
2303 + memcpy( vs->b + vs->dlen - 1, str, n ); | |
2304 + //strncat( vs->b, str, n ); | |
2305 + | |
2306 + vs->dlen += n; | |
2307 + vs->b[ vs->dlen - 1 ] = '\0'; | |
2308 +} // }}} | |
2309 +void vstrunc( vstr *v, int off ) // {{{ Drop chars [off..dlen] | |
2310 +{ | |
2311 + if( off >= v->dlen - 1 ) return; //nothing to do | |
2312 + v->b[off] = '\0'; | |
2313 + v->dlen = off + 1; | |
2314 +} | |
2315 +// }}} | |
2316 +// }}} | |
2317 +// {{{ User input | |
2318 +// TODO: not sure how useful this stuff is here | |
2319 +int fmyinput(char *prmpt, char *ibuf, int maxlen) /* {{{ get user input */ | |
2320 +{ | |
2321 + printf("%s",prmpt); | |
2322 + | |
2323 + fgets(ibuf,maxlen+1,stdin); | |
2324 + | |
2325 + ibuf[strlen(ibuf)-1] = 0; | |
2326 + | |
2327 + return(strlen(ibuf)); | |
2328 +} | |
2329 +// }}} | |
2330 +//}}} | |
2331 +// | |
2332 +// | |
2333 +//{{{ String formatting and output to FILE *stream or just stdout, etc | |
2334 +// TODO: a lot of old, unused stuff in here | |
2335 +void vswinhex8(vstr *vs, unsigned char *hbuf, int start, int stop, int loff ) // {{{ Produce regedit-style hex output */ | |
2336 +{ | |
2337 + int i; | |
2338 + int lineflag=0; | |
2339 + | |
2340 + for( i=start; i<stop; i++) | |
2341 + { | |
2342 + loff += vscatprintf( vs, "%02x", hbuf[i] ); | |
2343 + if( i < stop - 1 ) { | |
2344 + loff+=vscatprintf( vs, "," ); | |
2345 + switch( lineflag ) { | |
2346 + case 0: | |
2347 + if( loff >= 77) { | |
2348 + lineflag=1; | |
2349 + loff=0; | |
2350 + vscatprintf( vs, "\\%s ", STUPID_CR ); | |
2351 + } | |
2352 + break; | |
2353 + case 1: | |
2354 + if( loff >= 75 ) { | |
2355 + loff=0; | |
2356 + vscatprintf( vs, "\\%s ", STUPID_CR ); | |
2357 + } | |
2358 + break; | |
2359 + } | |
2360 + // if( 24 < i || 0 == (i - 17) % 25 ) fprintf( stream, "\\\n " ); | |
2361 + } | |
2362 + } | |
2363 + | |
2364 + // fprintf( stream, "\n" ); | |
2365 +} // }}} | |
2366 diff -Naur ../orig/libpst-0.5.1/vbuf.h libpst64-060926/vbuf.h | |
2367 --- ../orig/libpst-0.5.1/vbuf.h 1969-12-31 17:00:00.000000000 -0700 | |
2368 +++ libpst64-060926/vbuf.h 2006-09-26 14:09:55.000000000 -0600 | |
2369 @@ -0,0 +1,142 @@ | |
2370 +/* {{{ vbuf.h - variable length buffer functions | |
2371 + * | |
2372 + * Functions that try to make dealing with buffers easier. | |
2373 + * | |
2374 + * vbuf | |
2375 + * | |
2376 + * vstr | |
2377 + * - should always contain a valid string | |
2378 + * | |
2379 + * }}} */ | |
2380 + | |
2381 +#ifndef VBUF_H | |
2382 +#define VBUF_H | |
2383 +#define SZ_MAX 4096 | |
2384 +#include <stdlib.h> | |
2385 +#include <stdio.h> | |
2386 +#include <stdarg.h> | |
2387 +/***************************************************/ | |
2388 + | |
2389 +// {{{ Tokenizer const TOK_EMPTY, TOK_ELEMENT, DELIM | |
2390 +#define DELIM '\\' | |
2391 + | |
2392 +#define TOK_EMPTY 0 | |
2393 +#define TOK_DELIM 1 | |
2394 +#define TOK_PARENT 2 | |
2395 +#define TOK_CURRENT 3 | |
2396 +#define TOK_ELEMENT 4 | |
2397 + | |
2398 +#define TOK_ERROR 10 | |
2399 +#define TOK_BUF_SMALL 11 | |
2400 +// }}} | |
2401 + | |
2402 + | |
2403 +// Variable-length buffers | |
2404 +struct varbuf { // {{{ | |
2405 + size_t dlen; //length of data stored in buffer | |
2406 + size_t blen; //length of buffer | |
2407 + char *buf; //buffer | |
2408 + char *b; //start of stored data | |
2409 +}; // }}} | |
2410 + | |
2411 + | |
2412 +// The exact same thing as a varbuf but should always contain at least '\0' | |
2413 +struct varstr { // {{{ | |
2414 + size_t dlen; //length of data stored in buffer | |
2415 + size_t blen; //length of buffer | |
2416 + char *buf; //buffer | |
2417 + char *b; //start of stored data | |
2418 +}; // }}} | |
2419 + | |
2420 + | |
2421 +typedef struct varbuf vbuf; | |
2422 +typedef struct varstr vstr; | |
2423 + | |
2424 +#define VBUF_STATIC(x,y) static vbuf *x = NULL; if(!x) x = vballoc(y); | |
2425 +#define VSTR_STATIC(x,y) static vstr *x = NULL; if(!x) x = vsalloc(y); | |
2426 + | |
2427 +// vbuf functions | |
2428 +struct varbuf *vballoc( size_t len ); | |
2429 +void vbfree( vbuf *vb ); | |
2430 +void vbclear( vbuf *vb ); //ditch the data, keep the buffer | |
2431 +void vbresize( vbuf *vb, size_t len ); | |
2432 +int vbavail( vbuf *vb ); | |
2433 +void vbdump( vbuf *vb ); | |
2434 +void vbgrow( vbuf *vb, size_t len ); // grow buffer by len bytes, data are preserved | |
2435 +void vbset( vbuf *vb, void *data, size_t len ); | |
2436 +void vbskipws( vbuf *vb ); | |
2437 +void vbappend( vbuf *vb, void *data, size_t length ); | |
2438 +void vbskip( vbuf *vb, size_t skip ); | |
2439 +void vboverwrite( vbuf *vbdest, vbuf *vbsrc ); | |
2440 + | |
2441 +// vstr functions | |
2442 +vstr *vsalloc( size_t len ); | |
2443 +char *vsb( vstr *vs ); | |
2444 +size_t vslen( vstr *vs ); //strlen | |
2445 +void vsfree( vstr *vs ); | |
2446 +void vsset( vstr *vs, char *s ); // Store string s in vb | |
2447 +void vsnset( vstr *vs, char *s, size_t n ); // Store string s in vb | |
2448 +void vsgrow( vstr *vs, size_t len ); // grow buffer by len bytes, data are preserved | |
2449 +size_t vsavail( vstr *vs ); | |
2450 +void vscat( vstr *vs, char *str ); | |
2451 +void vsncat( vstr *vs, char *str, size_t len ); | |
2452 +void vsnprepend( vstr *vs, char *str, size_t len ) ; | |
2453 +void vsskip( vstr *vs, size_t len ); | |
2454 +int vscmp( vstr *vs, char *str ); | |
2455 +void vsskipws( vstr *vs ); | |
2456 +void vs_printf( vstr *vs, char *fmt, ... ); | |
2457 +void vs_printfa( vstr *vs, char *fmt, ... ); | |
2458 +void vshexdump( vstr *vs, char *b, size_t start, size_t stop, int ascii ); | |
2459 +int vscatprintf( vstr *vs, char *fmt, ... ); | |
2460 +void vsvprintf( vstr *vs, char *fmt, va_list ap ); | |
2461 +void vstrunc( vstr *vs, int off ); // Drop chars [off..dlen] | |
2462 +int vslast( vstr *vs ); // returns the last character stored in a vstr string | |
2463 +void vscharcat( vstr *vs, int ch ); | |
2464 +int vsutf16( vstr *vs, vbuf *in ); //in: in=zero-terminated utf16; out: vs=utf8; returns: 0 on success, else on fail | |
2465 + | |
2466 +int vs_parse_escaped_string( vstr *vs, char *str, size_t len ); | |
2467 + | |
2468 + | |
2469 +/* | |
2470 + * Windows unicode output trash - this stuff sucks | |
2471 + * TODO: most of this should not be here | |
2472 + */ | |
2473 + | |
2474 +void unicode_init(); | |
2475 +void unicode_close(); | |
2476 +int utf16_write( FILE* stream, const void *buf, size_t count ); | |
2477 +int utf16_fprintf( FILE* stream, const char *fmt, ... ); | |
2478 +int utf16to8( char *inbuf_o, char *outbuf_o, int length ); | |
2479 +int utf8to16( char *inbuf_o, int iblen, char *outbuf_o, int oblen); | |
2480 +int vb_utf8to16T( vbuf *bout, char *cin, int inlen ); | |
2481 +int vb_utf16to8( vbuf *dest, char *buf, int len ); | |
2482 +int iso8859_1to8( char *inbuf_o, char *outbuf_o, int length ); | |
2483 +int utf8toascii( const char *inbuf_o, char *outbuf_o, int length ); | |
2484 + | |
2485 +/* dump ascii hex in windoze format */ | |
2486 +void winhex(FILE* stream, unsigned char *hbuf, int start, int stop, int loff); | |
2487 +void winhex8(FILE *stream, unsigned char *hbuf, int start, int stop, int loff ); | |
2488 + | |
2489 +void vbwinhex8(vbuf *vb, unsigned char *hbuf, int start, int stop, int loff ); | |
2490 + | |
2491 +/* general search routine, find something in something else */ | |
2492 +int find_in_buf(char *buf, char *what, int sz, int len, int start); | |
2493 + | |
2494 +/* Get INTEGER from memory. This is probably low-endian specific? */ | |
2495 +int get_int( char *array ); | |
2496 + | |
2497 +int find_nl( vstr *vs ); // find newline of type type in b | |
2498 +int skip_nl( char *s ); // returns the width of the newline at s[0] | |
2499 +//int vb_readline( struct varbuf *vb, int *ctype, FILE *in ); // read *AT LEAST* one full line of data from in | |
2500 +int vb_skipline( struct varbuf *vb ); // in: vb->b == "stuff\nmore_stuff"; out: vb->b == "more_stuff" | |
2501 +/* Get a string of HEX bytes (space separated), | |
2502 + * or if first char is ' get an ASCII string instead. */ | |
2503 +int gethexorstr(char **c, char *wb); | |
2504 +char *esc_index( char *s, int c ); // just like index(3), but works on strings with escape sequences | |
2505 +char *esc_rindex( char *s, int c ); // just like rindex(3), but works on strings with escape sequences | |
2506 + | |
2507 +char *tok_esc_char( char *s, int *is_esc, int *c ); | |
2508 +int vb_path_token( vbuf *tok, char **path ); // returns things like TOK_EMPTY, TOK_ERROR, complete list at top | |
2509 + | |
2510 +int gettoken( char *tok, int len, char **path, char delim ); // Path tokenizer: increments path, dumps token in tok | |
2511 +#endif |