"Fossies" - the Fresh Open Source Software Archive

Member "libextractor-1.11/src/plugins/archive_extractor.c" (30 Jan 2021, 3816 Bytes) of package /linux/privat/libextractor-1.11.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "archive_extractor.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2      This file is part of libextractor.
    3      Copyright (C) 2012 Christian Grothoff
    4 
    5      libextractor is free software; you can redistribute it and/or modify
    6      it under the terms of the GNU General Public License as published
    7      by the Free Software Foundation; either version 3, or (at your
    8      option) any later version.
    9 
   10      libextractor is distributed in the hope that it will be useful, but
   11      WITHOUT ANY WARRANTY; without even the implied warranty of
   12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13      General Public License for more details.
   14 
   15      You should have received a copy of the GNU General Public License
   16      along with libextractor; see the file COPYING.  If not, write to the
   17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   18      Boston, MA 02110-1301, USA.
   19  */
   20 /**
   21  * @file plugins/archive_extractor.c
   22  * @brief plugin to support archives (such as TAR)
   23  * @author Christian Grothoff
   24  */
   25 #include "platform.h"
   26 #include "extractor.h"
   27 #include <archive.h>
   28 #include <archive_entry.h>
   29 
   30 /**
   31  * Callback for libarchive for 'reading'.
   32  *
   33  * @param a archive handle
   34  * @param client_data our 'struct EXTRACTOR_ExtractContext'
   35  * @param buff where to store data with pointer to data
   36  * @return number of bytes read
   37  */
   38 static ssize_t
   39 read_cb (struct archive *a,
   40          void *client_data,
   41          const void **buff)
   42 {
   43   struct EXTRACTOR_ExtractContext *ec = client_data;
   44   ssize_t ret;
   45 
   46   *buff = NULL;
   47   if (-1 == (ret = ec->read (ec->cls, (void **) buff, 16 * 1024)))
   48     return ARCHIVE_FATAL;
   49   return ret;
   50 }
   51 
   52 
   53 /**
   54  * Older versions of libarchive do not define __LA_INT64_T.
   55  */
   56 #if ARCHIVE_VERSION_NUMBER < 2000000
   57 #define __LA_INT64_T size_t
   58 #else
   59 #ifndef __LA_INT64_T
   60 #define __LA_INT64_T int64_t
   61 #endif
   62 #endif
   63 
   64 
   65 /**
   66  * Callback for libarchive for 'skipping'.
   67  *
   68  * @param a archive handle
   69  * @param client_data our 'struct EXTRACTOR_ExtractContext'
   70  * @param request number of bytes to skip
   71  * @return number of bytes skipped
   72  */
   73 static __LA_INT64_T
   74 skip_cb (struct archive *a,
   75          void *client_data,
   76          __LA_INT64_T request)
   77 {
   78   struct EXTRACTOR_ExtractContext *ec = client_data;
   79 
   80   if (-1 == ec->seek (ec->cls, request, SEEK_CUR))
   81     return 0;
   82   return request;
   83 }
   84 
   85 
   86 /**
   87  * Main entry method for the ARCHIVE extraction plugin.
   88  *
   89  * @param ec extraction context provided to the plugin
   90  */
   91 void
   92 EXTRACTOR_archive_extract_method (struct EXTRACTOR_ExtractContext *ec)
   93 {
   94   struct archive *a;
   95   struct archive_entry *entry;
   96   const char *fname;
   97   const char *s;
   98   char *format;
   99 
  100   format = NULL;
  101   a = archive_read_new ();
  102 #if ARCHIVE_VERSION_NUMBER >= 3000000
  103   archive_read_support_filter_all (a);
  104 #else
  105   archive_read_support_compression_all (a);
  106 #endif
  107   archive_read_support_format_all (a);
  108   if (archive_read_open2 (a, ec, NULL, &read_cb, &skip_cb, NULL)!= ARCHIVE_OK)
  109     return;
  110 
  111   while (ARCHIVE_OK == archive_read_next_header (a, &entry))
  112   {
  113     if ( (NULL == format) &&
  114          (NULL != (fname = archive_format_name (a))) )
  115       format = strdup (fname);
  116     s = archive_entry_pathname (entry);
  117     if (0 != ec->proc (ec->cls,
  118                        "tar",
  119                        EXTRACTOR_METATYPE_FILENAME,
  120                        EXTRACTOR_METAFORMAT_UTF8,
  121                        "text/plain",
  122                        s, strlen (s) + 1))
  123       break;
  124   }
  125 #if ARCHIVE_VERSION_NUMBER >= 3000000
  126   archive_read_free (a);
  127 #else
  128   archive_read_finish (a);
  129 #endif
  130   if (NULL != format)
  131   {
  132     if (0 != ec->proc (ec->cls,
  133                        "tar",
  134                        EXTRACTOR_METATYPE_FORMAT,
  135                        EXTRACTOR_METAFORMAT_UTF8,
  136                        "text/plain", format, strlen (format) + 1))
  137     {
  138       free (format);
  139       return;
  140     }
  141     free (format);
  142   }
  143 }
  144 
  145 
  146 /* end of tar_extractor.c */