Add API for getting/setting extra field data.

Doesn't parse the fields yet, just provides them to the library user.

Open points:
* cdir extra field entries are not changed
* heuristics for finding cdir should be adapted

Based on patch provided by Jono Spiro <jono.spiro@gmail.com> (with
minimal changes).

--HG--
branch : HEAD
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
index 29ba802..4d80b1e 100644
--- a/lib/CMakeLists.txt
+++ b/lib/CMakeLists.txt
@@ -85,6 +85,7 @@
   zip_get_compression_implementation.c
   zip_get_encryption_implementation.c
   zip_get_file_comment.c
+  zip_get_file_extra.c
   zip_get_name.c
   zip_get_num_files.c
   zip_memdup.c
@@ -97,6 +98,7 @@
   zip_set_archive_flag.c
   zip_set_default_password.c
   zip_set_file_comment.c
+  zip_set_file_extra.c
   zip_set_name.c
   zip_source_buffer.c
   zip_source_close.c
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 6faf4a1..b12e83c 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -42,6 +42,7 @@
 	zip_get_compression_implementation.c \
 	zip_get_encryption_implementation.c \
 	zip_get_file_comment.c \
+	zip_get_file_extra.c \
 	zip_get_num_files.c \
 	zip_get_name.c \
 	zip_memdup.c \
@@ -54,6 +55,7 @@
 	zip_set_archive_flag.c \
 	zip_set_default_password.c \
 	zip_set_file_comment.c \
+	zip_set_file_extra.c \
 	zip_source_buffer.c \
 	zip_source_close.c \
 	zip_source_crc.c \
diff --git a/lib/zip.h b/lib/zip.h
index 94ee69b..261e550 100644
--- a/lib/zip.h
+++ b/lib/zip.h
@@ -230,6 +230,8 @@
 ZIP_EXTERN int zip_get_archive_flag(struct zip *, int, int);
 ZIP_EXTERN const char *zip_get_file_comment(struct zip *, zip_uint64_t,
 					    int *, int);
+ZIP_EXTERN const char *zip_get_file_extra(struct zip *, zip_uint64_t,
+					  int *, int);
 ZIP_EXTERN const char *zip_get_name(struct zip *, zip_uint64_t, int);
 ZIP_EXTERN int zip_get_num_files(struct zip *);
 ZIP_EXTERN int zip_name_locate(struct zip *, const char *, int);
@@ -241,6 +243,8 @@
 ZIP_EXTERN int zip_set_default_password(struct zip *, const char *);
 ZIP_EXTERN int zip_set_file_comment(struct zip *, zip_uint64_t,
 				    const char *, int);
+ZIP_EXTERN int zip_set_file_extra(struct zip *, zip_uint64_t,
+				  const char *, int);
 ZIP_EXTERN struct zip_source *zip_source_buffer(struct zip *, const void *,
 						zip_uint64_t, int);
 ZIP_EXTERN struct zip_source *zip_source_file(struct zip *, const char *,
diff --git a/lib/zip_close.c b/lib/zip_close.c
index ded5345..6b7f8d2 100644
--- a/lib/zip_close.c
+++ b/lib/zip_close.c
@@ -217,6 +217,22 @@
 	    cd->entry[j].filename_len = de.filename_len;
 	}
 
+	if (za->entry[i].ch_extra_len != -1) {
+	    free(de.extrafield);
+	    if ((de.extrafield=malloc(za->entry[i].ch_extra_len)) == NULL) {
+		error = 1;
+		break;
+	    }
+	    memcpy(de.extrafield, za->entry[i].ch_extra, za->entry[i].ch_extra_len);
+	    de.extrafield_len = za->entry[i].ch_extra_len;
+	    /* as the rest of cd entries, its malloc/free is done by za */
+	    /* TODO unsure if this should also be set in the CD --
+	     * not done for now
+	    cd->entry[j].extrafield = za->entry[i].ch_extra;
+	    cd->entry[j].extrafield_len = za->entry[i].ch_extra_len;
+	    */
+	}
+
 	if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0) == 0
 	    && za->entry[i].ch_comment_len != -1) {
 	    /* as the rest of cd entries, its malloc/free is done by za */
@@ -557,6 +573,7 @@
 
     for (i=0; i<za->nentry; i++) {
 	if ((za->entry[i].state != ZIP_ST_UNCHANGED)
+	    || (za->entry[i].ch_extra_len != -1)
 	    || (za->entry[i].ch_comment_len != -1))
 	    changed = 1;
 	if (za->entry[i].state != ZIP_ST_DELETED)
diff --git a/lib/zip_entry_free.c b/lib/zip_entry_free.c
index c50c943..e8a7770 100644
--- a/lib/zip_entry_free.c
+++ b/lib/zip_entry_free.c
@@ -44,6 +44,9 @@
 {
     free(ze->ch_filename);
     ze->ch_filename = NULL;
+    free(ze->ch_extra);
+    ze->ch_extra = NULL;
+    ze->ch_extra_len = -1;
     free(ze->ch_comment);
     ze->ch_comment = NULL;
     ze->ch_comment_len = -1;
diff --git a/lib/zip_entry_new.c b/lib/zip_entry_new.c
index a22dd40..26d5c6a 100644
--- a/lib/zip_entry_new.c
+++ b/lib/zip_entry_new.c
@@ -67,6 +67,8 @@
     ze->state = ZIP_ST_UNCHANGED;
 
     ze->ch_filename = NULL;
+    ze->ch_extra = NULL;
+    ze->ch_extra_len = -1;
     ze->ch_comment = NULL;
     ze->ch_comment_len = -1;
     ze->source = NULL;
diff --git a/lib/zip_get_file_extra.c b/lib/zip_get_file_extra.c
new file mode 100644
index 0000000..afa507b
--- /dev/null
+++ b/lib/zip_get_file_extra.c
@@ -0,0 +1,58 @@
+/*
+  zip_get_file_extra.c -- get file extra field
+  Copyright (C) 2006-2010 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 "zipint.h"
+
+
+
+ZIP_EXTERN const char *
+zip_get_file_extra(struct zip *za, zip_uint64_t idx, int *lenp, int flags)
+{
+    if (idx >= za->nentry) {
+	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+	return NULL;
+    }
+
+    if ((flags & ZIP_FL_UNCHANGED)
+	|| (za->entry[idx].ch_extra_len == -1)) {
+	if (lenp != NULL)
+	    *lenp = za->cdir->entry[idx].extrafield_len;
+	return za->cdir->entry[idx].extrafield;
+    }
+
+    if (lenp != NULL)
+	*lenp = za->entry[idx].ch_extra_len;
+    return za->entry[idx].ch_extra;
+}
diff --git a/lib/zip_set_file_extra.c b/lib/zip_set_file_extra.c
new file mode 100644
index 0000000..9b80bde
--- /dev/null
+++ b/lib/zip_set_file_extra.c
@@ -0,0 +1,72 @@
+/*
+  zip_set_file_extra.c -- set extra field for file in archive
+  Copyright (C) 2006-2010 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 <stdlib.h>
+
+#include "zipint.h"
+
+
+
+ZIP_EXTERN int
+zip_set_file_extra(struct zip *za, zip_uint64_t idx,
+		   const char *extra, int len)
+{
+    char *tmpext;
+
+    if (idx >= za->nentry
+	|| len < 0 || len > MAXEXTLEN
+	|| (len > 0 && extra == NULL)) {
+	_zip_error_set(&za->error, ZIP_ER_INVAL, 0);
+	return -1;
+    }
+
+    if (ZIP_IS_RDONLY(za)) {
+	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+	return -1;
+    }
+
+    if (len > 0) {
+	if ((tmpext=(char *)_zip_memdup(extra, len, &za->error)) == NULL)
+	    return -1;
+    }
+    else
+	tmpext = NULL;
+
+    free(za->entry[idx].ch_extra);
+    za->entry[idx].ch_extra = tmpext;
+    za->entry[idx].ch_extra_len = len;
+
+    return 0;
+}
diff --git a/lib/zip_unchange.c b/lib/zip_unchange.c
index 58ec54b..e64186e 100644
--- a/lib/zip_unchange.c
+++ b/lib/zip_unchange.c
@@ -72,6 +72,9 @@
 	za->entry[idx].ch_filename = NULL;
     }
 
+    free(za->entry[idx].ch_extra);
+    za->entry[idx].ch_extra = NULL;
+    za->entry[idx].ch_extra_len = -1;
     free(za->entry[idx].ch_comment);
     za->entry[idx].ch_comment = NULL;
     za->entry[idx].ch_comment_len = -1;
diff --git a/lib/zipint.h b/lib/zipint.h
index 57304d2..e105461 100644
--- a/lib/zipint.h
+++ b/lib/zipint.h
@@ -103,6 +103,7 @@
 #define CDENTRYSIZE         46u
 #define LENTRYSIZE          30
 #define MAXCOMLEN        65536
+#define MAXEXTLEN        65536
 #define EOCDLEN             22
 #define CDBUFSIZE       (MAXCOMLEN+EOCDLEN)
 #define BUFSIZE		8192
@@ -275,6 +276,8 @@
     enum zip_state state;
     struct zip_source *source;
     char *ch_filename;
+    char *ch_extra;
+    int ch_extra_len;
     char *ch_comment;
     int ch_comment_len;
 };
diff --git a/man/CMakeLists.txt b/man/CMakeLists.txt
index 8285eca..2f9f728 100644
--- a/man/CMakeLists.txt
+++ b/man/CMakeLists.txt
@@ -18,6 +18,7 @@
   zip_get_archive_comment.mdoc
   zip_get_archive_flag.mdoc
   zip_get_file_comment.mdoc
+  zip_get_file_extra.mdoc
   zip_get_name.mdoc
   zip_get_num_files.mdoc
   zip_name_locate.mdoc
@@ -27,6 +28,7 @@
   zip_set_archive_flag.mdoc
   zip_set_default_password.mdoc
   zip_set_file_comment.mdoc
+  zip_set_file_extra.mdoc
   zip_source_buffer.mdoc
   zip_source_file.mdoc
   zip_source_filep.mdoc
diff --git a/man/Makefile.am b/man/Makefile.am
index e9f5462..ef23a69 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -25,6 +25,7 @@
 	zip_get_archive_comment.mdoc \
 	zip_get_archive_flag.mdoc \
 	zip_get_file_comment.mdoc \
+        zip_get_file_extra.mdoc \
 	zip_get_name.mdoc \
 	zip_get_num_files.mdoc \
 	zip_name_locate.mdoc \
@@ -34,6 +35,7 @@
 	zip_set_archive_flag.mdoc \
 	zip_set_default_password.mdoc \
 	zip_set_file_comment.mdoc \
+        zip_set_file_extra.mdoc \
 	zip_source_buffer.mdoc \
 	zip_source_file.mdoc \
 	zip_source_filep.mdoc \
diff --git a/man/zip_get_file_extra.man b/man/zip_get_file_extra.man
new file mode 100644
index 0000000..b767b47
--- /dev/null
+++ b/man/zip_get_file_extra.man
@@ -0,0 +1,90 @@
+.\" zip_get_file_extra.mdoc \-- get extra field for file in zip
+.\" Copyright (C) 2006-2011 Dieter Baron and Thomas Klausner
+.\"
+.\" This file is part of libzip, a library to manipulate ZIP files.
+.\" 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.
+.\"
+.TH ZIP_GET_FILE_EXTRA 3 "February 13, 2011" NiH
+.SH "NAME"
+zip_get_file_extra \- get extra field for file in zip
+.SH "LIBRARY"
+libzip (-lzip)
+.SH "SYNOPSIS"
+#include <zip.h>
+.PP
+const char *
+zip_get_file_extra(struct zip *archive, zip_uint64_t index); \
+"int *lenp" "int flags"
+.SH "DESCRIPTION"
+The
+zip_get_file_extra
+function returns the extra field for the file at position
+\fBindex\fR
+in the zip archive.
+This pointer should not be modified or
+free(3)
+Ap d.
+If
+\fBlenp\fR
+is not
+\fBNULL,\fR
+the integer to which it points will be set to the length of the
+extra.
+If
+\fBflags\fR
+is set to
+\fBZIP_FL_UNCHANGED,\fR
+the original unchanged extra field is returned.
+.SH "RETURN VALUES"
+Upon successful completion, a pointer to the extra field is returned,
+or
+\fBNULL\fR
+if there is no extra field.
+In case of an error,
+\fBNULL\fR
+is returned and the error code in
+\fBarchive\fR
+is set to indicate the error.
+.SH "ERRORS"
+zip_get_file_extra
+fails if:
+.RS
+.TP 4
+[ZIP_ER_INVAL]
+\fBindex\fR
+is not a valid file index in
+\fBarchive.\fR
+.RE
+.SH "SEE ALSO"
+libzip(3),
+zip_set_file_extra(3)
+.SH "AUTHORS"
+
+Dieter Baron <dillo@giga.or.at>
+and
+Thomas Klausner <tk@giga.or.at>
diff --git a/man/zip_get_file_extra.mdoc b/man/zip_get_file_extra.mdoc
new file mode 100644
index 0000000..bf6e49e
--- /dev/null
+++ b/man/zip_get_file_extra.mdoc
@@ -0,0 +1,90 @@
+.\" zip_get_file_extra.mdoc -- get extra field for file in zip
+.\" Copyright (C) 2006-2011 Dieter Baron and Thomas Klausner
+.\"
+.\" This file is part of libzip, a library to manipulate ZIP files.
+.\" 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.
+.\"
+.Dd February 13, 2011
+.Dt ZIP_GET_FILE_EXTRA 3
+.Os
+.Sh NAME
+.Nm zip_get_file_extra
+.Nd get extra field for file in zip
+.Sh LIBRARY
+libzip (-lzip)
+.Sh SYNOPSIS
+.In zip.h
+.Ft const char *
+.Fn zip_get_file_extra "struct zip *archive" "zip_uint64_t index" \
+"int *lenp" "int flags"
+.Sh DESCRIPTION
+The
+.Fn zip_get_file_extra
+function returns the extra field for the file at position
+.Ar index
+in the zip archive.
+This pointer should not be modified or
+.Xr free 3 Ap d .
+If
+.Ar lenp
+is not
+.Dv NULL ,
+the integer to which it points will be set to the length of the
+extra.
+If
+.Ar flags
+is set to
+.Dv ZIP_FL_UNCHANGED ,
+the original unchanged extra field is returned.
+.Sh RETURN VALUES
+Upon successful completion, a pointer to the extra field is returned,
+or
+.Dv NULL
+if there is no extra field.
+In case of an error,
+.Dv NULL
+is returned and the error code in
+.Ar archive
+is set to indicate the error.
+.Sh ERRORS
+.Fn zip_get_file_extra
+fails if:
+.Bl -tag -width Er
+.It Bq Er ZIP_ER_INVAL
+.Ar index
+is not a valid file index in
+.Ar archive .
+.El
+.Sh SEE ALSO
+.Xr libzip 3 ,
+.Xr zip_set_file_extra 3
+.Sh AUTHORS
+.An -nosplit
+.An Dieter Baron Aq dillo@giga.or.at
+and
+.An Thomas Klausner Aq tk@giga.or.at
diff --git a/man/zip_set_file_extra.man b/man/zip_set_file_extra.man
new file mode 100644
index 0000000..7298c1a
--- /dev/null
+++ b/man/zip_set_file_extra.man
@@ -0,0 +1,88 @@
+.\" zip_set_file_extra.mdoc \-- set extra field for file in zip
+.\" Copyright (C) 2006-2011 Dieter Baron and Thomas Klausner
+.\"
+.\" This file is part of libzip, a library to manipulate ZIP files.
+.\" 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.
+.\"
+.TH ZIP_SET_FILE_EXTRA 3 "February 13, 2011" NiH
+.SH "NAME"
+zip_set_file_extra \- set extra field for file in zip
+.SH "LIBRARY"
+libzip (-lzip)
+.SH "SYNOPSIS"
+#include <zip.h>
+.PP
+int
+zip_set_file_extra(struct zip *archive, zip_uint64_t index); \
+"const char *extra" "int len"
+.SH "DESCRIPTION"
+The
+zip_set_file_extra
+function sets the extra field for the file at position
+\fBindex\fR
+in the zip archive to
+\fBextra\fR
+of length
+\fBlen.\fR
+If
+\fBextra\fR
+is
+\fBNULL\fR
+and
+\fBlen\fR
+is 0, the file extra field will be removed.
+.SH "RETURN VALUES"
+Upon successful completion 0 is returned.
+Otherwise, \-1 is returned and the error information in
+\fBarchive\fR
+is set to indicate the error.
+.SH "ERRORS"
+zip_set_file_extra
+fails if:
+.RS
+.TP 4
+[ZIP_ER_INVAL]
+\fBindex\fR
+is not a valid file index in
+\fBarchive,\fR
+or
+\fBlen\fR
+is less than 0 or longer than the maximum extra field length in a zip file
+(65535).
+.TP 4
+[ZIP_ER_MEMORY]
+Required memory could not be allocated.
+.RE
+.SH "SEE ALSO"
+libzip(3),
+zip_get_file_extra(3)
+.SH "AUTHORS"
+
+Dieter Baron <dillo@giga.or.at>
+and
+Thomas Klausner <tk@giga.or.at>
diff --git a/man/zip_set_file_extra.mdoc b/man/zip_set_file_extra.mdoc
new file mode 100644
index 0000000..d54a14c
--- /dev/null
+++ b/man/zip_set_file_extra.mdoc
@@ -0,0 +1,88 @@
+.\" zip_set_file_extra.mdoc -- set extra field for file in zip
+.\" Copyright (C) 2006-2011 Dieter Baron and Thomas Klausner
+.\"
+.\" This file is part of libzip, a library to manipulate ZIP files.
+.\" 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.
+.\"
+.Dd February 13, 2011
+.Dt ZIP_SET_FILE_EXTRA 3
+.Os
+.Sh NAME
+.Nm zip_set_file_extra
+.Nd set extra field for file in zip
+.Sh LIBRARY
+libzip (-lzip)
+.Sh SYNOPSIS
+.In zip.h
+.Ft int
+.Fn zip_set_file_extra "struct zip *archive" "zip_uint64_t index" \
+"const char *extra" "int len"
+.Sh DESCRIPTION
+The
+.Fn zip_set_file_extra
+function sets the extra field for the file at position
+.Ar index
+in the zip archive to
+.Ar extra
+of length
+.Ar len .
+If
+.Ar extra
+is
+.Dv NULL
+and
+.Ar len
+is 0, the file extra field will be removed.
+.Sh RETURN VALUES
+Upon successful completion 0 is returned.
+Otherwise, \-1 is returned and the error information in
+.Ar archive
+is set to indicate the error.
+.Sh ERRORS
+.Fn zip_set_file_extra
+fails if:
+.Bl -tag -width Er
+.It Bq Er ZIP_ER_INVAL
+.Ar index
+is not a valid file index in
+.Ar archive ,
+or
+.Ar len
+is less than 0 or longer than the maximum extra field length in a zip file
+(65535).
+.It Bq Er ZIP_ER_MEMORY
+Required memory could not be allocated.
+.El
+.Sh SEE ALSO
+.Xr libzip 3 ,
+.Xr zip_get_file_extra 3
+.Sh AUTHORS
+.An -nosplit
+.An Dieter Baron Aq dillo@giga.or.at
+and
+.An Thomas Klausner Aq tk@giga.or.at