/*
 hole.c -- convert huge files with mostly NULs to/from source_hole
 Copyright (C) 2014-2017 Dieter Baron and Thomas Klausner
 
 This file is part of libzip, a library to manipulate ZIP archives.
 The authors can be contacted at <libzip@nih.at>
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
 notice, this list of conditions and the following disclaimer.
 2. Redistributions in binary form must reproduce the above copyright
 notice, this list of conditions and the following disclaimer in
 the documentation and/or other materials provided with the
 distribution.
 3. The names of the authors may not be used to endorse or promote
 products derived from this software without specific prior
 written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"

#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifndef HAVE_GETOPT
#include "getopt.h"
#endif

#include "zip.h"

/* public API */

zip_source_t *source_hole_create(const char *, int flags, zip_error_t *);

const char *prg;


static int
copy_source(zip_source_t *from, zip_source_t *to)
{
    zip_uint8_t buf[8192];
    zip_int64_t n;
    
    if (zip_source_open(from) < 0) {
        fprintf(stderr, "%s: can't open source for reading: %s\n", prg, zip_error_strerror(zip_source_error(from)));
        return -1;
    }
    
    if (zip_source_begin_write(to) < 0) {
        fprintf(stderr, "%s: can't open source for writing: %s\n", prg, zip_error_strerror(zip_source_error(to)));
        zip_source_close(from);
        return -1;
    }
        
    while ((n = zip_source_read(from, buf, sizeof(buf))) > 0) {
        if (zip_source_write(to, buf, (zip_uint64_t)n) != n) {
            fprintf(stderr, "%s: can't write to source: %s\n", prg, zip_error_strerror(zip_source_error(to)));
            zip_source_close(from);
            zip_source_rollback_write(to);
            return -1;
        }
    }
    
    if (n < 0) {
        fprintf(stderr, "%s: can't read from source: %s\n", prg, zip_error_strerror(zip_source_error(from)));
        zip_source_close(from);
        zip_source_rollback_write(to);
        return -1;
    }

    zip_source_close(from);
    
    if (zip_source_commit_write(to) < 0) {
        fprintf(stderr, "%s: can't commit source: %s\n", prg, zip_error_strerror(zip_source_error(to)));
        zip_source_rollback_write(to);
        return -1;
    }
    
    return 0;
}


static zip_source_t *
open_compressed(const char *fname, int flags)
{
    zip_error_t error;
    zip_source_t *src;
    
    zip_error_init(&error);
    
    if ((src = source_hole_create(fname, flags, &error)) == NULL) {
        fprintf(stderr, "%s: can't open compressed file %s: %s\n", prg, fname, zip_error_strerror(&error));
        zip_error_fini(&error);
        exit(1);
    }
    
    return src;
}


static zip_source_t *
open_file(const char *fname)
{
    zip_error_t error;
    zip_source_t *src;
    
    zip_error_init(&error);
    
    if ((src = zip_source_file_create(fname, 0, 0, &error)) == NULL) {
        fprintf(stderr, "%s: can't open file %s: %s\n", prg, fname, zip_error_strerror(&error));
        zip_error_fini(&error);
        exit(1);
    }
    
    return src;
}


static void
usage(void)
{
    fprintf(stderr, "usage: %s [-du] in out\n", prg);
    fprintf(stderr, "\nOptions:\n  -d  decompress in\n  -u  update in\n");
    exit(1);
}


int
main(int argc, char **argv)
{
    zip_source_t *from;
    zip_source_t *to;
    int c, err;
    int compress = 1;
    int decompress = 0;
    
    prg = argv[0];
    
    while ((c=getopt(argc, argv, "du")) != -1) {
        switch (c) {
            case 'd':
                compress = 0;
                decompress = 1;
                break;

            case 'u':
                compress = 1;
                decompress = 1;
                break;

            default:
                usage();
                break;
        }
    }
    
    if (optind+2 != argc) {
        usage();
    }
    
    if (decompress) {
        from = open_compressed(argv[optind], 0);
    }
    else {
        from = open_file(argv[optind]);
    }

    if (compress) {
        to = open_compressed(argv[optind+1], ZIP_CREATE);
    }
    else {
        to = open_file(argv[optind+1]);
    }
    
    err = copy_source(from, to);
    
    zip_source_free(from);
    zip_source_free(to);
    
    exit(err < 0 ? 1 : 0);
}

