blob: b277635c7fadc1c096843bbb77da1317c566ca61 [file] [log] [blame]
Dieter Baronbbb63691999-07-26 22:04:20 +00001/*
Dieter Baron1f3803c2005-06-09 19:57:10 +00002 $NiH: zip_source_buffer.c,v 1.4 2005/05/20 21:54:12 wiz Exp $
Dieter Baron1c5ffe22002-06-06 09:27:17 +00003
Thomas Klausnerfa02d9d2004-11-18 17:26:55 +00004 zip_source_buffer.c -- create zip data source from buffer
Dieter Baron1f3803c2005-06-09 19:57:10 +00005 Copyright (C) 1999, 2003, 2004, 2005 Dieter Baron and Thomas Klausner
Dieter Baronbbb63691999-07-26 22:04:20 +00006
Dieter Barondd9afca2003-10-02 14:13:37 +00007 This file is part of libzip, a library to manipulate ZIP archives.
Dieter Baronbbb63691999-07-26 22:04:20 +00008 The authors can be contacted at <nih@giga.or.at>
9
Dieter Barondd9afca2003-10-02 14:13:37 +000010 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 Baronbbb63691999-07-26 22:04:20 +000034*/
35
36
37
Dieter Baron194b9601999-07-25 22:40:10 +000038#include <stdlib.h>
Thomas Klausnerf817acf2003-01-30 03:46:01 +000039#include <string.h>
Dieter Baron194b9601999-07-25 22:40:10 +000040
41#include "zip.h"
42#include "zipint.h"
43
44struct read_data {
Dieter Baron0e339b62004-06-24 15:01:59 +000045 const char *buf, *data, *end;
46 time_t mtime;
Dieter Baron194b9601999-07-25 22:40:10 +000047 int freep;
48};
49
Dieter Baronb2ed74d2004-04-14 14:01:31 +000050static ssize_t read_data(void *state, void *data, size_t len,
Dieter Baron35bf0fd2004-12-22 16:32:01 +000051 enum zip_source_cmd cmd);
Dieter Baron194b9601999-07-25 22:40:10 +000052
53
54
Thomas Klausnerf2dc4362004-11-18 15:06:24 +000055struct zip_source *
Thomas Klausnerfa02d9d2004-11-18 17:26:55 +000056zip_source_buffer(struct zip *za, const void *data, off_t len, int freep)
Dieter Baronb2ed74d2004-04-14 14:01:31 +000057{
58 struct read_data *f;
Thomas Klausnerf2dc4362004-11-18 15:06:24 +000059 struct zip_source *zs;
60
Thomas Klausner7b221722004-11-18 16:28:13 +000061 if (za == NULL)
62 return NULL;
63
Thomas Klausnerf2dc4362004-11-18 15:06:24 +000064 if (len < 0 || (data == NULL && len > 0)) {
65 _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
66 return NULL;
67 }
Dieter Baronb2ed74d2004-04-14 14:01:31 +000068
69 if ((f=malloc(sizeof(*f))) == NULL) {
Thomas Klausnerf2dc4362004-11-18 15:06:24 +000070 _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
71 return NULL;
Dieter Baron194b9601999-07-25 22:40:10 +000072 }
73
74 f->data = data;
Dieter Baron645c4d32005-05-19 18:17:44 +000075 f->end = ((const char *)data)+len;
Dieter Baron194b9601999-07-25 22:40:10 +000076 f->freep = freep;
Dieter Baron0e339b62004-06-24 15:01:59 +000077 f->mtime = time(NULL);
Dieter Baron194b9601999-07-25 22:40:10 +000078
Thomas Klausnerf2dc4362004-11-18 15:06:24 +000079 if ((zs=zip_source_function(za, read_data, f)) == NULL) {
80 free(f);
81 return NULL;
82 }
83
84 return zs;
Dieter Baron194b9601999-07-25 22:40:10 +000085}
86
87
88
Thomas Klausner781c2992005-05-20 21:54:12 +000089static ssize_t
Dieter Baron35bf0fd2004-12-22 16:32:01 +000090read_data(void *state, void *data, size_t len, enum zip_source_cmd cmd)
Dieter Baron194b9601999-07-25 22:40:10 +000091{
92 struct read_data *z;
93 char *buf;
94 int n;
95
Thomas Klausneraf93f081999-07-26 01:39:56 +000096 z = (struct read_data *)state;
Dieter Baron194b9601999-07-25 22:40:10 +000097 buf = (char *)data;
98
99 switch (cmd) {
Dieter Baron35bf0fd2004-12-22 16:32:01 +0000100 case ZIP_SOURCE_OPEN:
Dieter Baron194b9601999-07-25 22:40:10 +0000101 z->buf = z->data;
102 return 0;
103
Dieter Baron35bf0fd2004-12-22 16:32:01 +0000104 case ZIP_SOURCE_READ:
Dieter Baron0e339b62004-06-24 15:01:59 +0000105 n = z->end - z->buf;
106 if (n > len)
107 n = len;
Dieter Baron6d7d5321999-07-26 20:17:26 +0000108 if (n < 0)
109 n = 0;
Dieter Baron194b9601999-07-25 22:40:10 +0000110
Dieter Baron15c39e31999-07-26 20:13:52 +0000111 if (n) {
112 memcpy(buf, z->buf, n);
113 z->buf += n;
Dieter Baron15c39e31999-07-26 20:13:52 +0000114 }
Dieter Baron194b9601999-07-25 22:40:10 +0000115
116 return n;
117
Dieter Baron35bf0fd2004-12-22 16:32:01 +0000118 case ZIP_SOURCE_CLOSE:
Dieter Baron0e339b62004-06-24 15:01:59 +0000119 return 0;
120
Dieter Baron35bf0fd2004-12-22 16:32:01 +0000121 case ZIP_SOURCE_STAT:
Dieter Baron0e339b62004-06-24 15:01:59 +0000122 {
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 Baron35bf0fd2004-12-22 16:32:01 +0000139 case ZIP_SOURCE_ERROR:
Dieter Baron0e339b62004-06-24 15:01:59 +0000140 {
141 int *e;
142
143 if (len < sizeof(int)*2)
144 return -1;
145
Thomas Klausnerf2dc4362004-11-18 15:06:24 +0000146 e = (int *)data;
Dieter Baron0e339b62004-06-24 15:01:59 +0000147 e[0] = e[1] = 0;
148 }
149 return sizeof(int)*2;
150
Dieter Baron35bf0fd2004-12-22 16:32:01 +0000151 case ZIP_SOURCE_FREE:
Dieter Baron194b9601999-07-25 22:40:10 +0000152 if (z->freep) {
Dieter Baron9360da02003-10-01 09:51:01 +0000153 free((void *)z->data);
Dieter Baron194b9601999-07-25 22:40:10 +0000154 z->data = NULL;
155 }
Dieter Baronb2ed74d2004-04-14 14:01:31 +0000156 free(z);
Dieter Baron194b9601999-07-25 22:40:10 +0000157 return 0;
Dieter Baronb2ed74d2004-04-14 14:01:31 +0000158
159 default:
160 ;
Dieter Baron194b9601999-07-25 22:40:10 +0000161 }
Thomas Klausneraf93f081999-07-26 01:39:56 +0000162
163 return -1;
Dieter Baron194b9601999-07-25 22:40:10 +0000164}