Dieter Baron | bbb6369 | 1999-07-26 22:04:20 +0000 | [diff] [blame] | 1 | /* |
Dieter Baron | 1f3803c | 2005-06-09 19:57:10 +0000 | [diff] [blame] | 2 | $NiH: zip_source_buffer.c,v 1.4 2005/05/20 21:54:12 wiz Exp $ |
Dieter Baron | 1c5ffe2 | 2002-06-06 09:27:17 +0000 | [diff] [blame] | 3 | |
Thomas Klausner | fa02d9d | 2004-11-18 17:26:55 +0000 | [diff] [blame] | 4 | zip_source_buffer.c -- create zip data source from buffer |
Dieter Baron | 1f3803c | 2005-06-09 19:57:10 +0000 | [diff] [blame] | 5 | Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner |
Dieter Baron | bbb6369 | 1999-07-26 22:04:20 +0000 | [diff] [blame] | 6 | |
Dieter Baron | dd9afca | 2003-10-02 14:13:37 +0000 | [diff] [blame] | 7 | This file is part of libzip, a library to manipulate ZIP archives. |
Dieter Baron | bbb6369 | 1999-07-26 22:04:20 +0000 | [diff] [blame] | 8 | The authors can be contacted at <nih@giga.or.at> |
| 9 | |
Dieter Baron | dd9afca | 2003-10-02 14:13:37 +0000 | [diff] [blame] | 10 | Redistribution and use in source and binary forms, with or without |
| 11 | modification, are permitted provided that the following conditions |
| 12 | are met: |
| 13 | 1. Redistributions of source code must retain the above copyright |
| 14 | notice, this list of conditions and the following disclaimer. |
| 15 | 2. Redistributions in binary form must reproduce the above copyright |
| 16 | notice, this list of conditions and the following disclaimer in |
| 17 | the documentation and/or other materials provided with the |
| 18 | distribution. |
| 19 | 3. The names of the authors may not be used to endorse or promote |
| 20 | products derived from this software without specific prior |
| 21 | written permission. |
| 22 | |
| 23 | THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS |
| 24 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 25 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 26 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY |
| 27 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 28 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE |
| 29 | GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 30 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER |
| 31 | IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
| 32 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN |
| 33 | IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
Dieter Baron | bbb6369 | 1999-07-26 22:04:20 +0000 | [diff] [blame] | 34 | */ |
| 35 | |
| 36 | |
| 37 | |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 38 | #include <stdlib.h> |
Thomas Klausner | f817acf | 2003-01-30 03:46:01 +0000 | [diff] [blame] | 39 | #include <string.h> |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 40 | |
| 41 | #include "zip.h" |
| 42 | #include "zipint.h" |
| 43 | |
| 44 | struct read_data { |
Dieter Baron | 0e339b6 | 2004-06-24 15:01:59 +0000 | [diff] [blame] | 45 | const char *buf, *data, *end; |
| 46 | time_t mtime; |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 47 | int freep; |
| 48 | }; |
| 49 | |
Dieter Baron | b2ed74d | 2004-04-14 14:01:31 +0000 | [diff] [blame] | 50 | static ssize_t read_data(void *state, void *data, size_t len, |
Dieter Baron | 35bf0fd | 2004-12-22 16:32:01 +0000 | [diff] [blame] | 51 | enum zip_source_cmd cmd); |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 52 | |
| 53 | |
| 54 | |
Thomas Klausner | f2dc436 | 2004-11-18 15:06:24 +0000 | [diff] [blame] | 55 | struct zip_source * |
Thomas Klausner | fa02d9d | 2004-11-18 17:26:55 +0000 | [diff] [blame] | 56 | zip_source_buffer(struct zip *za, const void *data, off_t len, int freep) |
Dieter Baron | b2ed74d | 2004-04-14 14:01:31 +0000 | [diff] [blame] | 57 | { |
| 58 | struct read_data *f; |
Thomas Klausner | f2dc436 | 2004-11-18 15:06:24 +0000 | [diff] [blame] | 59 | struct zip_source *zs; |
| 60 | |
Thomas Klausner | 7b22172 | 2004-11-18 16:28:13 +0000 | [diff] [blame] | 61 | if (za == NULL) |
| 62 | return NULL; |
| 63 | |
Thomas Klausner | f2dc436 | 2004-11-18 15:06:24 +0000 | [diff] [blame] | 64 | if (len < 0 || (data == NULL && len > 0)) { |
| 65 | _zip_error_set(&za->error, ZIP_ER_INVAL, 0); |
| 66 | return NULL; |
| 67 | } |
Dieter Baron | b2ed74d | 2004-04-14 14:01:31 +0000 | [diff] [blame] | 68 | |
| 69 | if ((f=malloc(sizeof(*f))) == NULL) { |
Thomas Klausner | f2dc436 | 2004-11-18 15:06:24 +0000 | [diff] [blame] | 70 | _zip_error_set(&za->error, ZIP_ER_MEMORY, 0); |
| 71 | return NULL; |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 72 | } |
| 73 | |
| 74 | f->data = data; |
Dieter Baron | 645c4d3 | 2005-05-19 18:17:44 +0000 | [diff] [blame] | 75 | f->end = ((const char *)data)+len; |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 76 | f->freep = freep; |
Dieter Baron | 0e339b6 | 2004-06-24 15:01:59 +0000 | [diff] [blame] | 77 | f->mtime = time(NULL); |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 78 | |
Thomas Klausner | f2dc436 | 2004-11-18 15:06:24 +0000 | [diff] [blame] | 79 | if ((zs=zip_source_function(za, read_data, f)) == NULL) { |
| 80 | free(f); |
| 81 | return NULL; |
| 82 | } |
| 83 | |
| 84 | return zs; |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 85 | } |
| 86 | |
| 87 | |
| 88 | |
Thomas Klausner | 781c299 | 2005-05-20 21:54:12 +0000 | [diff] [blame] | 89 | static ssize_t |
Dieter Baron | 35bf0fd | 2004-12-22 16:32:01 +0000 | [diff] [blame] | 90 | read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd) |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 91 | { |
| 92 | struct read_data *z; |
| 93 | char *buf; |
| 94 | int n; |
| 95 | |
Thomas Klausner | af93f08 | 1999-07-26 01:39:56 +0000 | [diff] [blame] | 96 | z = (struct read_data *)state; |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 97 | buf = (char *)data; |
| 98 | |
| 99 | switch (cmd) { |
Dieter Baron | 35bf0fd | 2004-12-22 16:32:01 +0000 | [diff] [blame] | 100 | case ZIP_SOURCE_OPEN: |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 101 | z->buf = z->data; |
| 102 | return 0; |
| 103 | |
Dieter Baron | 35bf0fd | 2004-12-22 16:32:01 +0000 | [diff] [blame] | 104 | case ZIP_SOURCE_READ: |
Dieter Baron | 0e339b6 | 2004-06-24 15:01:59 +0000 | [diff] [blame] | 105 | n = z->end - z->buf; |
| 106 | if (n > len) |
| 107 | n = len; |
Dieter Baron | 6d7d532 | 1999-07-26 20:17:26 +0000 | [diff] [blame] | 108 | if (n < 0) |
| 109 | n = 0; |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 110 | |
Dieter Baron | 15c39e3 | 1999-07-26 20:13:52 +0000 | [diff] [blame] | 111 | if (n) { |
| 112 | memcpy(buf, z->buf, n); |
| 113 | z->buf += n; |
Dieter Baron | 15c39e3 | 1999-07-26 20:13:52 +0000 | [diff] [blame] | 114 | } |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 115 | |
| 116 | return n; |
| 117 | |
Dieter Baron | 35bf0fd | 2004-12-22 16:32:01 +0000 | [diff] [blame] | 118 | case ZIP_SOURCE_CLOSE: |
Dieter Baron | 0e339b6 | 2004-06-24 15:01:59 +0000 | [diff] [blame] | 119 | return 0; |
| 120 | |
Dieter Baron | 35bf0fd | 2004-12-22 16:32:01 +0000 | [diff] [blame] | 121 | case ZIP_SOURCE_STAT: |
Dieter Baron | 0e339b6 | 2004-06-24 15:01:59 +0000 | [diff] [blame] | 122 | { |
| 123 | struct zip_stat *st; |
| 124 | |
| 125 | if (len < sizeof(*st)) |
| 126 | return -1; |
| 127 | |
| 128 | st = (struct zip_stat *)data; |
| 129 | |
| 130 | st->mtime = z->mtime; |
| 131 | st->crc = 0; |
| 132 | st->size = z->end - z->data; |
| 133 | st->comp_size = -1; |
| 134 | st->comp_method = ZIP_CM_STORE; |
| 135 | |
| 136 | return sizeof(*st); |
| 137 | } |
| 138 | |
Dieter Baron | 35bf0fd | 2004-12-22 16:32:01 +0000 | [diff] [blame] | 139 | case ZIP_SOURCE_ERROR: |
Dieter Baron | 0e339b6 | 2004-06-24 15:01:59 +0000 | [diff] [blame] | 140 | { |
| 141 | int *e; |
| 142 | |
| 143 | if (len < sizeof(int)*2) |
| 144 | return -1; |
| 145 | |
Thomas Klausner | f2dc436 | 2004-11-18 15:06:24 +0000 | [diff] [blame] | 146 | e = (int *)data; |
Dieter Baron | 0e339b6 | 2004-06-24 15:01:59 +0000 | [diff] [blame] | 147 | e[0] = e[1] = 0; |
| 148 | } |
| 149 | return sizeof(int)*2; |
| 150 | |
Dieter Baron | 35bf0fd | 2004-12-22 16:32:01 +0000 | [diff] [blame] | 151 | case ZIP_SOURCE_FREE: |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 152 | if (z->freep) { |
Dieter Baron | 9360da0 | 2003-10-01 09:51:01 +0000 | [diff] [blame] | 153 | free((void *)z->data); |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 154 | z->data = NULL; |
| 155 | } |
Dieter Baron | b2ed74d | 2004-04-14 14:01:31 +0000 | [diff] [blame] | 156 | free(z); |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 157 | return 0; |
Dieter Baron | b2ed74d | 2004-04-14 14:01:31 +0000 | [diff] [blame] | 158 | |
| 159 | default: |
| 160 | ; |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 161 | } |
Thomas Klausner | af93f08 | 1999-07-26 01:39:56 +0000 | [diff] [blame] | 162 | |
| 163 | return -1; |
Dieter Baron | 194b960 | 1999-07-25 22:40:10 +0000 | [diff] [blame] | 164 | } |