Home | History | Annotate | Line # | Download | only in libarchive
      1 /*-
      2  * Copyright (c) 2011 Tim Kientzle
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
     15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     17  * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
     18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "archive_platform.h"
     27 
     28 #include "archive_read_private.h"
     29 #include "archive_options_private.h"
     30 
     31 static int	archive_set_format_option(struct archive *a,
     32 		    const char *m, const char *o, const char *v);
     33 static int	archive_set_filter_option(struct archive *a,
     34 		    const char *m, const char *o, const char *v);
     35 static int	archive_set_option(struct archive *a,
     36 		    const char *m, const char *o, const char *v);
     37 
     38 int
     39 archive_read_set_format_option(struct archive *a, const char *m, const char *o,
     40     const char *v)
     41 {
     42 	return _archive_set_option(a, m, o, v,
     43 	    ARCHIVE_READ_MAGIC, "archive_read_set_format_option",
     44 	    archive_set_format_option);
     45 }
     46 
     47 int
     48 archive_read_set_filter_option(struct archive *a, const char *m, const char *o,
     49     const char *v)
     50 {
     51 	return _archive_set_option(a, m, o, v,
     52 	    ARCHIVE_READ_MAGIC, "archive_read_set_filter_option",
     53 	    archive_set_filter_option);
     54 }
     55 
     56 int
     57 archive_read_set_option(struct archive *a, const char *m, const char *o,
     58     const char *v)
     59 {
     60 	return _archive_set_option(a, m, o, v,
     61 	    ARCHIVE_READ_MAGIC, "archive_read_set_option",
     62 	    archive_set_option);
     63 }
     64 
     65 int
     66 archive_read_set_options(struct archive *a, const char *options)
     67 {
     68 	return _archive_set_options(a, options,
     69 	    ARCHIVE_READ_MAGIC, "archive_read_set_options",
     70 	    archive_set_option);
     71 }
     72 
     73 static int
     74 archive_set_format_option(struct archive *_a, const char *m, const char *o,
     75     const char *v)
     76 {
     77 	struct archive_read *a = (struct archive_read *)_a;
     78 	size_t i;
     79 	int r, rv = ARCHIVE_WARN, matched_modules = 0;
     80 
     81 	for (i = 0; i < sizeof(a->formats)/sizeof(a->formats[0]); i++) {
     82 		struct archive_format_descriptor *format = &a->formats[i];
     83 
     84 		if (format->options == NULL || format->name == NULL)
     85 			/* This format does not support option. */
     86 			continue;
     87 		if (m != NULL) {
     88 			if (strcmp(format->name, m) != 0)
     89 				continue;
     90 			++matched_modules;
     91 		}
     92 
     93 		a->format = format;
     94 		r = format->options(a, o, v);
     95 		a->format = NULL;
     96 
     97 		if (r == ARCHIVE_FATAL)
     98 			return (ARCHIVE_FATAL);
     99 
    100 		if (r == ARCHIVE_OK)
    101 			rv = ARCHIVE_OK;
    102 	}
    103 	/* If the format name didn't match, return a special code for
    104 	 * _archive_set_option[s]. */
    105 	if (m != NULL && matched_modules == 0)
    106 		return ARCHIVE_WARN - 1;
    107 	return (rv);
    108 }
    109 
    110 static int
    111 archive_set_filter_option(struct archive *_a, const char *m, const char *o,
    112     const char *v)
    113 {
    114 	(void)_a; /* UNUSED */
    115 	(void)o; /* UNUSED */
    116 	(void)v; /* UNUSED */
    117 
    118 	/* If the filter name didn't match, return a special code for
    119 	 * _archive_set_option[s]. */
    120 	if (m != NULL)
    121 		return ARCHIVE_WARN - 1;
    122 	return ARCHIVE_WARN;
    123 }
    124 
    125 static int
    126 archive_set_option(struct archive *a, const char *m, const char *o,
    127     const char *v)
    128 {
    129 	return _archive_set_either_option(a, m, o, v,
    130 	    archive_set_format_option,
    131 	    archive_set_filter_option);
    132 }
    133