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);
158 a->archive_error_number = 0;
162 archive_set_error(struct archive *a, int error_number, const char *fmt, ...)
166 a->archive_error_number = error_number;
173 archive_string_vsprintf(&(a->error_string), fmt, ap);
175 a->error = a->error_string.s;
179 archive_copy_error(struct archive *dest, struct archive *src)
181 dest->archive_error_number = src->archive_error_number;
183 archive_string_copy(&dest->error_string, &src->error_string);
184 dest->error = dest->error_string.s;
188 __archive_errx(int retvalue, const char *msg)
190 static const char *msg1 = "Fatal Internal Error in libarchive: ";
193 s = write(2, msg1, strlen(msg1));
194 (void)s; /* UNUSED */
195 s = write(2, msg, strlen(msg));
196 (void)s; /* UNUSED */
197 s = write(2, "\n", 1);
198 (void)s; /* UNUSED */
203 * Parse option strings
204 * Detail of option format.
205 * - The option can accept:
206 * "opt-name", "!opt-name", "opt-name=value".
208 * - The option entries are separated by comma.
209 * e.g "compression=9,opt=XXX,opt-b=ZZZ"
211 * - The name of option string consist of '-' and alphabet
212 * but character '-' cannot be used for the first character.
213 * (Regular expression is [a-z][-a-z]+)
215 * - For a specfic format/filter, using the format name with ':'.
216 * e.g "zip:compression=9"
217 * (This "compression=9" option entry is for "zip" format only)
219 * If another entries follow it, those are not for
220 * the specfic format/filter.
221 * e.g handle "zip:compression=9,opt=XXX,opt-b=ZZZ"
222 * "zip" format/filter handler will get "compression=9"
223 * all format/filter handler will get "opt=XXX"
224 * all format/filter handler will get "opt-b=ZZZ"
226 * - Whitespace and tab are bypassed.
230 __archive_parse_options(const char *p, const char *fn, int keysize, char *key,
231 int valsize, char *val)
238 /* Requested for initialization. */
240 /* Finding format/filter-name and option-name. */
242 /* Finding option-name only.
243 * (already detected format/filter-name) */
245 /* Getting option-value. */
251 kidx = vidx = negative = 0;
263 if ((*p >= 'a' && *p <= 'z') ||
264 (*p >= '0' && *p <= '9') || *p == '-') {
265 if (kidx == 0 && !(*p >= 'a' && *p <= 'z'))
266 /* Illegal sequence. */
268 if (kidx >= keysize -1)
269 /* Too many characters. */
272 } else if (*p == '!') {
274 /* Illegal sequence. */
278 } else if (*p == ',') {
280 /* Illegal sequence. */
284 /* We have got boolean option data. */
289 /* This option does not apply to the
290 * format which the fn variable
293 } else if (*p == ':') {
294 /* obuf data is format name */
296 /* We already found it. */
299 /* Illegal sequence. */
302 /* We cannot accept "!format-name:". */
305 if (strcmp(fn, key) != 0)
306 /* This option does not apply to the
307 * format which the fn variable
313 } else if (*p == '=') {
315 /* Illegal sequence. */
318 /* We cannot accept "!opt-name=value". */
322 } else if (*p == ' ') {
323 /* Pass the space character */
326 /* Illegal character. */
333 /* Illegal sequence. */
335 /* We have got option data. */
340 /* This option does not apply to the
341 * format which the fn variable
344 } else if (*p == ' ') {
345 /* Pass the space character */
348 if (vidx >= valsize -1)
349 /* Too many characters. */
363 /* We have got boolean option. */
365 /* This option apply to the format which the
366 * fn variable indicate. */
372 /* Illegal sequence. */
374 /* We have got option value. */
376 /* This option apply to the format which the fn
377 * variable indicate. */
380 case INIT:/* nothing */
384 /* End of Option string. */
390 /* Return a size which we've consumed for detecting option */
391 return ((int)(p - p_org));