archive_write_set_format_filter_by_ext.c revision 302001
11592Srgrimes/*-
21592Srgrimes * Copyright (c) 2003-2007 Tim Kientzle
31592Srgrimes * Copyright (c) 2015 Okhotnikov Kirill
41592Srgrimes * All rights reserved.
51592Srgrimes *
61592Srgrimes * Redistribution and use in source and binary forms, with or without
71592Srgrimes * modification, are permitted provided that the following conditions
81592Srgrimes * are met:
91592Srgrimes * 1. Redistributions of source code must retain the above copyright
101592Srgrimes *    notice, this list of conditions and the following disclaimer.
111592Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
121592Srgrimes *    notice, this list of conditions and the following disclaimer in the
131592Srgrimes *    documentation and/or other materials provided with the distribution.
141592Srgrimes *
151592Srgrimes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
161592Srgrimes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
171592Srgrimes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
181592Srgrimes * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
191592Srgrimes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
201592Srgrimes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
211592Srgrimes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
221592Srgrimes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
231592Srgrimes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
241592Srgrimes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
251592Srgrimes */
261592Srgrimes
271592Srgrimes#include "archive_platform.h"
281592Srgrimes__FBSDID("$FreeBSD: stable/10/contrib/libarchive/libarchive/archive_write_set_format_filter_by_ext.c 302001 2016-06-17 22:40:10Z mm $");
291592Srgrimes
301592Srgrimes#ifdef HAVE_SYS_TYPES_H
311592Srgrimes#include <sys/types.h>
321592Srgrimes#endif
331592Srgrimes
341592Srgrimes#ifdef HAVE_ERRNO_H
3531307Scharnier#include <errno.h>
361592Srgrimes#endif
371592Srgrimes#ifdef HAVE_STRING_H
381592Srgrimes#include <string.h>
391592Srgrimes#endif
401592Srgrimes
4131307Scharnier#include "archive.h"
421592Srgrimes#include "archive_private.h"
4331307Scharnier
4431307Scharnier/* A table that maps names to functions. */
4537297Sbdestatic
461592Srgrimesstruct { const char *name; int (*format)(struct archive *); int (*filter)(struct archive *);  } names[] =
471592Srgrimes{
481592Srgrimes	{ ".7z",	archive_write_set_format_7zip,            archive_write_add_filter_none},
491592Srgrimes	{ ".zip",	archive_write_set_format_zip,             archive_write_add_filter_none},
501592Srgrimes	{ ".jar",	archive_write_set_format_zip,             archive_write_add_filter_none},
511592Srgrimes	{ ".cpio",	archive_write_set_format_cpio,            archive_write_add_filter_none},
521592Srgrimes	{ ".iso",	archive_write_set_format_iso9660,         archive_write_add_filter_none},
531592Srgrimes#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__) || defined(__OpenBSD__)
541592Srgrimes	{ ".a",	        archive_write_set_format_ar_bsd,          archive_write_add_filter_none},
551592Srgrimes	{ ".ar",	archive_write_set_format_ar_bsd,          archive_write_add_filter_none},
561592Srgrimes#else
5731307Scharnier	{ ".a",	        archive_write_set_format_ar_svr4,         archive_write_add_filter_none},
581592Srgrimes	{ ".ar",	archive_write_set_format_ar_svr4,         archive_write_add_filter_none},
591592Srgrimes#endif
601592Srgrimes	{ ".tar",	archive_write_set_format_pax_restricted,  archive_write_add_filter_none},
611592Srgrimes	{ ".tgz",	archive_write_set_format_pax_restricted,  archive_write_add_filter_gzip},
6218093Speter	{ ".tar.gz",	archive_write_set_format_pax_restricted,  archive_write_add_filter_gzip},
631592Srgrimes	{ ".tar.bz2",	archive_write_set_format_pax_restricted,  archive_write_add_filter_bzip2},
641592Srgrimes	{ ".tar.xz",	archive_write_set_format_pax_restricted,  archive_write_add_filter_xz},
651592Srgrimes	{ NULL,		NULL,                             NULL }
661592Srgrimes};
671592Srgrimes
681592Srgrimesstatic
691592Srgrimesint cmpsuff(const char *str, const char *suffix)
701592Srgrimes{
711592Srgrimes  size_t length_str, length_suffix;
721592Srgrimes
731592Srgrimes  if ((str == NULL) || (suffix == NULL))
741592Srgrimes    return -1;
751592Srgrimes
761592Srgrimes  length_str = strlen(str);
771592Srgrimes  length_suffix = strlen(suffix);
781592Srgrimes
791592Srgrimes  if (length_str >= length_suffix) {
801592Srgrimes    return strcmp(str + (length_str - length_suffix), suffix);
8116105Spst  } else {
821592Srgrimes    return -1;
833618Sache  }
841592Srgrimes}
851592Srgrimes
861592Srgrimesstatic int get_array_index(const char *name)
871592Srgrimes{
881592Srgrimes  int i;
891592Srgrimes
901592Srgrimes  for (i = 0; names[i].name != NULL; i++)
911592Srgrimes  {
921592Srgrimes    if (cmpsuff(name, names[i].name) == 0)
931592Srgrimes      return i;
941592Srgrimes  }
953618Sache  return -1;
961592Srgrimes
971592Srgrimes}
981592Srgrimes
9931307Scharnierint
10031307Scharnierarchive_write_set_format_filter_by_ext(struct archive *a, const char *filename)
1011592Srgrimes{
1021592Srgrimes  int names_index = get_array_index(filename);
1031592Srgrimes
1041592Srgrimes  if (names_index >= 0)
1051592Srgrimes  {
1061592Srgrimes    int format_state = (names[names_index].format)(a);
1071592Srgrimes    if (format_state == ARCHIVE_OK)
1081592Srgrimes      return ((names[names_index].filter)(a));
1091592Srgrimes    else
1101592Srgrimes      return format_state;
1111592Srgrimes  }
1121592Srgrimes
1131592Srgrimes  archive_set_error(a, EINVAL, "No such format '%s'", filename);
1141592Srgrimes  a->state = ARCHIVE_STATE_FATAL;
1151592Srgrimes  return (ARCHIVE_FATAL);
1161592Srgrimes}
1171592Srgrimes
1181592Srgrimesint
1191592Srgrimesarchive_write_set_format_filter_by_ext_def(struct archive *a, const char *filename, const char * def_ext)
1201592Srgrimes{
1211592Srgrimes  int names_index = get_array_index(filename);
1221592Srgrimes
1231592Srgrimes  if (names_index < 0)
1241592Srgrimes    names_index = get_array_index(def_ext);
1251592Srgrimes
1261592Srgrimes  if (names_index >= 0)
1271592Srgrimes  {
1281592Srgrimes    int format_state = (names[names_index].format)(a);
1291592Srgrimes    if (format_state == ARCHIVE_OK)
1301592Srgrimes      return ((names[names_index].filter)(a));
1311592Srgrimes    else
1321592Srgrimes      return format_state;
1331592Srgrimes  }
1341592Srgrimes
1351592Srgrimes  archive_set_error(a, EINVAL, "No such format '%s'", filename);
1361592Srgrimes  a->state = ARCHIVE_STATE_FATAL;
1371592Srgrimes  return (ARCHIVE_FATAL);
1381592Srgrimes}
1391592Srgrimes
1401592Srgrimes
1411592Srgrimes
1421592Srgrimes
1431592Srgrimes