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

1.1       misho       1: /*
                      2:   zip_source_zip.c -- create data source from zip file
                      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 <stdlib.h>
                     37: #include <string.h>
                     38: 
                     39: #include "zipint.h"
                     40: 
                     41: struct read_zip {
                     42:     struct zip_file *zf;
                     43:     struct zip_stat st;
                     44:     off_t off, len;
                     45: };
                     46: 
                     47: static ssize_t read_zip(void *st, void *data, size_t len,
                     48:                        enum zip_source_cmd cmd);
                     49: 
                     50: 
                     51: 
                     52: ZIP_EXTERN(struct zip_source *)
                     53: zip_source_zip(struct zip *za, struct zip *srcza, int srcidx, int flags,
                     54:               off_t start, off_t len)
                     55: {
                     56:     struct zip_error error;
                     57:     struct zip_source *zs;
                     58:     struct read_zip *p;
                     59: 
                     60:     /* XXX: ZIP_FL_RECOMPRESS */
                     61: 
                     62:     if (za == NULL)
                     63:        return NULL;
                     64: 
                     65:     if (srcza == NULL || start < 0 || len < -1 || srcidx < 0 || srcidx >= srcza->nentry) {
                     66:        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
                     67:        return NULL;
                     68:     }
                     69: 
                     70:     if ((flags & ZIP_FL_UNCHANGED) == 0
                     71:        && ZIP_ENTRY_DATA_CHANGED(srcza->entry+srcidx)) {
                     72:        _zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
                     73:        return NULL;
                     74:     }
                     75: 
                     76:     if (len == 0)
                     77:        len = -1;
                     78: 
                     79:     if (start == 0 && len == -1 && (flags & ZIP_FL_RECOMPRESS) == 0)
                     80:        flags |= ZIP_FL_COMPRESSED;
                     81:     else
                     82:        flags &= ~ZIP_FL_COMPRESSED;
                     83: 
                     84:     if ((p=(struct read_zip *)malloc(sizeof(*p))) == NULL) {
                     85:        _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                     86:        return NULL;
                     87:     }
                     88:        
                     89:     _zip_error_copy(&error, &srcza->error);
                     90:        
                     91:     if (zip_stat_index(srcza, srcidx, flags, &p->st) < 0
                     92:        || (p->zf=zip_fopen_index(srcza, srcidx, flags)) == NULL) {
                     93:        free(p);
                     94:        _zip_error_copy(&za->error, &srcza->error);
                     95:        _zip_error_copy(&srcza->error, &error);
                     96:        
                     97:        return NULL;
                     98:     }
                     99:     p->off = start;
                    100:     p->len = len;
                    101: 
                    102:     if ((flags & ZIP_FL_COMPRESSED) == 0) {
                    103:        p->st.size = p->st.comp_size = len;
                    104:        p->st.comp_method = ZIP_CM_STORE;
                    105:        p->st.crc = 0;
                    106:     }
                    107:     
                    108:     if ((zs=zip_source_function(za, read_zip, p)) == NULL) {
                    109:        free(p);
                    110:        return NULL;
                    111:     }
                    112: 
                    113:     return zs;
                    114: }
                    115: 
                    116: 
                    117: 
                    118: static ssize_t
                    119: read_zip(void *state, void *data, size_t len, enum zip_source_cmd cmd)
                    120: {
                    121:     struct read_zip *z;
                    122:     char b[8192], *buf;
                    123:     int i, n;
                    124: 
                    125:     z = (struct read_zip *)state;
                    126:     buf = (char *)data;
                    127: 
                    128:     switch (cmd) {
                    129:     case ZIP_SOURCE_OPEN:
                    130:        for (n=0; n<z->off; n+= i) {
                    131:            i = (z->off-n > sizeof(b) ? sizeof(b) : z->off-n);
                    132:            if ((i=zip_fread(z->zf, b, i)) < 0) {
                    133:                zip_fclose(z->zf);
                    134:                z->zf = NULL;
                    135:                return -1;
                    136:            }
                    137:        }
                    138:        return 0;
                    139:        
                    140:     case ZIP_SOURCE_READ:
                    141:        if (z->len != -1)
                    142:            n = len > z->len ? z->len : len;
                    143:        else
                    144:            n = len;
                    145:        
                    146: 
                    147:        if ((i=zip_fread(z->zf, buf, n)) < 0)
                    148:            return -1;
                    149: 
                    150:        if (z->len != -1)
                    151:            z->len -= i;
                    152: 
                    153:        return i;
                    154:        
                    155:     case ZIP_SOURCE_CLOSE:
                    156:        return 0;
                    157: 
                    158:     case ZIP_SOURCE_STAT:
                    159:        if (len < sizeof(z->st))
                    160:            return -1;
                    161:        len = sizeof(z->st);
                    162: 
                    163:        memcpy(data, &z->st, len);
                    164:        return len;
                    165: 
                    166:     case ZIP_SOURCE_ERROR:
                    167:        {
                    168:            int *e;
                    169: 
                    170:            if (len < sizeof(int)*2)
                    171:                return -1;
                    172: 
                    173:            e = (int *)data;
                    174:            zip_file_error_get(z->zf, e, e+1);
                    175:        }
                    176:        return sizeof(int)*2;
                    177: 
                    178:     case ZIP_SOURCE_FREE:
                    179:        zip_fclose(z->zf);
                    180:        free(z);
                    181:        return 0;
                    182: 
                    183:     default:
                    184:        ;
                    185:     }
                    186: 
                    187:     return -1;
                    188: }

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