/*
  $NiH: zipmerge.c,v 1.10 2005/06/03 12:55:31 wiz 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 <unistd.h>

#include "config.h"
#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;
}
