* lib/zip_get_name.c (zip_get_name): add flags argument.
	(_zip_get_name): new function.
	* lib/zip_uncange.c (zip_unchange): return error if unchanging
	name would result in duplicate name in archive.

--HG--
branch : HEAD
diff --git a/lib/zip.h b/lib/zip.h
index 49f382d..c574351 100644
--- a/lib/zip.h
+++ b/lib/zip.h
@@ -2,7 +2,7 @@
 #define _HAD_ZIP_H
 
 /*
-  $NiH: zip.h,v 1.43 2004/11/18 17:26:51 wiz Exp $
+  $NiH: zip.h,v 1.44 2004/11/30 21:51:29 wiz Exp $
 
   zip.h -- exported declarations.
   Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -146,7 +146,7 @@
 struct zip_file *zip_fopen(struct zip *, const char *, int);
 struct zip_file *zip_fopen_index(struct zip *, int, int);
 ssize_t zip_fread(struct zip_file *, void *, size_t);
-const char *zip_get_name(struct zip *, int);
+const char *zip_get_name(struct zip *, int, int);
 int zip_get_num_files(struct zip *);
 int zip_name_locate(struct zip *, const char *, int);
 struct zip *zip_open(const char *, int, int *);
diff --git a/lib/zip_get_name.c b/lib/zip_get_name.c
index 293eb3e..1dfd8e7 100644
--- a/lib/zip_get_name.c
+++ b/lib/zip_get_name.c
@@ -1,5 +1,5 @@
 /*
-  $NiH: zip_get_name.c,v 1.10 2004/11/18 17:11:21 wiz Exp $
+  $NiH: zip_get_name.c,v 1.11 2004/11/30 22:19:37 wiz Exp $
 
   zip_get_name.c -- get filename for a file in zip file
   Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -41,19 +41,28 @@
 
 
 const char *
-zip_get_name(struct zip *za, int idx)
+zip_get_name(struct zip *za, int idx, int flags)
+{
+    return _zip_get_name(za, idx, flags, &za->error);
+}
+
+
+
+const char *
+_zip_get_name(struct zip *za, int idx, int flags, struct zip_error *error)
 {
     if (idx < 0 || idx >= za->nentry) {
-	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+	_zip_error_set(error, ZIP_ER_INVAL, 0);
 	return NULL;
     }
 
-    if (za->entry[idx].ch_filename)
+    if ((flags & ZIP_FL_UNCHANGED) == 0 && za->entry[idx].ch_filename)
 	return za->entry[idx].ch_filename;
 
-    /* newly added (partially filled) entry */
-    if (za->cdir == NULL || idx >= za->cdir->nentry)
+    if (za->cdir == NULL || idx >= za->cdir->nentry) {
+	_zip_error_set(error, ZIP_ER_INVAL, 0);
 	return NULL;
+    }
     
     return za->cdir->entry[idx].filename;
 }
diff --git a/lib/zip_name_locate.c b/lib/zip_name_locate.c
index cc8bbc3..006d17e 100644
--- a/lib/zip_name_locate.c
+++ b/lib/zip_name_locate.c
@@ -1,5 +1,5 @@
 /*
-  $NiH: zip_name_locate.c,v 1.15 2004/11/18 15:04:05 wiz Exp $
+  $NiH: zip_name_locate.c,v 1.16 2004/11/30 22:19:37 wiz Exp $
 
   zip_name_locate.c -- get index by name
   Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -45,30 +45,24 @@
 int
 zip_name_locate(struct zip *za, const char *fname, int flags)
 {
-    int i;
-    
-    if (fname == NULL) {
-	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
-	return -1;
-    }
-    
-    i = _zip_name_locate(za, fname, flags);
-
-    if (i == -1)
-	_zip_error_set(&za->error, ZIP_ER_NOENT, 0);
-
-    return i;
+    return _zip_name_locate(za, fname, flags, &za->error);
 }
 
 
 
 int
-_zip_name_locate(struct zip *za, const char *fname, int flags)
+_zip_name_locate(struct zip *za, const char *fname, int flags,
+		 struct zip_error *error)
 {
     int (*cmp)(const char *, const char *);
     const char *fn, *p, *q;
     int i, n;
 
+    if (fname == NULL) {
+	_zip_error_set(error, ZIP_ER_INVAL, 0);
+	return -1;
+    }
+    
     cmp = (flags & ZIP_FL_NOCASE) ? strcasecmp : strcmp;
 
     n = (flags & ZIP_FL_UNCHANGED) ? za->cdir->nentry : za->nentry;
@@ -76,7 +70,7 @@
 	if (flags & ZIP_FL_UNCHANGED)
 	    fn = za->cdir->entry[i].filename;
 	else
-	    fn = zip_get_name(za, i);
+	    fn = _zip_get_name(za, i, flags, error);
 
 	/* newly added (partially filled) entry */
 	if (fn == NULL)
@@ -98,5 +92,6 @@
 	    return i;
     }
 
+    _zip_error_set(error, ZIP_ER_NOENT, 0);
     return -1;
 }
diff --git a/lib/zip_set_name.c b/lib/zip_set_name.c
index d0bf1a5..38faabe 100644
--- a/lib/zip_set_name.c
+++ b/lib/zip_set_name.c
@@ -1,5 +1,5 @@
 /*
-  $NiH: zip_set_name.c,v 1.14 2004/11/18 17:11:22 wiz Exp $
+  $NiH: zip_set_name.c,v 1.15 2004/11/30 22:19:38 wiz Exp $
 
   zip_set_name.c -- rename helper function
   Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -46,17 +46,22 @@
 _zip_set_name(struct zip *za, int idx, const char *name)
 {
     char *s;
+    int i;
     
     if (idx < 0 || idx >= za->nentry || name == NULL) {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return -1;
     }
 
-    if (_zip_name_locate(za, name, 0) != -1) {
+    if ((i=_zip_name_locate(za, name, 0, NULL)) != -1 && i != idx) {
 	_zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
 	return -1;
     }
 
+    /* no effective name change */
+    if (i == idx)
+	return 0;
+    
     if ((s=strdup(name)) == NULL) {
 	_zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
 	return -1;
diff --git a/lib/zip_stat_index.c b/lib/zip_stat_index.c
index 86d897d..06d5b74 100644
--- a/lib/zip_stat_index.c
+++ b/lib/zip_stat_index.c
@@ -1,5 +1,5 @@
 /*
-  $NiH: zip_stat_index.c,v 1.5 2004/11/17 21:55:14 wiz Exp $
+  $NiH: zip_stat_index.c,v 1.6 2004/11/18 15:04:05 wiz Exp $
 
   zip_stat_index.c -- get information about file by index
   Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -43,11 +43,17 @@
 int
 zip_stat_index(struct zip *za, int index, int flags, struct zip_stat *st)
 {
+    const char *name;
+    
     if (index < 0 || index >= za->nentry) {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return -1;
     }
 
+    if ((name=zip_get_name(za, index, flags)) == NULL)
+	return -1;
+    
+
     if ((flags & ZIP_FL_UNCHANGED) == 0
 	&& ZIP_ENTRY_DATA_CHANGED(za->entry+index)) {
 	if (za->entry[index].source->f(za->entry[index].source->ud,
@@ -57,7 +63,7 @@
 	}
     }
     else {
-	if (index >= za->cdir->nentry) {
+	if (za->cdir == NULL || index >= za->cdir->nentry) {
 	    _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	    return -1;
 	}
@@ -71,10 +77,7 @@
 	/* st->bitflags = za->cdir->entry[index].bitflags; */
     }
 
-    if (flags & ZIP_FL_UNCHANGED)
-	st->name = za->cdir->entry[index].filename;
-    else
-	st->name = zip_get_name(za, index);
-
+    st->name = name;
+    
     return 0;
 }
diff --git a/lib/zip_unchange.c b/lib/zip_unchange.c
index 412f431..35b8883 100644
--- a/lib/zip_unchange.c
+++ b/lib/zip_unchange.c
@@ -1,5 +1,5 @@
 /*
-  $NiH: zip_unchange.c,v 1.15 2004/11/18 15:04:05 wiz Exp $
+  $NiH: zip_unchange.c,v 1.16 2004/11/18 17:11:22 wiz Exp $
 
   zip_unchange.c -- undo changes to file in zip archive
   Copyright (C) 1999, 2004 Dieter Baron and Thomas Klausner
@@ -44,12 +44,32 @@
 int
 zip_unchange(struct zip *za, int idx)
 {
+    return _zip_unchange(za, idx, 0);
+}
+
+
+
+int
+_zip_unchange(struct zip *za, int idx, int allow_duplicates)
+{
+    int i;
+    
     if (!za || idx < 0 || idx >= za->nentry) {
 	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
 	return -1;
     }
 
     if (za->entry[idx].ch_filename) {
+	if (!allow_duplicates) {
+	    i = _zip_name_locate(za,
+			 _zip_get_name(za, idx, ZIP_FL_UNCHANGED, NULL),
+				 0, NULL);
+	    if (i != -1 && i != idx) {
+		_zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
+		return -1;
+	    }
+	}
+
 	free(za->entry[idx].ch_filename);
 	za->entry[idx].ch_filename = NULL;
     }
diff --git a/lib/zip_unchange_all.c b/lib/zip_unchange_all.c
index fba406d..3678d4f 100644
--- a/lib/zip_unchange_all.c
+++ b/lib/zip_unchange_all.c
@@ -1,5 +1,5 @@
 /*
-  $NiH: zip_unchange_all.c,v 1.5 2003/10/03 08:34:11 dillo Exp $
+  $NiH: zip_unchange_all.c,v 1.6 2003/10/06 16:37:41 dillo Exp $
 
   zip_unchange.c -- undo changes to all files in zip archive
   Copyright (C) 1999 Dieter Baron and Thomas Klausner
@@ -48,7 +48,7 @@
 
     ret = 0;
     for (i=0; i<za->nentry; i++)
-	ret |= zip_unchange(za, i);
+	ret |= _zip_unchange(za, i, 1);
         
     return ret;
 }
diff --git a/lib/zip_unchange_data.c b/lib/zip_unchange_data.c
index 404310c..6a45074 100644
--- a/lib/zip_unchange_data.c
+++ b/lib/zip_unchange_data.c
@@ -1,5 +1,5 @@
 /*
-  $NiH: zip_unchange_data.c,v 1.12 2004/06/24 15:01:58 dillo Exp $
+  $NiH: zip_unchange_data.c,v 1.13 2004/11/18 15:04:06 wiz Exp $
 
   zip_unchange_data.c -- undo helper function
   Copyright (C) 1999, 2004 Dieter Baron and Thomas Klausner
@@ -36,7 +36,7 @@
 
 
 #include <stdlib.h>
-#include "zip.h"
+
 #include "zipint.h"
 
 void
diff --git a/lib/zipint.h b/lib/zipint.h
index 79efc00..9072c8e 100644
--- a/lib/zipint.h
+++ b/lib/zipint.h
@@ -2,7 +2,7 @@
 #define _HAD_ZIPINT_H
 
 /*
-  $NiH: zipint.h,v 1.33 2004/11/30 21:51:30 wiz Exp $
+  $NiH: zipint.h,v 1.34 2004/11/30 22:19:38 wiz Exp $
 
   zipint.h -- internal declarations.
   Copyright (C) 1999, 2003, 2004 Dieter Baron and Thomas Klausner
@@ -197,14 +197,16 @@
 unsigned int _zip_file_get_offset(struct zip *, int);
 
 void _zip_free(struct zip *);
+const char *_zip_get_name(struct zip *, int, int, struct zip_error *);
 int _zip_local_header_read(struct zip *, int);
 void *_zip_memdup(const void *, int);
-int _zip_name_locate(struct zip *, const char *, int);
+int _zip_name_locate(struct zip *, const char *, int, struct zip_error *);
 struct zip *_zip_new(struct zip_error *);
 unsigned short _zip_read2(unsigned char **);
 unsigned int _zip_read4(unsigned char **);
 int _zip_replace(struct zip *, int, const char *, struct zip_source *);
 int _zip_set_name(struct zip *, int, const char *);
+int _zip_unchange(struct zip *, int, int);
 void _zip_unchange_data(struct zip_entry *);
 
 #endif /* zipint.h */