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

1.1       misho       1: /*
                      2:   zip_source_filep.c -- create data source from FILE *
                      3:   Copyright (C) 1999-2009 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 <sys/stat.h>
                     37: #include <errno.h>
                     38: #include <stdio.h>
                     39: #include <stdlib.h>
                     40: #include <string.h>
                     41: 
                     42: #include "zipint.h"
                     43: 
                     44: struct read_file {
                     45:     char *fname;       /* name of file to copy from */
                     46:     FILE *f;           /* file to copy from */
                     47:     off_t off;         /* start offset of */
                     48:     off_t len;         /* lengt of data to copy */
                     49:     off_t remain;      /* bytes remaining to be copied */
                     50:     int e[2];          /* error codes */
                     51: };
                     52: 
                     53: static ssize_t read_file(void *state, void *data, size_t len,
                     54:                     enum zip_source_cmd cmd);
                     55: 
                     56: 
                     57: 
                     58: ZIP_EXTERN(struct zip_source *)
                     59: zip_source_filep(struct zip *za, FILE *file, off_t start, off_t len)
                     60: {
                     61:     if (za == NULL)
                     62:        return NULL;
                     63: 
                     64:     if (file == NULL || start < 0 || len < -1) {
                     65:        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
                     66:        return NULL;
                     67:     }
                     68: 
                     69:     return _zip_source_file_or_p(za, NULL, file, start, len);
                     70: }
                     71: 
                     72: 
                     73: 
                     74: struct zip_source *
                     75: _zip_source_file_or_p(struct zip *za, const char *fname, FILE *file,
                     76:                      off_t start, off_t len)
                     77: {
                     78:     struct read_file *f;
                     79:     struct zip_source *zs;
                     80: 
                     81:     if (file == NULL && fname == NULL) {
                     82:        _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
                     83:        return NULL;
                     84:     }
                     85: 
                     86:     if ((f=(struct read_file *)malloc(sizeof(struct read_file))) == NULL) {
                     87:        _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                     88:        return NULL;
                     89:     }
                     90: 
                     91:     f->fname = NULL;
                     92:     if (fname) {
                     93:        if ((f->fname=strdup(fname)) == NULL) {
                     94:            _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
                     95:            free(f);
                     96:            return NULL;
                     97:        }
                     98:     }
                     99:     f->f = file;
                    100:     f->off = start;
                    101:     f->len = (len ? len : -1);
                    102:     
                    103:     if ((zs=zip_source_function(za, read_file, f)) == NULL) {
                    104:        free(f);
                    105:        return NULL;
                    106:     }
                    107: 
                    108:     return zs;
                    109: }
                    110: 
                    111: 
                    112: 
                    113: static ssize_t
                    114: read_file(void *state, void *data, size_t len, enum zip_source_cmd cmd)
                    115: {
                    116:     struct read_file *z;
                    117:     char *buf;
                    118:     int i, n;
                    119: 
                    120:     z = (struct read_file *)state;
                    121:     buf = (char *)data;
                    122: 
                    123:     switch (cmd) {
                    124:     case ZIP_SOURCE_OPEN:
                    125:        if (z->fname) {
                    126:            if ((z->f=fopen(z->fname, "rb")) == NULL) {
                    127:                z->e[0] = ZIP_ER_OPEN;
                    128:                z->e[1] = errno;
                    129:                return -1;
                    130:            }
                    131:        }
                    132: 
                    133:        if (fseeko(z->f, z->off, SEEK_SET) < 0) {
                    134:            z->e[0] = ZIP_ER_SEEK;
                    135:            z->e[1] = errno;
                    136:            return -1;
                    137:        }
                    138:        z->remain = z->len;
                    139:        return 0;
                    140:        
                    141:     case ZIP_SOURCE_READ:
                    142:        if (z->remain != -1)
                    143:            n = len > z->remain ? z->remain : len;
                    144:        else
                    145:            n = len;
                    146:        
                    147:        if ((i=fread(buf, 1, n, z->f)) < 0) {
                    148:            z->e[0] = ZIP_ER_READ;
                    149:            z->e[1] = errno;
                    150:            return -1;
                    151:        }
                    152: 
                    153:        if (z->remain != -1)
                    154:            z->remain -= i;
                    155: 
                    156:        return i;
                    157:        
                    158:     case ZIP_SOURCE_CLOSE:
                    159:        if (z->fname) {
                    160:            fclose(z->f);
                    161:            z->f = NULL;
                    162:        }
                    163:        return 0;
                    164: 
                    165:     case ZIP_SOURCE_STAT:
                    166:         {
                    167:            struct zip_stat *st;
                    168:            struct stat fst;
                    169:            int err;
                    170:            
                    171:            if (len < sizeof(*st))
                    172:                return -1;
                    173: 
                    174:            if (z->f)
                    175:                err = fstat(fileno(z->f), &fst);
                    176:            else
                    177:                err = stat(z->fname, &fst);
                    178: 
                    179:            if (err != 0) {
                    180:                z->e[0] = ZIP_ER_READ; /* best match */
                    181:                z->e[1] = errno;
                    182:                return -1;
                    183:            }
                    184: 
                    185:            st = (struct zip_stat *)data;
                    186: 
                    187:            zip_stat_init(st);
                    188:            st->mtime = fst.st_mtime;
                    189:            if (z->len != -1)
                    190:                st->size = z->len;
                    191:            else if ((fst.st_mode&S_IFMT) == S_IFREG)
                    192:                st->size = fst.st_size;
                    193: 
                    194:            return sizeof(*st);
                    195:        }
                    196: 
                    197:     case ZIP_SOURCE_ERROR:
                    198:        if (len < sizeof(int)*2)
                    199:            return -1;
                    200: 
                    201:        memcpy(data, z->e, sizeof(int)*2);
                    202:        return sizeof(int)*2;
                    203: 
                    204:     case ZIP_SOURCE_FREE:
                    205:        free(z->fname);
                    206:        if (z->f)
                    207:        fclose(z->f);
                    208:        free(z);
                    209:        return 0;
                    210: 
                    211:     default:
                    212:        ;
                    213:     }
                    214: 
                    215:     return -1;
                    216: }

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