/*
  zipmerge.c -- merge zip archives
  Copyright (C) 2004-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 <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "config.h"

#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

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

#include "compat.h"
#include "zip.h"

char *prg;

#define PROGRAM "zipmerge"

#define USAGE "usage: %s [-DhIiSsV] target-zip zip...\n"

char help_head[] = PROGRAM " (" PACKAGE ") by Dieter Baron and Thomas Klausner\n\n";

char help[] = "\n\
  -h       display this help message\n\
  -V       display version number\n\
  -D       ignore directory component in file names\n\
  -I       ignore case in file names\n\
  -i       ask before overwriting files\n\
  -S       don't overwrite identical files\n\
  -s       overwrite identical files without asking\n\
\n\
Report bugs to <libzip@nih.at>.\n";

char version_string[] = PROGRAM " (" PACKAGE " " VERSION ")\n\
Copyright (C) 2004-2017 Dieter Baron and Thomas Klausner\n\
" PACKAGE " comes with ABSOLUTELY NO WARRANTY, to the extent permitted by law.\n";

#define OPTIONS "hVDiIsS"

#define CONFIRM_ALL_YES 0x001
#define CONFIRM_ALL_NO 0x002
#define CONFIRM_SAME_YES 0x010
#define CONFIRM_SAME_NO 0x020

int confirm;
zip_flags_t name_flags;

static int confirm_replace(zip_t *, const char *, zip_uint64_t, zip_t *, const char *, zip_uint64_t);
static zip_t *merge_zip(zip_t *, const char *, const char *);


int
main(int argc, char *argv[]) {
    zip_t *za;
    zip_t **zs;
    int c, err;
    unsigned int i, n;
    char *tname;

    prg = argv[0];

    confirm = CONFIRM_ALL_YES;
    name_flags = 0;

    while ((c = getopt(argc, argv, OPTIONS)) != -1) {
	switch (c) {
	case 'D':
	    name_flags |= ZIP_FL_NODIR;
	    break;
	case 'i':
	    confirm &= ~CONFIRM_ALL_YES;
	    break;
	case 'I':
	    name_flags |= ZIP_FL_NOCASE;
	    break;
	case 's':
	    confirm &= ~CONFIRM_SAME_NO;
	    confirm |= CONFIRM_SAME_YES;
	    break;
	case 'S':
	    confirm &= ~CONFIRM_SAME_YES;
	    confirm |= CONFIRM_SAME_NO;
	    break;

	case 'h':
	    fputs(help_head, stdout);
	    printf(USAGE, prg);
	    fputs(help, stdout);
	    exit(0);
	case 'V':
	    fputs(version_string, stdout);
	    exit(0);

	default:
	    fprintf(stderr, USAGE, prg);
	    exit(2);
	}
    }

    if (argc < optind + 2) {
	fprintf(stderr, USAGE, prg);
	exit(2);
    }

    tname = argv[optind++];
    argv += optind;

    n = (unsigned int)(argc - optind);
    if ((zs = (zip_t **)malloc(sizeof(zs[0]) * n)) == NULL) {
	fprintf(stderr, "%s: out of memory\n", prg);
	exit(1);
    }

    if ((za = zip_open(tname, ZIP_CREATE, &err)) == NULL) {
	zip_error_t error;
	zip_error_init_with_code(&error, err);
	fprintf(stderr, "%s: can't open zip archive '%s': %s\n", prg, tname, zip_error_strerror(&error));
	zip_error_fini(&error);
	exit(1);
    }

    for (i = 0; i < n; i++) {
	if ((zs[i] = merge_zip(za, tname, argv[i])) == NULL)
	    exit(1);
    }

    if (zip_close(za) < 0) {
	fprintf(stderr, "%s: cannot write zip archive '%s': %s\n", prg, tname, zip_strerror(za));
	exit(1);
    }

    for (i = 0; i < n; i++)
	zip_close(zs[i]);

    exit(0);
}


static int
confirm_replace(zip_t *za, const char *tname, zip_uint64_t it, zip_t *zs, const char *sname, zip_uint64_t is) {
    char line[1024];
    struct zip_stat st, ss;

    if (confirm & CONFIRM_ALL_YES)
	return 1;
    else if (confirm & CONFIRM_ALL_NO)
	return 0;

    if (zip_stat_index(za, it, ZIP_FL_UNCHANGED, &st) < 0) {
	fprintf(stderr, "%s: cannot stat file %" PRIu64 " in '%s': %s\n", prg, it, tname, zip_strerror(za));
	return -1;
    }
    if (zip_stat_index(zs, is, 0, &ss) < 0) {
	fprintf(stderr, "%s: cannot stat file %" PRIu64 " in '%s': %s\n", prg, is, sname, zip_strerror(zs));
	return -1;
    }

    if (st.size == ss.size && st.crc == ss.crc) {
	if (confirm & CONFIRM_SAME_YES)
	    return 1;
	else if (confirm & CONFIRM_SAME_NO)
	    return 0;
    }

    printf("replace '%s' (%" PRIu64 " / %08x) in `%s'\n"
	   "   with '%s' (%" PRIu64 " / %08x) from `%s'? ",
	   st.name, st.size, st.crc, tname, ss.name, ss.size, ss.crc, sname);
    fflush(stdout);

    if (fgets(line, sizeof(line), stdin) == NULL) {
	fprintf(stderr, "%s: read error from stdin: %s\n", prg, strerror(errno));
	return -1;
    }

    if (tolower((unsigned char)line[0]) == 'y')
	return 1;

    return 0;
}


static zip_t *
merge_zip(zip_t *za, const char *tname, const char *sname) {
    zip_t *zs;
    zip_source_t *source;
    zip_int64_t ret, idx;
    zip_uint64_t i;
    int err;
    const char *fname;

    if ((zs = zip_open(sname, 0, &err)) == NULL) {
	zip_error_t error;
	zip_error_init_with_code(&error, err);
	fprintf(stderr, "%s: can't open zip archive '%s': %s\n", prg, sname, zip_error_strerror(&error));
	zip_error_fini(&error);
	return NULL;
    }

    ret = zip_get_num_entries(zs, 0);
    if (ret < 0) {
	fprintf(stderr, "%s: cannot get number of entries for '%s': %s\n", prg, sname, zip_strerror(za));
	return NULL;
    }
    for (i = 0; i < (zip_uint64_t)ret; i++) {
	fname = zip_get_name(zs, i, 0);

	if ((idx = zip_name_locate(za, fname, name_flags)) >= 0) {
	    switch (confirm_replace(za, tname, (zip_uint64_t)idx, zs, sname, i)) {
	    case 0:
		break;

	    case 1:
		if ((source = zip_source_zip(za, zs, i, 0, 0, 0)) == NULL || zip_replace(za, (zip_uint64_t)idx, source) < 0) {
		    zip_source_free(source);
		    fprintf(stderr, "%s: cannot replace '%s' in `%s': %s\n", prg, fname, tname, zip_strerror(za));
		    zip_close(zs);
		    return NULL;
		}
		break;

	    case -1:
		zip_close(zs);
		return NULL;

	    default:
		fprintf(stderr,
			"%s: internal error: "
			"unexpected return code from confirm (%d)\n",
			prg, err);
		zip_close(zs);
		return NULL;
	    }
	}
	else {
	    if ((source = zip_source_zip(za, zs, i, 0, 0, 0)) == NULL || zip_add(za, fname, source) < 0) {
		zip_source_free(source);
		fprintf(stderr, "%s: cannot add '%s' to `%s': %s\n", prg, fname, tname, zip_strerror(za));
		zip_close(zs);
		return NULL;
	    }
	}
    }

    return zs;
}
