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