Home | History | Annotate | Line # | Download | only in libarchive
      1 /*-
      2  * Copyright (c) 2003-2012 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 #ifdef HAVE_ERRNO_H
     29 #include <errno.h>
     30 #endif
     31 
     32 #include "archive.h"
     33 #include "archive_private.h"
     34 #include "archive_read_private.h"
     35 
     36 int
     37 archive_read_set_format(struct archive *_a, int code)
     38 {
     39   int r1, r2, slots, i;
     40   const char *str;
     41   struct archive_read *a = (struct archive_read *)_a;
     42 
     43   if ((r1 = archive_read_support_format_by_code(_a, code)) < (ARCHIVE_OK))
     44     return r1;
     45 
     46   r1 = r2 = (ARCHIVE_OK);
     47   if (a->format)
     48     r2 = (ARCHIVE_WARN);
     49   switch (code & ARCHIVE_FORMAT_BASE_MASK)
     50   {
     51     case ARCHIVE_FORMAT_7ZIP:
     52       str = "7zip";
     53       break;
     54     case ARCHIVE_FORMAT_AR:
     55       str = "ar";
     56       break;
     57     case ARCHIVE_FORMAT_CAB:
     58       str = "cab";
     59       break;
     60     case ARCHIVE_FORMAT_CPIO:
     61       str = "cpio";
     62       break;
     63     case ARCHIVE_FORMAT_EMPTY:
     64       str = "empty";
     65       break;
     66     case ARCHIVE_FORMAT_ISO9660:
     67       str = "iso9660";
     68       break;
     69     case ARCHIVE_FORMAT_LHA:
     70       str = "lha";
     71       break;
     72     case ARCHIVE_FORMAT_MTREE:
     73       str = "mtree";
     74       break;
     75     case ARCHIVE_FORMAT_RAR:
     76       str = "rar";
     77       break;
     78     case ARCHIVE_FORMAT_RAR_V5:
     79       str = "rar5";
     80       break;
     81     case ARCHIVE_FORMAT_RAW:
     82       str = "raw";
     83       break;
     84     case ARCHIVE_FORMAT_TAR:
     85       str = "tar";
     86       break;
     87     case ARCHIVE_FORMAT_WARC:
     88       str = "warc";
     89       break;
     90     case ARCHIVE_FORMAT_XAR:
     91       str = "xar";
     92       break;
     93     case ARCHIVE_FORMAT_ZIP:
     94       str = "zip";
     95       break;
     96     default:
     97       archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
     98           "Invalid format code specified");
     99       return (ARCHIVE_FATAL);
    100   }
    101 
    102   slots = sizeof(a->formats) / sizeof(a->formats[0]);
    103   a->format = &(a->formats[0]);
    104   for (i = 0; i < slots; i++, a->format++) {
    105     if (!a->format->name || !strcmp(a->format->name, str))
    106       break;
    107   }
    108   if (!a->format->name || strcmp(a->format->name, str))
    109   {
    110     archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
    111         "Internal error: Unable to set format");
    112     r1 = (ARCHIVE_FATAL);
    113   }
    114 
    115   return (r1 < r2) ? r1 : r2;
    116 }
    117