"Fossies" - the Fresh Open Source Software Archive

Member "libzip-1.6.0/examples/in-memory.c" (24 Jan 2020, 5704 Bytes) of package /linux/misc/libzip-1.6.0.tar.xz:


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. See also the latest Fossies "Diffs" side-by-side code changes report for "in-memory.c": 1.5.2_vs_1.6.0.

    1 /*
    2   in-memory.c -- modify zip file in memory
    3   Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner
    4 
    5   This file is part of libzip, a library to manipulate ZIP archives.
    6   The authors can be contacted at <libzip@nih.at>
    7 
    8   Redistribution and use in source and binary forms, with or without
    9   modification, are permitted provided that the following conditions
   10   are met:
   11   1. Redistributions of source code must retain the above copyright
   12      notice, this list of conditions and the following disclaimer.
   13   2. Redistributions in binary form must reproduce the above copyright
   14      notice, this list of conditions and the following disclaimer in
   15      the documentation and/or other materials provided with the
   16      distribution.
   17   3. The names of the authors may not be used to endorse or promote
   18      products derived from this software without specific prior
   19      written permission.
   20 
   21   THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
   22   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   23   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
   25   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
   27   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   28   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   29   IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   30   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
   31   IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32 */
   33 
   34 #include <errno.h>
   35 #include <stdio.h>
   36 #include <stdlib.h>
   37 #include <string.h>
   38 #include <sys/stat.h>
   39 
   40 #include <zip.h>
   41 
   42 static int
   43 get_data(void **datap, size_t *sizep, const char *archive) {
   44     /* example implementation that reads data from file */
   45     struct stat st;
   46     FILE *fp;
   47 
   48     if ((fp = fopen(archive, "r")) == NULL) {
   49     if (errno != ENOENT) {
   50         fprintf(stderr, "can't open %s: %s\n", archive, strerror(errno));
   51         return -1;
   52     }
   53 
   54     *datap = NULL;
   55     *sizep = 0;
   56 
   57     return 0;
   58     }
   59 
   60     if (fstat(fileno(fp), &st) < 0) {
   61     fprintf(stderr, "can't stat %s: %s\n", archive, strerror(errno));
   62     fclose(fp);
   63     return -1;
   64     }
   65 
   66     if ((*datap = malloc((size_t)st.st_size)) == NULL) {
   67     fprintf(stderr, "can't allocate buffer\n");
   68     fclose(fp);
   69     return -1;
   70     }
   71 
   72     if (fread(*datap, 1, (size_t)st.st_size, fp) < (size_t)st.st_size) {
   73     fprintf(stderr, "can't read %s: %s\n", archive, strerror(errno));
   74     free(*datap);
   75     fclose(fp);
   76     return -1;
   77     }
   78 
   79     fclose(fp);
   80 
   81     *sizep = (size_t)st.st_size;
   82     return 0;
   83 }
   84 
   85 static int
   86 modify_archive(zip_t *za) {
   87     /* modify the archive */
   88     return 0;
   89 }
   90 
   91 
   92 static int
   93 use_data(void *data, size_t size, const char *archive) {
   94     /* example implementation that writes data to file */
   95     FILE *fp;
   96 
   97     if (data == NULL) {
   98     if (remove(archive) < 0 && errno != ENOENT) {
   99         fprintf(stderr, "can't remove %s: %s\n", archive, strerror(errno));
  100         return -1;
  101     }
  102     return 0;
  103     }
  104 
  105     if ((fp = fopen(archive, "wb")) == NULL) {
  106     fprintf(stderr, "can't open %s: %s\n", archive, strerror(errno));
  107     return -1;
  108     }
  109     if (fwrite(data, 1, size, fp) < size) {
  110     fprintf(stderr, "can't write %s: %s\n", archive, strerror(errno));
  111     fclose(fp);
  112     return -1;
  113     }
  114     if (fclose(fp) < 0) {
  115     fprintf(stderr, "can't write %s: %s\n", archive, strerror(errno));
  116     return -1;
  117     }
  118 
  119     return 0;
  120 }
  121 
  122 
  123 int
  124 main(int argc, char *argv[]) {
  125     const char *archive;
  126     zip_source_t *src;
  127     zip_t *za;
  128     zip_error_t error;
  129     void *data;
  130     size_t size;
  131 
  132     if (argc < 2) {
  133     fprintf(stderr, "usage: %s archive\n", argv[0]);
  134     return 1;
  135     }
  136     archive = argv[1];
  137 
  138     /* get buffer with zip archive inside */
  139     if (get_data(&data, &size, archive) < 0) {
  140     return 1;
  141     }
  142 
  143     zip_error_init(&error);
  144     /* create source from buffer */
  145     if ((src = zip_source_buffer_create(data, size, 1, &error)) == NULL) {
  146     fprintf(stderr, "can't create source: %s\n", zip_error_strerror(&error));
  147     free(data);
  148     zip_error_fini(&error);
  149     return 1;
  150     }
  151 
  152     /* open zip archive from source */
  153     if ((za = zip_open_from_source(src, 0, &error)) == NULL) {
  154     fprintf(stderr, "can't open zip from source: %s\n", zip_error_strerror(&error));
  155     zip_source_free(src);
  156     zip_error_fini(&error);
  157     return 1;
  158     }
  159     zip_error_fini(&error);
  160 
  161     /* we'll want to read the data back after zip_close */
  162     zip_source_keep(src);
  163 
  164     /* modify archive */
  165     modify_archive(za);
  166 
  167     /* close archive */
  168     if (zip_close(za) < 0) {
  169     fprintf(stderr, "can't close zip archive '%s': %s\n", archive, zip_strerror(za));
  170     return 1;
  171     }
  172 
  173 
  174     /* copy new archive to buffer */
  175 
  176     if (zip_source_is_deleted(src)) {
  177     /* new archive is empty, thus no data */
  178     data = NULL;
  179     }
  180     else {
  181     zip_stat_t zst;
  182 
  183     if (zip_source_stat(src, &zst) < 0) {
  184         fprintf(stderr, "can't stat source: %s\n", zip_error_strerror(zip_source_error(src)));
  185         return 1;
  186     }
  187 
  188     size = zst.size;
  189 
  190     if (zip_source_open(src) < 0) {
  191         fprintf(stderr, "can't open source: %s\n", zip_error_strerror(zip_source_error(src)));
  192         return 1;
  193     }
  194     if ((data = malloc(size)) == NULL) {
  195         fprintf(stderr, "malloc failed: %s\n", strerror(errno));
  196         zip_source_close(src);
  197         return 1;
  198     }
  199     if ((zip_uint64_t)zip_source_read(src, data, size) < size) {
  200         fprintf(stderr, "can't read data from source: %s\n", zip_error_strerror(zip_source_error(src)));
  201         zip_source_close(src);
  202         free(data);
  203         return 1;
  204     }
  205     zip_source_close(src);
  206     }
  207 
  208     /* we're done with src */
  209     zip_source_free(src);
  210 
  211     /* use new data */
  212     use_data(data, size, archive);
  213 
  214     free(data);
  215 
  216     return 0;
  217 }