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: head/lib/libarchive/archive_util.c 201098 2009-12-28 02:58:14Z kientzle $");
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));