Path: blob/master/Utilities/cmlibarchive/libarchive/archive_options.c
3153 views
/*-1* Copyright (c) 2011 Tim Kientzle2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer.9* 2. Redistributions in binary form must reproduce the above copyright10* notice, this list of conditions and the following disclaimer in the11* documentation and/or other materials provided with the distribution.12*13* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR14* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES15* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.16* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,17* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT18* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,19* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY20* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT21* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF22* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.23*/2425#include "archive_platform.h"2627#ifdef HAVE_ERRNO_H28#include <errno.h>29#endif3031#include "archive_options_private.h"3233static const char *34parse_option(const char **str,35const char **mod, const char **opt, const char **val);3637int38_archive_set_option(struct archive *a,39const char *m, const char *o, const char *v,40int magic, const char *fn, option_handler use_option)41{42const char *mp, *op, *vp;43int r;4445archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);4647mp = (m != NULL && m[0] != '\0') ? m : NULL;48op = (o != NULL && o[0] != '\0') ? o : NULL;49vp = (v != NULL && v[0] != '\0') ? v : NULL;5051if (op == NULL && vp == NULL)52return (ARCHIVE_OK);53if (op == NULL) {54archive_set_error(a, ARCHIVE_ERRNO_MISC, "Empty option");55return (ARCHIVE_FAILED);56}5758r = use_option(a, mp, op, vp);59if (r == ARCHIVE_WARN - 1) {60archive_set_error(a, ARCHIVE_ERRNO_MISC,61"Unknown module name: `%s'", mp);62return (ARCHIVE_FAILED);63}64if (r == ARCHIVE_WARN) {65archive_set_error(a, ARCHIVE_ERRNO_MISC,66"Undefined option: `%s%s%s%s%s%s'",67vp?"":"!", mp?mp:"", mp?":":"", op, vp?"=":"", vp?vp:"");68return (ARCHIVE_FAILED);69}70return (r);71}7273int74_archive_set_either_option(struct archive *a, const char *m, const char *o, const char *v,75option_handler use_format_option, option_handler use_filter_option)76{77int r1, r2;7879if (o == NULL && v == NULL)80return (ARCHIVE_OK);81if (o == NULL)82return (ARCHIVE_FAILED);8384r1 = use_format_option(a, m, o, v);85if (r1 == ARCHIVE_FATAL)86return (ARCHIVE_FATAL);8788r2 = use_filter_option(a, m, o, v);89if (r2 == ARCHIVE_FATAL)90return (ARCHIVE_FATAL);9192if (r2 == ARCHIVE_WARN - 1)93return r1;94return r1 > r2 ? r1 : r2;95}9697int98_archive_set_options(struct archive *a, const char *options,99int magic, const char *fn, option_handler use_option)100{101int allok = 1, anyok = 0, ignore_mod_err = 0, r;102char *data;103const char *s, *mod, *opt, *val;104105archive_check_magic(a, magic, ARCHIVE_STATE_NEW, fn);106107if (options == NULL || options[0] == '\0')108return ARCHIVE_OK;109110if ((data = strdup(options)) == NULL) {111archive_set_error(a,112ENOMEM, "Out of memory adding file to list");113return (ARCHIVE_FATAL);114}115s = (const char *)data;116117do {118mod = opt = val = NULL;119120parse_option(&s, &mod, &opt, &val);121if (mod == NULL && opt != NULL &&122strcmp("__ignore_wrong_module_name__", opt) == 0) {123/* Ignore module name error */124if (val != NULL) {125ignore_mod_err = 1;126anyok = 1;127}128continue;129}130131r = use_option(a, mod, opt, val);132if (r == ARCHIVE_FATAL) {133free(data);134return (ARCHIVE_FATAL);135}136if (r == ARCHIVE_FAILED && mod != NULL) {137free(data);138return (ARCHIVE_FAILED);139}140if (r == ARCHIVE_WARN - 1) {141if (ignore_mod_err)142continue;143/* The module name is wrong. */144archive_set_error(a, ARCHIVE_ERRNO_MISC,145"Unknown module name: `%s'", mod);146free(data);147return (ARCHIVE_FAILED);148}149if (r == ARCHIVE_WARN) {150/* The option name is wrong. No-one used this. */151archive_set_error(a, ARCHIVE_ERRNO_MISC,152"Undefined option: `%s%s%s'",153mod?mod:"", mod?":":"", opt);154free(data);155return (ARCHIVE_FAILED);156}157if (r == ARCHIVE_OK)158anyok = 1;159else160allok = 0;161} while (s != NULL);162163free(data);164return allok ? ARCHIVE_OK : anyok ? ARCHIVE_WARN : ARCHIVE_FAILED;165}166167static const char *168parse_option(const char **s, const char **m, const char **o, const char **v)169{170const char *end, *mod, *opt, *val;171char *p;172173end = NULL;174mod = NULL;175opt = *s;176val = "1";177178p = strchr(opt, ',');179180if (p != NULL) {181*p = '\0';182end = ((const char *)p) + 1;183}184185if (0 == strlen(opt)) {186*s = end;187*m = NULL;188*o = NULL;189*v = NULL;190return end;191}192193p = strchr(opt, ':');194if (p != NULL) {195*p = '\0';196mod = opt;197opt = ++p;198}199200p = strchr(opt, '=');201if (p != NULL) {202*p = '\0';203val = ++p;204} else if (opt[0] == '!') {205++opt;206val = NULL;207}208209*s = end;210*m = mod;211*o = opt;212*v = val;213214return end;215}216217218219