/*
  $NiH: zipmerge.c,v 1.11 2005/06/09 19:57:10 dillo Exp $

  zipmerge.c -- merge zip archives
  Copyright (C) 2004, 2005 Dieter Baron and Thomas Klausner

  This file is part of libzip, a library to manipulate ZIP archives.
  The authors can be contacted at <nih@giga.or.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

#include "zip.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 <nih@giga.or.at>.\n";

char version_string[] = PROGRAM " (" PACKAGE " " VERSION ")\n\
Copyright (C) 2003 Dieter Baron and Thomas Klausner\n\
" PACKAGE " comes with ABSOLUTELY NO WARRANTY, to the extent permitted by law.\n\
You may redistribute copies of\n\
" PACKAGE " under the terms of the GNU General Public License.\n\
For more information about these matters, see the files named COPYING.\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;
int name_flags;

static int confirm_replace(struct zip *, const char *, int,
			   struct zip *, const char *, int);
static int merge_zip(struct zip *za, const char *, const char *);



int
main(int argc, char *argv[])
{
    struct zip *za;
    int c, err;
    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++];
    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);
    }

    while (optind<argc) {
	if (merge_zip(za, tname, argv[optind++]) < 0)
	    exit(1);
    }

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

    exit(0);
}



static int
confirm_replace(struct zip *za, const char *tname, int it,
		struct zip *zs, const char *sname, int 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 %d 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 %d 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' (%llu / %08x) in `%s'\n"
	   "   with `%s' (%llu / %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 int
merge_zip(struct zip *za, const char *tname, const char *sname)
{
    struct zip *zs;
    struct zip_source *source;
    int i, idx, 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 -1;
    }

    for (i=0; i<zip_get_num_files(zs); i++) {
	fname = zip_get_name(zs, i, 0);

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

	    case -1:
		return -1;
		
	    default:
		fprintf(stderr,	"%s: internal error: "
			"unexpected return code from confirm (%d)\n",
			prg, err);
		return -1;
	    }
	}
	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));
		return -1;
	    }
	}
    }

    return 0;
}
