2 * Copyright (c) 2009 Michihiro NAKAJIMA
3 * Copyright (c) 2003-2007 Tim Kientzle
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "archive_platform.h"
28 __FBSDID("$FreeBSD$");
30 #ifdef HAVE_SYS_TYPES_H
31 #include <sys/types.h>
41 #include "archive_private.h"
42 #include "archive_string.h"
44 #if ARCHIVE_VERSION_NUMBER < 3000000
45 /* These disappear in libarchive 3.0 */
48 archive_api_feature(void)
50 return (ARCHIVE_API_FEATURE);
55 archive_api_version(void)
57 return (ARCHIVE_API_VERSION);
60 /* Deprecated synonym for archive_version_number() */
62 archive_version_stamp(void)
64 return (archive_version_number());
67 /* Deprecated synonym for archive_version_string() */
71 return (archive_version_string());
76 archive_version_number(void)
78 return (ARCHIVE_VERSION_NUMBER);
82 archive_version_string(void)
84 return (ARCHIVE_VERSION_STRING);
88 archive_errno(struct archive *a)
90 return (a->archive_error_number);
94 archive_error_string(struct archive *a)
97 if (a->error != NULL && *a->error != '\0')
100 return ("(Empty error message)");
104 archive_file_count(struct archive *a)
106 return (a->file_count);
110 archive_format(struct archive *a)
112 return (a->archive_format);
116 archive_format_name(struct archive *a)
118 return (a->archive_format_name);
123 archive_compression(struct archive *a)
125 return (a->compression_code);
129 archive_compression_name(struct archive *a)
131 return (a->compression_name);
136 * Return a count of the number of compressed bytes processed.
139 archive_position_compressed(struct archive *a)
141 return (a->raw_position);
145 * Return a count of the number of uncompressed bytes processed.
148 archive_position_uncompressed(struct archive *a)
150 return (a->file_position);
154 archive_clear_error(struct archive *a)
156 archive_string_empty(&a->error_string);
161 archive_set_error(struct archive *a, int error_number, const char *fmt, ...)
165 a->archive_error_number = error_number;
172 archive_string_vsprintf(&(a->error_string), fmt, ap);
174 a->error = a->error_string.s;
178 archive_copy_error(struct archive *dest, struct archive *src)
180 dest->archive_error_number = src->archive_error_number;
182 archive_string_copy(&dest->error_string, &src->error_string);
183 dest->error = dest->error_string.s;
187 __archive_errx(int retvalue, const char *msg)
189 static const char *msg1 = "Fatal Internal Error in libarchive: ";
192 s = write(2, msg1, strlen(msg1));
193 (void)s; /* UNUSED */
194 s = write(2, msg, strlen(msg));
195 (void)s; /* UNUSED */
196 s = write(2, "\n", 1);
197 (void)s; /* UNUSED */
202 * Parse option strings
203 * Detail of option format.
204 * - The option can accept:
205 * "opt-name", "!opt-name", "opt-name=value".
207 * - The option entries are separated by comma.
208 * e.g "compression=9,opt=XXX,opt-b=ZZZ"
210 * - The name of option string consist of '-' and alphabet
211 * but character '-' cannot be used for the first character.
212 * (Regular expression is [a-z][-a-z]+)
214 * - For a specfic format/filter, using the format name with ':'.
215 * e.g "zip:compression=9"
216 * (This "compression=9" option entry is for "zip" format only)
218 * If another entries follow it, those are not for
219 * the specfic format/filter.
220 * e.g handle "zip:compression=9,opt=XXX,opt-b=ZZZ"
221 * "zip" format/filter handler will get "compression=9"
222 * all format/filter handler will get "opt=XXX"
223 * all format/filter handler will get "opt-b=ZZZ"
225 * - Whitespace and tab are bypassed.
229 __archive_parse_options(const char *p, const char *fn, int keysize, char *key,
230 int valsize, char *val)
237 /* Requested for initialization. */
239 /* Finding format/filter-name and option-name. */
241 /* Finding option-name only.
242 * (already detected format/filter-name) */
244 /* Getting option-value. */
250 kidx = vidx = negative = 0;
262 if ((*p >= 'a' && *p <= 'z') ||
263 (*p >= '0' && *p <= '9') || *p == '-') {
264 if (kidx == 0 && !(*p >= 'a' && *p <= 'z'))
265 /* Illegal sequence. */
267 if (kidx >= keysize -1)
268 /* Too many characters. */
271 } else if (*p == '!') {
273 /* Illegal sequence. */
277 } else if (*p == ',') {
279 /* Illegal sequence. */
283 /* We have got boolean option data. */
288 /* This option does not apply to the
289 * format which the fn variable
292 } else if (*p == ':') {
293 /* obuf data is format name */
295 /* We already found it. */
298 /* Illegal sequence. */
301 /* We cannot accept "!format-name:". */
304 if (strcmp(fn, key) != 0)
305 /* This option does not apply to the
306 * format which the fn variable
312 } else if (*p == '=') {
314 /* Illegal sequence. */
317 /* We cannot accept "!opt-name=value". */
321 } else if (*p == ' ') {
322 /* Pass the space character */
325 /* Illegal character. */
332 /* Illegal sequence. */
334 /* We have got option data. */
339 /* This option does not apply to the
340 * format which the fn variable
343 } else if (*p == ' ') {
344 /* Pass the space character */
347 if (vidx >= valsize -1)
348 /* Too many characters. */
362 /* We have got boolean option. */
364 /* This option apply to the format which the
365 * fn variable indicate. */
371 /* Illegal sequence. */
373 /* We have got option value. */
375 /* This option apply to the format which the fn
376 * variable indicate. */
379 case INIT:/* nothing */
383 /* End of Option string. */
389 /* Return a size which we've consumed for detecting option */
390 return ((int)(p - p_org));