/*
  zipmerge.c -- merge zip archives
  Copyright (C) 2004-2012 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 "zip.h"
#include "compat.h"


char *prg;

#define PROGRAM	"zipmerge"

char *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) 2012 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(struct zip *, const char *, zip_uint64_t,
			   struct zip *, const char *, zip_uint64_t);
static struct zip *merge_zip(struct zip *, const char *, const char *);



int
main(int argc, char *argv[])
{
    struct zip *za;
    struct zip **zs;
    int c, err;
    unsigned int i, n;
    char errstr[1024], *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=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_to_str(errstr, sizeof(errstr), err, errno);
	fprintf(stderr, "%s: cannot open zip archive `%s': %s\n",
		prg, tname, errstr);
	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(struct zip *za, const char *tname, zip_uint64_t it,
		struct zip *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 struct zip *
merge_zip(struct zip *za, const char *tname, const char *sname)
{
    struct zip *zs;
    struct zip_source *source;
    zip_int64_t ret, idx;
    zip_uint64_t i;
    int err;
    char errstr[1024];
    const char *fname;
    
    if ((zs=zip_open(sname, 0, &err)) == NULL) {
	zip_error_to_str(errstr, sizeof(errstr), err, errno);
	fprintf(stderr, "%s: cannot open zip archive `%s': %s\n",
		prg, sname, errstr);
	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;
}
