~ubuntu-branches/ubuntu/natty/zziplib/natty

« back to all changes in this revision

Viewing changes to zzip/mmapped.c

  • Committer: Bazaar Package Importer
  • Author(s): Anibal Monsalve Salazar
  • Date: 2009-03-23 21:13:57 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090323211357-6j35t8532ie9wlxf
Tags: 0.13.50-1
* New upstream version 
  - Update 01-fetch.patch
* debhelper compat version is 7
* Standards version is 3.8.1
* Run dh_prep instead of dh_clean -k
* Add debian/watch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
1
2
/*
2
3
 * NOTE: this is part of libzzipmmapped (i.e. it is not libzzip).
3
4
 *                                            ==================
65
66
 * This function does primary initialization of a disk-buffer struct.
66
67
 */
67
68
int
68
 
zzip_disk_init(ZZIP_DISK* disk, void* buffer, zzip_size_t buflen)
 
69
zzip_disk_init(ZZIP_DISK * disk, void *buffer, zzip_size_t buflen)
69
70
{
70
 
    disk->buffer = (zzip_byte_t*) buffer;
71
 
    disk->endbuf = (zzip_byte_t*) buffer + buflen;
 
71
    disk->buffer = (zzip_byte_t *) buffer;
 
72
    disk->endbuf = (zzip_byte_t *) buffer + buflen;
72
73
    disk->reserved = 0;
73
74
    disk->flags = 0;
74
75
    disk->mapped = 0;
80
81
/** => zzip_disk_mmap
81
82
 * This function allocates a new disk-buffer with => malloc(3)
82
83
 */
83
 
zzip__new__ ZZIP_DISK*
 
84
zzip__new__ ZZIP_DISK *
84
85
zzip_disk_new(void)
85
86
{
86
 
    ZZIP_DISK* disk = malloc(sizeof(disk));
87
 
    if (! disk) return disk;
88
 
    zzip_disk_init (disk, 0, 0);
 
87
    ZZIP_DISK *disk = malloc(sizeof(disk));
 
88
    if (! disk)
 
89
        return disk;
 
90
    zzip_disk_init(disk, 0, 0);
89
91
    return disk;
90
92
}
91
93
 
96
98
 * successful then a newly allocated ZZIP_DISK* is returned with 
97
99
 * disk->buffer pointing to the mapview of the zipdisk content.
98
100
 */
99
 
zzip__new__ ZZIP_DISK*
 
101
zzip__new__ ZZIP_DISK *
100
102
zzip_disk_mmap(int fd)
101
103
{
102
104
    struct stat st;
103
 
    if (fstat (fd, &st) || ! st.st_size) return 0;
104
 
    ___ ZZIP_DISK* disk = zzip_disk_new (); if (! disk) return 0;
105
 
    disk->buffer = _zzip_mmap (& disk->mapped, fd, 0, st.st_size);
106
 
    if (disk->buffer == MAP_FAILED) { free (disk); return 0; }
 
105
    if (fstat(fd, &st) || ! st.st_size)
 
106
        return 0;
 
107
    ___ ZZIP_DISK *disk = zzip_disk_new();
 
108
    if (! disk)
 
109
        return 0;
 
110
    disk->buffer = _zzip_mmap(&disk->mapped, fd, 0, st.st_size);
 
111
    if (disk->buffer == MAP_FAILED)
 
112
        { free (disk); return 0; }
107
113
    disk->endbuf = disk->buffer + st.st_size;
108
 
    return disk; ____;
 
114
    return disk;
 
115
    ____;
109
116
}
110
117
 
111
118
/** => zzip_disk_mmap
113
120
 * munmap(2) on the buffer area and => free(3) on the ZZIP_DISK structure.
114
121
 */
115
122
int
116
 
zzip_disk_munmap(ZZIP_DISK* disk)
 
123
zzip_disk_munmap(ZZIP_DISK * disk)
117
124
{
118
 
    if (! disk) return 0;
119
 
    _zzip_munmap (disk->mapped, disk->buffer, disk->endbuf-disk->buffer);
120
 
    free (disk);
 
125
    if (! disk)
 
126
        return 0;
 
127
    _zzip_munmap(disk->mapped, disk->buffer, disk->endbuf - disk->buffer);
 
128
    free(disk);
121
129
    return 0;
122
130
}
123
131
 
129
137
 * memory block. Only if that fails too then we return null. Since handling
130
138
 * of disk->buffer is ambigous it should not be snatched away please.
131
139
 */
132
 
ZZIP_DISK* zzip__new__
133
 
zzip_disk_open(char* filename)
 
140
ZZIP_DISK *zzip__new__
 
141
zzip_disk_open(char *filename)
134
142
{
135
143
#  ifndef O_BINARY
136
144
#  define O_BINARY 0
137
145
#  endif
138
146
    struct stat st;
139
 
    if (stat (filename, &st) || ! st.st_size) return 0;
140
 
    ___ int fd = open (filename, O_RDONLY|O_BINARY);
141
 
    if (fd <= 0) return 0;
142
 
    ___ ZZIP_DISK* disk = zzip_disk_mmap (fd);
143
 
    if (disk) return disk;
144
 
    ___ zzip_byte_t* buffer = malloc (st.st_size);
145
 
    if (! buffer) return 0;
146
 
    if ((st.st_size == read (fd, buffer, st.st_size)) &&
147
 
        (disk = zzip_disk_new ())) 
 
147
    if (stat(filename, &st) || ! st.st_size)
 
148
        return 0;
 
149
    ___ int fd = open(filename, O_RDONLY | O_BINARY);
 
150
    if (fd <= 0)
 
151
        return 0;
 
152
    ___ ZZIP_DISK *disk = zzip_disk_mmap(fd);
 
153
    if (disk)
 
154
        return disk;
 
155
    ___ zzip_byte_t *buffer = malloc(st.st_size);
 
156
    if (! buffer)
 
157
        return 0;
 
158
    if ((st.st_size == read(fd, buffer, st.st_size)) &&
 
159
        (disk = zzip_disk_new()))
148
160
    {
149
 
        disk->buffer = buffer;
150
 
        disk->endbuf = buffer+st.st_size;
151
 
        disk->mapped = -1;
152
 
    }else free (buffer);
153
 
    return disk; ____;____;____;
 
161
        disk->buffer = buffer;
 
162
        disk->endbuf = buffer + st.st_size;
 
163
        disk->mapped = -1;
 
164
    } else
 
165
        free(buffer);
 
166
    return disk;
 
167
    ____;
 
168
    ____;
 
169
    ____;
154
170
}
155
171
 
156
172
/** => zzip_disk_mmap
160
176
 * and it dumps the handle struct as well.
161
177
 */
162
178
int
163
 
zzip_disk_close(ZZIP_DISK* disk)
 
179
zzip_disk_close(ZZIP_DISK * disk)
164
180
{
165
 
    if (! disk) return 0;
166
 
    if (disk->mapped != -1) return zzip_disk_munmap (disk);
167
 
    free (disk->buffer);
168
 
    free (disk);
 
181
    if (! disk)
 
182
        return 0;
 
183
    if (disk->mapped != -1)
 
184
        return zzip_disk_munmap(disk);
 
185
    free(disk->buffer);
 
186
    free(disk);
169
187
    return 0;
170
188
}
171
189
 
172
190
/* ====================================================================== */
 
191
 
173
192
/*                      helper functions                                  */
174
193
 
175
194
#ifdef ZZIP_HAVE_STRNDUP
176
195
#define _zzip_strndup strndup
177
196
#else
 
197
 
178
198
/* if your system does not have strndup: */
179
 
zzip__new__ static char* _zzip_strndup(char* p, size_t maxlen)
 
199
zzip__new__ static char *
 
200
_zzip_strndup(char *p, size_t maxlen)
180
201
{
181
 
    if (! p) return 0;
182
 
    ___ zzip_byte_t* r = malloc (maxlen+1);
183
 
    if (! r) return r;
184
 
    strncpy (r, p, maxlen);
 
202
    if (! p)
 
203
        return 0;
 
204
    ___ zzip_byte_t *r = malloc(maxlen + 1);
 
205
    if (! r)
 
206
        return r;
 
207
    strncpy(r, p, maxlen);
185
208
    r[maxlen] = '\0';
186
 
    return r; ____;
 
209
    return r;
 
210
    ____;
187
211
}
188
212
#endif
189
213
 
190
214
#if defined ZZIP_HAVE_STRCASECMP || defined strcasecmp
191
215
#define _zzip_strcasecmp strcasecmp
192
216
#else
 
217
 
193
218
/* if your system does not have strcasecmp: */
194
 
static int _zzip_strcasecmp(char* __zzip_restrict a, char* _zzip_restrict b)
 
219
static int
 
220
_zzip_strcasecmp(char *__zzip_restrict a, char *_zzip_restrict b)
195
221
{
196
 
    if (! a) return (b) ? 1 : 0;
197
 
    if (! b) return -1;
198
 
    while (1) 
 
222
    if (! a)
 
223
        return (b) ? 1 : 0;
 
224
    if (! b)
 
225
        return -1;
 
226
    while (1)
199
227
    {
200
 
        int v = tolower(*a) - tolower(*b);
201
 
        if (v) return v;
202
 
        if (! *a) return 1;
203
 
        if (! *b) return -1;
204
 
        a++; b++;
 
228
        int v = tolower(*a) - tolower(*b);
 
229
        if (v)
 
230
            return v;
 
231
        if (! *a)
 
232
            return 1;
 
233
        if (! *b)
 
234
            return -1;
 
235
        a++;
 
236
        b++;
205
237
    }
206
238
}
207
239
#endif
213
245
 * the data block right after the file_header. Only disk->buffer would be
214
246
 * needed to perform the seek but we check the mmapped range end as well.
215
247
 */
216
 
zzip_byte_t*
217
 
zzip_disk_entry_to_data(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
 
248
zzip_byte_t *
 
249
zzip_disk_entry_to_data(ZZIP_DISK * disk, struct zzip_disk_entry * entry)
218
250
{
219
 
    struct zzip_file_header* file = 
220
 
        zzip_disk_entry_to_file_header(disk, entry);
221
 
    if (file) return zzip_file_header_to_data (file);
 
251
    struct zzip_file_header *file = zzip_disk_entry_to_file_header(disk, entry);
 
252
    if (file)
 
253
        return zzip_file_header_to_data(file);
222
254
    return 0;
223
255
}
224
256
 
226
258
 * This function does half the job of => zzip_disk_entry_to_data where it
227
259
 * can augment with => zzip_file_header_to_data helper from format/fetch.h
228
260
 */
229
 
struct zzip_file_header*
230
 
zzip_disk_entry_to_file_header(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
 
261
struct zzip_file_header *
 
262
zzip_disk_entry_to_file_header(ZZIP_DISK * disk, struct zzip_disk_entry *entry)
231
263
{
232
 
    zzip_byte_t* file_header = /* (struct zzip_file_header*) */
233
 
        (disk->buffer + zzip_disk_entry_fileoffset (entry));
234
 
    if (disk->buffer > file_header || file_header >= disk->endbuf) 
235
 
        return 0;
236
 
    return (struct zzip_file_header*) file_header;
 
264
    zzip_byte_t *file_header =  /* (struct zzip_file_header*) */
 
265
        (disk->buffer + zzip_disk_entry_fileoffset(entry));
 
266
    if (disk->buffer > file_header || file_header >= disk->endbuf)
 
267
        return 0;
 
268
    return (struct zzip_file_header *) file_header;
237
269
}
238
270
 
239
271
/** => zzip_disk_entry_to_data
243
275
 * in the zip central directory but if not then we fallback to the filename
244
276
 * given in the file_header of each compressed data portion.
245
277
 */
246
 
zzip__new__ char*
247
 
zzip_disk_entry_strdup_name(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
 
278
zzip__new__ char *
 
279
zzip_disk_entry_strdup_name(ZZIP_DISK * disk, struct zzip_disk_entry *entry)
248
280
{
249
 
    if (! disk || ! entry) return 0;
 
281
    if (! disk || ! entry)
 
282
        return 0;
250
283
 
251
 
    ___ char* name; zzip_size_t len;
252
 
    struct zzip_file_header* file;
253
 
    if ((len = zzip_disk_entry_namlen (entry)))
254
 
        name = zzip_disk_entry_to_filename (entry);
255
 
    else if ((file = zzip_disk_entry_to_file_header (disk, entry)) &&
256
 
             (len = zzip_file_header_namlen (file)))
257
 
        name = zzip_file_header_to_filename (file);
 
284
    ___ char *name;
 
285
    zzip_size_t len;
 
286
    struct zzip_file_header *file;
 
287
    if ((len = zzip_disk_entry_namlen(entry)))
 
288
        name = zzip_disk_entry_to_filename(entry);
 
289
    else if ((file = zzip_disk_entry_to_file_header(disk, entry)) &&
 
290
             (len = zzip_file_header_namlen(file)))
 
291
        name = zzip_file_header_to_filename(file);
258
292
    else
259
 
        return 0;
260
 
 
261
 
    if ((zzip_byte_t*) name < disk->buffer || 
262
 
        (zzip_byte_t*) name+len > disk->endbuf)
263
 
        return 0;
264
 
    
265
 
    return  _zzip_strndup (name, len); ____;
 
293
        return 0;
 
294
 
 
295
    if ((zzip_byte_t *) name < disk->buffer ||
 
296
        (zzip_byte_t *) name + len > disk->endbuf)
 
297
        return 0;
 
298
 
 
299
    return _zzip_strndup(name, len);
 
300
    ____;
266
301
}
267
302
 
268
303
/** => zzip_disk_entry_to_data
269
304
 * This function is similar creating a reference to a zero terminated
270
305
 * string but it can only exist in the zip central directory entry.
271
306
 */
272
 
zzip__new__ char*
273
 
zzip_disk_entry_strdup_comment(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
 
307
zzip__new__ char *
 
308
zzip_disk_entry_strdup_comment(ZZIP_DISK * disk, struct zzip_disk_entry *entry)
274
309
{
275
 
    if (! disk || ! entry) return 0;
 
310
    if (! disk || ! entry)
 
311
        return 0;
276
312
 
277
 
    ___ char* text; zzip_size_t len;
278
 
    if ((len = zzip_disk_entry_comment (entry)))
279
 
        text = zzip_disk_entry_to_comment (entry);
 
313
    ___ char *text;
 
314
    zzip_size_t len;
 
315
    if ((len = zzip_disk_entry_comment(entry)))
 
316
        text = zzip_disk_entry_to_comment(entry);
280
317
    else
281
 
        return 0;
282
 
 
283
 
    if ((zzip_byte_t*) text < disk->buffer || 
284
 
        (zzip_byte_t*) text+len > disk->endbuf)
285
 
        return 0;
286
 
    
287
 
    return  _zzip_strndup (text, len); ____;
 
318
        return 0;
 
319
 
 
320
    if ((zzip_byte_t *) text < disk->buffer ||
 
321
        (zzip_byte_t *) text + len > disk->endbuf)
 
322
        return 0;
 
323
 
 
324
    return _zzip_strndup(text, len);
 
325
    ____;
288
326
}
289
327
 
290
328
/* ====================================================================== */
316
354
 * catch a common brokeness with zip archives that still allows us to find
317
355
 * the start of the zip central directory.
318
356
 */
319
 
struct zzip_disk_entry*
320
 
zzip_disk_findfirst(ZZIP_DISK* disk)
 
357
struct zzip_disk_entry *
 
358
zzip_disk_findfirst(ZZIP_DISK * disk)
321
359
{
322
 
    if (disk->buffer > disk->endbuf-sizeof(struct zzip_disk_trailer))
323
 
        return 0;
324
 
    ___ zzip_byte_t* p = disk->endbuf-sizeof(struct zzip_disk_trailer);
325
 
    for (; p >= disk->buffer ; p--)
 
360
    if (disk->buffer > disk->endbuf - sizeof(struct zzip_disk_trailer))
 
361
        return 0;
 
362
    ___ zzip_byte_t *p = disk->endbuf - sizeof(struct zzip_disk_trailer);
 
363
    for (; p >= disk->buffer; p--)
326
364
    {
327
 
        zzip_byte_t* root; /* (struct zzip_disk_entry*) */
328
 
        if (zzip_disk_trailer_check_magic(p)) {
329
 
            root =  disk->buffer + zzip_disk_trailer_get_rootseek (
330
 
                (struct zzip_disk_trailer*)p);
331
 
            if (root > p) 
332
 
            {   /* the first disk_entry is after the disk_trailer? can't be! */
333
 
                zzip_size_t rootsize = zzip_disk_trailer_get_rootsize (
334
 
                    (struct zzip_disk_trailer*)p);
335
 
                if (disk->buffer+rootsize > p) continue;
336
 
                /* a common brokeness that can be fixed: we just assume the
337
 
                 * central directory was written directly before the trailer:*/
338
 
                root = p - rootsize;
339
 
            }
340
 
        } else if (zzip_disk64_trailer_check_magic(p)) {
341
 
            if (sizeof(void*) < 8) return 0; /* EOVERFLOW */
342
 
            root =  disk->buffer + zzip_disk64_trailer_get_rootseek (
343
 
                (struct zzip_disk64_trailer*)p);
344
 
            if (root > p) continue; 
345
 
        } else continue;
 
365
        zzip_byte_t *root;      /* (struct zzip_disk_entry*) */
 
366
        if (zzip_disk_trailer_check_magic(p))
 
367
        {
 
368
            struct zzip_disk_trailer *trailer = (struct zzip_disk_trailer *) p;
 
369
            root = disk->buffer + zzip_disk_trailer_get_rootseek(trailer);
 
370
            if (root > p)
 
371
            {
 
372
                /* the first disk_entry is after the disk_trailer? can't be! */
 
373
                zzip_size_t rootsize = zzip_disk_trailer_get_rootsize(trailer);
 
374
                if (disk->buffer + rootsize > p)
 
375
                    continue;
 
376
                /* a common brokeness that can be fixed: we just assume the
 
377
                 * central directory was written directly before the trailer:*/
 
378
                root = p - rootsize;
 
379
            }
 
380
        } else if (zzip_disk64_trailer_check_magic(p))
 
381
        {
 
382
            struct zzip_disk64_trailer *trailer =
 
383
                (struct zzip_disk64_trailer *) p;
 
384
            if (sizeof(void *) < 8)
 
385
                return 0;       /* EOVERFLOW */
 
386
            root = disk->buffer + zzip_disk64_trailer_get_rootseek(trailer);
 
387
            if (root > p)
 
388
                continue;
 
389
        } else
 
390
        {
 
391
            continue;
 
392
        }
346
393
 
347
 
        if (root < disk->buffer) continue;
348
 
        if (zzip_disk_entry_check_magic(root)) 
349
 
            return (struct zzip_disk_entry*) root;
350
 
    }____;
 
394
        if (root < disk->buffer)
 
395
            continue;
 
396
        if (zzip_disk_entry_check_magic(root))
 
397
            return (struct zzip_disk_entry *) root;
 
398
    } ____;
351
399
    return 0;
352
400
}
353
401
 
357
405
 * (e.g. from zzip_disk_findfirst) and returns the next entry within in
358
406
 * the given bounds of the mmapped file area.
359
407
 */
360
 
struct zzip_disk_entry*
361
 
zzip_disk_findnext(ZZIP_DISK* disk, struct zzip_disk_entry* entry)
 
408
struct zzip_disk_entry *
 
409
zzip_disk_findnext(ZZIP_DISK * disk, struct zzip_disk_entry *entry)
362
410
{
363
 
    if ((zzip_byte_t*)entry < disk->buffer || 
364
 
        (zzip_byte_t*)entry > disk->endbuf-sizeof(entry) ||
365
 
        ! zzip_disk_entry_check_magic (entry) ||
366
 
        zzip_disk_entry_sizeto_end (entry) > 64*1024)
367
 
        return 0;
368
 
    entry = zzip_disk_entry_to_next_entry (entry);
369
 
    if ((zzip_byte_t*)entry > disk->endbuf-sizeof(entry) ||
370
 
        ! zzip_disk_entry_check_magic (entry) ||
371
 
        zzip_disk_entry_sizeto_end (entry) > 64*1024 ||
372
 
        zzip_disk_entry_skipto_end (entry) + sizeof(entry) > disk->endbuf)
373
 
        return 0;
 
411
    if ((zzip_byte_t *) entry < disk->buffer ||
 
412
        (zzip_byte_t *) entry > disk->endbuf - sizeof(entry) ||
 
413
        ! zzip_disk_entry_check_magic(entry) ||
 
414
        zzip_disk_entry_sizeto_end(entry) > 64 * 1024)
 
415
        return 0;
 
416
    entry = zzip_disk_entry_to_next_entry(entry);
 
417
    if ((zzip_byte_t *) entry > disk->endbuf - sizeof(entry) ||
 
418
        ! zzip_disk_entry_check_magic(entry) ||
 
419
        zzip_disk_entry_sizeto_end(entry) > 64 * 1024 ||
 
420
        zzip_disk_entry_skipto_end(entry) + sizeof(entry) > disk->endbuf)
 
421
        return 0;
374
422
    else
375
 
        return entry;
 
423
        return entry;
376
424
}
377
425
 
378
426
/** search for files in the (mmapped) zip central directory
385
433
 * entries with a special "compare" function (if null then a doubled search
386
434
 * is rather useless with this variant of _findfile).
387
435
 */
388
 
struct zzip_disk_entry*
389
 
zzip_disk_findfile(ZZIP_DISK* disk, char* filename, 
390
 
                    struct zzip_disk_entry* after, zzip_strcmp_fn_t compare)
 
436
struct zzip_disk_entry *
 
437
zzip_disk_findfile(ZZIP_DISK * disk, char *filename,
 
438
                   struct zzip_disk_entry *after, zzip_strcmp_fn_t compare)
391
439
{
392
 
    struct zzip_disk_entry* entry = (! after ? zzip_disk_findfirst (disk) 
393
 
                                     : zzip_disk_findnext (disk, after));
394
 
    if (! compare) 
395
 
        compare = (zzip_strcmp_fn_t)( (disk->flags&1) ? 
396
 
                                      (_zzip_strcasecmp) : (strcmp));
397
 
    for (; entry ; entry = zzip_disk_findnext (disk, entry))
 
440
    struct zzip_disk_entry *entry = (! after ? zzip_disk_findfirst(disk)
 
441
                                     : zzip_disk_findnext(disk, after));
 
442
    if (! compare)
 
443
        compare = (zzip_strcmp_fn_t) ((disk->flags & 1) ?
 
444
                                      (_zzip_strcasecmp) : (strcmp));
 
445
    for (; entry; entry = zzip_disk_findnext(disk, entry))
398
446
    {
399
 
        /* filenames within zip files are often not null-terminated! */
400
 
        char* realname = zzip_disk_entry_strdup_name (disk, entry);
401
 
        if (realname && ! compare(filename, realname))
402
 
        {
403
 
            free (realname);
404
 
            return entry;
405
 
        }
406
 
        free (realname);
 
447
        /* filenames within zip files are often not null-terminated! */
 
448
        char *realname = zzip_disk_entry_strdup_name(disk, entry);
 
449
        if (realname && ! compare(filename, realname))
 
450
        {
 
451
            free(realname);
 
452
            return entry;
 
453
        }
 
454
        free(realname);
407
455
    }
408
456
    return 0;
409
457
}
421
469
 * matching entry, or the last disk_entry return-value to find the
422
470
 * next entry matching the given filespec.
423
471
 */
424
 
struct zzip_disk_entry*
425
 
zzip_disk_findmatch(ZZIP_DISK* disk, char* filespec, 
426
 
                    struct zzip_disk_entry* after,
427
 
                    zzip_fnmatch_fn_t compare, int flags)
 
472
struct zzip_disk_entry *
 
473
zzip_disk_findmatch(ZZIP_DISK * disk, char *filespec,
 
474
                    struct zzip_disk_entry *after,
 
475
                    zzip_fnmatch_fn_t compare, int flags)
428
476
{
429
 
    struct zzip_disk_entry* entry = (! after ? zzip_disk_findfirst (disk) 
430
 
                                     : zzip_disk_findnext (disk, after));
431
 
    if (! compare) { 
432
 
        compare = (zzip_fnmatch_fn_t) _zzip_fnmatch; 
433
 
        if (disk->flags&1) disk->flags |= _zzip_fnmatch_CASEFOLD;
 
477
    struct zzip_disk_entry *entry = (! after ? zzip_disk_findfirst(disk)
 
478
                                     : zzip_disk_findnext(disk, after));
 
479
    if (! compare)
 
480
    {
 
481
        compare = (zzip_fnmatch_fn_t) _zzip_fnmatch;
 
482
        if (disk->flags & 1)
 
483
            disk->flags |= _zzip_fnmatch_CASEFOLD;
434
484
    }
435
 
    for (; entry ; entry = zzip_disk_findnext (disk, entry))
 
485
    for (; entry; entry = zzip_disk_findnext(disk, entry))
436
486
    {
437
 
        /* filenames within zip files are often not null-terminated! */
438
 
        char* realname = zzip_disk_entry_strdup_name(disk, entry);
439
 
        if (realname && ! compare(filespec, realname, flags))
440
 
        {
441
 
            free (realname);
442
 
            return entry;
443
 
        }
444
 
        free (realname);
 
487
        /* filenames within zip files are often not null-terminated! */
 
488
        char *realname = zzip_disk_entry_strdup_name(disk, entry);
 
489
        if (realname && ! compare(filespec, realname, flags))
 
490
        {
 
491
            free(realname);
 
492
            return entry;
 
493
        }
 
494
        free(realname);
445
495
    }
446
496
    return 0;
447
497
}
459
509
 * _read() operations will be able to get the next data portion or
460
510
 * return an eof condition for that file part wrapped in the zip archive.
461
511
 */
462
 
zzip__new__ ZZIP_DISK_FILE*
463
 
zzip_disk_entry_fopen (ZZIP_DISK* disk, ZZIP_DISK_ENTRY* entry)
 
512
zzip__new__ ZZIP_DISK_FILE *
 
513
zzip_disk_entry_fopen(ZZIP_DISK * disk, ZZIP_DISK_ENTRY * entry)
464
514
{
465
515
    /* keep this in sync with zzip_mem_entry_fopen */
466
 
    struct zzip_file_header* header = 
467
 
        zzip_disk_entry_to_file_header (disk, entry);
468
 
    if (! header) return 0;
469
 
    ___ ZZIP_DISK_FILE* file = malloc(sizeof(ZZIP_DISK_FILE));
470
 
    if (! file) return file;
 
516
    struct zzip_file_header *header =
 
517
        zzip_disk_entry_to_file_header(disk, entry);
 
518
    if (! header)
 
519
        return 0;
 
520
    ___ ZZIP_DISK_FILE *file = malloc(sizeof(ZZIP_DISK_FILE));
 
521
    if (! file)
 
522
        return file;
471
523
    file->buffer = disk->buffer;
472
524
    file->endbuf = disk->endbuf;
473
 
    file->avail = zzip_file_header_usize (header);
 
525
    file->avail = zzip_file_header_usize(header);
474
526
 
475
 
    if (! file->avail || zzip_file_header_data_stored (header))
476
 
    { file->stored = zzip_file_header_to_data (header); return file; }
 
527
    if (! file->avail || zzip_file_header_data_stored(header))
 
528
        { file->stored = zzip_file_header_to_data (header); return file; }
477
529
 
478
530
    file->stored = 0;
479
531
    file->zlib.opaque = 0;
480
532
    file->zlib.zalloc = Z_NULL;
481
533
    file->zlib.zfree = Z_NULL;
482
 
    file->zlib.avail_in = zzip_file_header_csize (header);
483
 
    file->zlib.next_in = zzip_file_header_to_data (header);
484
 
 
485
 
    if (! zzip_file_header_data_deflated (header) ||
486
 
        inflateInit2 (& file->zlib, -MAX_WBITS) != Z_OK)
487
 
    { free (file); return 0; }
488
 
 
489
 
    return file; ____;
 
534
    file->zlib.avail_in = zzip_file_header_csize(header);
 
535
    file->zlib.next_in = zzip_file_header_to_data(header);
 
536
 
 
537
    if (! zzip_file_header_data_deflated(header) ||
 
538
        inflateInit2(&file->zlib, -MAX_WBITS) != Z_OK)
 
539
        { free (file); return 0; }
 
540
 
 
541
    return file;
 
542
    ____;
490
543
}
491
544
 
492
545
/** openening a file part wrapped within a (mmapped) zip archive
495
548
 * the zip central directory with => zzip_disk_findfile and whatever
496
549
 * is found first is given to => zzip_disk_entry_fopen
497
550
 */
498
 
zzip__new__ ZZIP_DISK_FILE*
499
 
zzip_disk_fopen (ZZIP_DISK* disk, char* filename)
 
551
zzip__new__ ZZIP_DISK_FILE *
 
552
zzip_disk_fopen(ZZIP_DISK * disk, char *filename)
500
553
{
501
 
    ZZIP_DISK_ENTRY* entry = zzip_disk_findfile (disk, filename, 0, 0);
502
 
    if (! entry) return 0; else return zzip_disk_entry_fopen (disk, entry);
 
554
    ZZIP_DISK_ENTRY *entry = zzip_disk_findfile(disk, filename, 0, 0);
 
555
    if (! entry)
 
556
        return 0;
 
557
    else
 
558
        return zzip_disk_entry_fopen(disk, entry);
503
559
}
504
560
 
505
561
 
511
567
 * with => zzip_disk_feof for the difference.
512
568
 */
513
569
zzip_size_t
514
 
zzip_disk_fread (void* ptr, zzip_size_t sized, zzip_size_t nmemb,
515
 
                 ZZIP_DISK_FILE* file)
 
570
zzip_disk_fread(void *ptr, zzip_size_t sized, zzip_size_t nmemb,
 
571
                ZZIP_DISK_FILE * file)
516
572
{
517
 
    zzip_size_t size = sized*nmemb;
518
 
    if (size > file->avail) size = file->avail;
 
573
    zzip_size_t size = sized * nmemb;
 
574
    if (size > file->avail)
 
575
        size = file->avail;
519
576
    if (file->stored)
520
577
    {
521
 
        memcpy (ptr, file->stored, size);
522
 
        file->stored += size;
523
 
        file->avail -= size;
524
 
        return size;
 
578
        memcpy(ptr, file->stored, size);
 
579
        file->stored += size;
 
580
        file->avail -= size;
 
581
        return size;
525
582
    }
526
 
    
527
 
    file->zlib.avail_out = sized*nmemb;
 
583
 
 
584
    file->zlib.avail_out = sized * nmemb;
528
585
    file->zlib.next_out = ptr;
529
586
    ___ zzip_size_t total_old = file->zlib.total_out;
530
 
    ___ int err = inflate (& file->zlib, Z_NO_FLUSH);
 
587
    ___ int err = inflate(&file->zlib, Z_NO_FLUSH);
531
588
    if (err == Z_STREAM_END)
532
 
        file->avail = 0;
 
589
        file->avail = 0;
533
590
    else if (err == Z_OK)
534
 
        file->avail -= file->zlib.total_out - total_old;
 
591
        file->avail -= file->zlib.total_out - total_old;
535
592
    else
536
 
        return 0;
 
593
        return 0;
537
594
    return file->zlib.total_out - total_old;
538
 
    ____;____;
 
595
    ____;
 
596
    ____;
539
597
}
540
598
 
541
599
/** => zzip_disk_fopen
543
601
 * and dumps the ZZIP_DISK_FILE* then.
544
602
 */
545
603
int
546
 
zzip_disk_fclose (ZZIP_DISK_FILE* file)
 
604
zzip_disk_fclose(ZZIP_DISK_FILE * file)
547
605
{
548
606
    if (! file->stored)
549
 
        inflateEnd (& file->zlib);
550
 
    free (file);
 
607
        inflateEnd(&file->zlib);
 
608
    free(file);
551
609
    return 0;
552
610
}
553
611
 
556
614
 * This function allows to distinguish an error from an eof condition. 
557
615
 * Actually, if we found an error but we did already reach eof then we
558
616
 * just keep on saying that it was an eof, so the app can just continue.
559
 
 */ 
 
617
 */
560
618
int
561
 
zzip_disk_feof (ZZIP_DISK_FILE* file)
 
619
zzip_disk_feof(ZZIP_DISK_FILE * file)
562
620
{
563
621
    return ! file || ! file->avail;
564
622
}