Annotation of embedaddon/php/ext/zip/lib/zip_fopen_index.c, revision 1.1.1.1

1.1       misho       1: /*
                      2:   zip_fopen_index.c -- open file in zip archive for reading by index
                      3:   Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner
                      4: 
                      5:   This file is part of libzip, a library to manipulate ZIP archives.
                      6:   The authors can be contacted at <libzip@nih.at>
                      7: 
                      8:   Redistribution and use in source and binary forms, with or without
                      9:   modification, are permitted provided that the following conditions
                     10:   are met:
                     11:   1. Redistributions of source code must retain the above copyright
                     12:      notice, this list of conditions and the following disclaimer.
                     13:   2. Redistributions in binary form must reproduce the above copyright
                     14:      notice, this list of conditions and the following disclaimer in
                     15:      the documentation and/or other materials provided with the
                     16:      distribution.
                     17:   3. The names of the authors may not be used to endorse or promote
                     18:      products derived from this software without specific prior
                     19:      written permission.
                     20:  
                     21:   THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
                     22:   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
                     23:   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     24:   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
                     25:   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     26:   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
                     27:   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     28:   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
                     29:   IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     30:   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
                     31:   IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     32: */
                     33: 
                     34: 
                     35: 
                     36: #include <errno.h>
                     37: #include <stdio.h>
                     38: #include <stdlib.h>
                     39: 
                     40: #include "zipint.h"
                     41: 
                     42: static struct zip_file *_zip_file_new(struct zip *za);
                     43: 
                     44: 
                     45: 
                     46: ZIP_EXTERN(struct zip_file *)
                     47: zip_fopen_index(struct zip *za, int fileno, int flags)
                     48: {
                     49:     int len, ret;
                     50:     int zfflags;
                     51:     struct zip_file *zf;
                     52: 
                     53:     if ((fileno < 0) || (fileno >= za->nentry)) {
                     54:        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
                     55:        return NULL;
                     56:     }
                     57: 
                     58:     if ((flags & ZIP_FL_UNCHANGED) == 0
                     59:        && ZIP_ENTRY_DATA_CHANGED(za->entry+fileno)) {
                     60:        _zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
                     61:        return NULL;
                     62:     }
                     63: 
                     64:     if (fileno >= za->cdir->nentry) {
                     65:        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
                     66:        return NULL;
                     67:     }
                     68: 
                     69:     zfflags = 0;
                     70:     switch (za->cdir->entry[fileno].comp_method) {
                     71:     case ZIP_CM_STORE:
                     72:        zfflags |= ZIP_ZF_CRC;
                     73:        break;
                     74: 
                     75:     case ZIP_CM_DEFLATE:
                     76:        if ((flags & ZIP_FL_COMPRESSED) == 0)
                     77:            zfflags |= ZIP_ZF_CRC | ZIP_ZF_DECOMP;
                     78:        break;
                     79:     default:
                     80:        if ((flags & ZIP_FL_COMPRESSED) == 0) {
                     81:            _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
                     82:            return NULL;
                     83:        }
                     84:        break;
                     85:     }
                     86: 
                     87:     zf = _zip_file_new(za);
                     88: 
                     89:     zf->flags = zfflags;
                     90:     /* zf->name = za->cdir->entry[fileno].filename; */
                     91:     zf->method = za->cdir->entry[fileno].comp_method;
                     92:     zf->bytes_left = za->cdir->entry[fileno].uncomp_size;
                     93:     zf->cbytes_left = za->cdir->entry[fileno].comp_size;
                     94:     zf->crc_orig = za->cdir->entry[fileno].crc;
                     95: 
                     96:     if ((zf->fpos=_zip_file_get_offset(za, fileno)) == 0) {
                     97:        zip_fclose(zf);
                     98:        return NULL;
                     99:     }
                    100:     
                    101:     if ((zf->flags & ZIP_ZF_DECOMP) == 0)
                    102:        zf->bytes_left = zf->cbytes_left;
                    103:     else {
                    104:        if ((zf->buffer=(char *)malloc(BUFSIZE)) == NULL) {
                    105:            _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                    106:            zip_fclose(zf);
                    107:            return NULL;
                    108:        }
                    109: 
                    110:        len = _zip_file_fillbuf(zf->buffer, BUFSIZE, zf);
                    111:        if (len <= 0) {
                    112:            _zip_error_copy(&za->error, &zf->error);
                    113:            zip_fclose(zf);
                    114:        return NULL;
                    115:        }
                    116: 
                    117:        if ((zf->zstr = (z_stream *)malloc(sizeof(z_stream))) == NULL) {
                    118:            _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                    119:            zip_fclose(zf);
                    120:            return NULL;
                    121:        }
                    122:        zf->zstr->zalloc = Z_NULL;
                    123:        zf->zstr->zfree = Z_NULL;
                    124:        zf->zstr->opaque = NULL;
                    125:        zf->zstr->next_in = (Bytef *)zf->buffer;
                    126:        zf->zstr->avail_in = len;
                    127:        
                    128:        /* negative value to tell zlib that there is no header */
                    129:        if ((ret=inflateInit2(zf->zstr, -MAX_WBITS)) != Z_OK) {
                    130:            _zip_error_set(&za->error, ZIP_ER_ZLIB, ret);
                    131:            zip_fclose(zf);
                    132:            return NULL;
                    133:        }
                    134:     }
                    135:     
                    136:     return zf;
                    137: }
                    138: 
                    139: 
                    140: 
                    141: int
                    142: _zip_file_fillbuf(void *buf, size_t buflen, struct zip_file *zf)
                    143: {
                    144:     int i, j;
                    145: 
                    146:     if (zf->error.zip_err != ZIP_ER_OK)
                    147:        return -1;
                    148: 
                    149:     if ((zf->flags & ZIP_ZF_EOF) || zf->cbytes_left <= 0 || buflen <= 0)
                    150:        return 0;
                    151:     
                    152:     if (fseeko(zf->za->zp, zf->fpos, SEEK_SET) < 0) {
                    153:        _zip_error_set(&zf->error, ZIP_ER_SEEK, errno);
                    154:        return -1;
                    155:     }
                    156:     if (buflen < zf->cbytes_left)
                    157:        i = buflen;
                    158:     else
                    159:        i = zf->cbytes_left;
                    160: 
                    161:     j = fread(buf, 1, i, zf->za->zp);
                    162:     if (j == 0) {
                    163:        _zip_error_set(&zf->error, ZIP_ER_EOF, 0);
                    164:        j = -1;
                    165:     }
                    166:     else if (j < 0)
                    167:        _zip_error_set(&zf->error, ZIP_ER_READ, errno);
                    168:     else {
                    169:        zf->fpos += j;
                    170:        zf->cbytes_left -= j;
                    171:     }
                    172: 
                    173:     return j;  
                    174: }
                    175: 
                    176: 
                    177: 
                    178: static struct zip_file *
                    179: _zip_file_new(struct zip *za)
                    180: {
                    181:     struct zip_file *zf, **file;
                    182:     int n;
                    183: 
                    184:     if ((zf=(struct zip_file *)malloc(sizeof(struct zip_file))) == NULL) {
                    185:        _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                    186:        return NULL;
                    187:     }
                    188:     
                    189:     if (za->nfile >= za->nfile_alloc-1) {
                    190:        n = za->nfile_alloc + 10;
                    191:        file = (struct zip_file **)realloc(za->file,
                    192:                                           n*sizeof(struct zip_file *));
                    193:        if (file == NULL) {
                    194:            _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                    195:            free(zf);
                    196:            return NULL;
                    197:        }
                    198:        za->nfile_alloc = n;
                    199:        za->file = file;
                    200:     }
                    201: 
                    202:     za->file[za->nfile++] = zf;
                    203: 
                    204:     zf->za = za;
                    205:     _zip_error_init(&zf->error);
                    206:     zf->flags = 0;
                    207:     zf->crc = crc32(0L, Z_NULL, 0);
                    208:     zf->crc_orig = 0;
                    209:     zf->method = -1;
                    210:     zf->bytes_left = zf->cbytes_left = 0;
                    211:     zf->fpos = 0;
                    212:     zf->buffer = NULL;
                    213:     zf->zstr = NULL;
                    214: 
                    215:     return zf;
                    216: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>