archive_options.c revision 231200
1231200Smm/*-
2231200Smm * Copyright (c) 2011 Tim Kientzle
3231200Smm * All rights reserved.
4231200Smm *
5231200Smm * Redistribution and use in source and binary forms, with or without
6231200Smm * modification, are permitted provided that the following conditions
7231200Smm * are met:
8231200Smm * 1. Redistributions of source code must retain the above copyright
9231200Smm *    notice, this list of conditions and the following disclaimer.
10231200Smm * 2. Redistributions in binary form must reproduce the above copyright
11231200Smm *    notice, this list of conditions and the following disclaimer in the
12231200Smm *    documentation and/or other materials provided with the distribution.
13231200Smm *
14231200Smm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
15231200Smm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16231200Smm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17231200Smm * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
18231200Smm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19231200Smm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20231200Smm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21231200Smm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22231200Smm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23231200Smm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24231200Smm */
25231200Smm
26231200Smm#include "archive_platform.h"
27231200Smm__FBSDID("$FreeBSD$");
28231200Smm
29231200Smm#include "archive_options_private.h"
30231200Smm
31231200Smmstatic const char *
32231200Smmparse_option(const char **str,
33231200Smm    const char **mod, const char **opt, const char **val);
34231200Smm
35231200Smmint
36231200Smm_archive_set_option(struct archive *a,
37231200Smm    const char *m, const char *o, const char *v,
38231200Smm    int magic, const char *fn, option_handler use_option)
39231200Smm{
40231200Smm	const char *mp, *op, *vp;
41231200Smm
42231200Smm	archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
43231200Smm
44231200Smm	mp = m != NULL && m[0] == '\0' ? NULL : m;
45231200Smm	op = o != NULL && o[0] == '\0' ? NULL : o;
46231200Smm	vp = v != NULL && v[0] == '\0' ? NULL : v;
47231200Smm
48231200Smm	if (op == NULL && vp == NULL)
49231200Smm		return (ARCHIVE_OK);
50231200Smm	if (op == NULL)
51231200Smm		return (ARCHIVE_FAILED);
52231200Smm
53231200Smm	return use_option(a, mp, op, vp);
54231200Smm}
55231200Smm
56231200Smmint
57231200Smm_archive_set_either_option(struct archive *a, const char *m, const char *o, const char *v,
58231200Smm    option_handler use_format_option, option_handler use_filter_option)
59231200Smm{
60231200Smm	int r1, r2;
61231200Smm
62231200Smm	if (o == NULL && v == NULL)
63231200Smm		return (ARCHIVE_OK);
64231200Smm	if (o == NULL)
65231200Smm		return (ARCHIVE_FAILED);
66231200Smm
67231200Smm	r1 = use_format_option(a, m, o, v);
68231200Smm	if (r1 == ARCHIVE_FATAL)
69231200Smm		return (ARCHIVE_FATAL);
70231200Smm
71231200Smm	r2 = use_filter_option(a, m, o, v);
72231200Smm	if (r2 == ARCHIVE_FATAL)
73231200Smm		return (ARCHIVE_FATAL);
74231200Smm
75231200Smm	return r1 > r2 ? r1 : r2;
76231200Smm}
77231200Smm
78231200Smmint
79231200Smm_archive_set_options(struct archive *a, const char *options,
80231200Smm    int magic, const char *fn, option_handler use_option)
81231200Smm{
82231200Smm	int allok = 1, anyok = 0, r;
83231200Smm	char *data;
84231200Smm	const char *s, *mod, *opt, *val;
85231200Smm
86231200Smm	archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);
87231200Smm
88231200Smm	if (options == NULL || options[0] == '\0')
89231200Smm		return ARCHIVE_OK;
90231200Smm
91231200Smm	data = (char *)malloc(strlen(options) + 1);
92231200Smm	strcpy(data, options);
93231200Smm	s = (const char *)data;
94231200Smm
95231200Smm	do {
96231200Smm		mod = opt = val = NULL;
97231200Smm
98231200Smm		parse_option(&s, &mod, &opt, &val);
99231200Smm
100231200Smm		r = use_option(a, mod, opt, val);
101231200Smm		if (r == ARCHIVE_FATAL) {
102231200Smm			free(data);
103231200Smm			return (ARCHIVE_FATAL);
104231200Smm		}
105231200Smm		if (r == ARCHIVE_OK)
106231200Smm			anyok = 1;
107231200Smm		else
108231200Smm			allok = 0;
109231200Smm	} while (s != NULL);
110231200Smm
111231200Smm	free(data);
112231200Smm	return allok ? ARCHIVE_OK : anyok ? ARCHIVE_WARN : ARCHIVE_FAILED;
113231200Smm}
114231200Smm
115231200Smmstatic const char *
116231200Smmparse_option(const char **s, const char **m, const char **o, const char **v)
117231200Smm{
118231200Smm	const char *end, *mod, *opt, *val;
119231200Smm	char *p;
120231200Smm
121231200Smm	end = NULL;
122231200Smm	mod = NULL;
123231200Smm	opt = *s;
124231200Smm	val = "1";
125231200Smm
126231200Smm	p = strchr(opt, ',');
127231200Smm
128231200Smm	if (p != NULL) {
129231200Smm		*p = '\0';
130231200Smm		end = ((const char *)p) + 1;
131231200Smm	}
132231200Smm
133231200Smm	if (0 == strlen(opt)) {
134231200Smm		*s = end;
135231200Smm		*m = NULL;
136231200Smm		*o = NULL;
137231200Smm		*v = NULL;
138231200Smm		return end;
139231200Smm	}
140231200Smm
141231200Smm	p = strchr(opt, ':');
142231200Smm	if (p != NULL) {
143231200Smm		*p = '\0';
144231200Smm		mod = opt;
145231200Smm		opt = ++p;
146231200Smm	}
147231200Smm
148231200Smm	p = strchr(opt, '=');
149231200Smm	if (p != NULL) {
150231200Smm		*p = '\0';
151231200Smm		val = ++p;
152231200Smm	} else if (opt[0] == '!') {
153231200Smm		++opt;
154231200Smm		val = NULL;
155231200Smm	}
156231200Smm
157231200Smm	*s = end;
158231200Smm	*m = mod;
159231200Smm	*o = opt;
160231200Smm	*v = val;
161231200Smm
162231200Smm	return end;
163231200Smm}
164231200Smm
165