Support setting and querying opsys and external attributes.

For newly added files, set operating system to UNIX, permissions
to 0666 (0777 for directories).
diff --git a/NEWS b/NEWS
index 2c0aab2..08a1a97 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,9 @@
+0.xx [XXXX/XX/XX]
+
+* Support querying/setting operating system and external attributes.
+* For newly added files, set operating system to UNIX, permissions
+  to 0666 (0777 for directories).
+
 0.11.1 [2013/04/27]
 
 * Fix bugs in zip_set_file_compression().
diff --git a/TODO b/TODO
index 499467f..61b3e27 100644
--- a/TODO
+++ b/TODO
@@ -13,15 +13,6 @@
 * zip_set_archive_prefix(struct zip *za, const zip_uint8_t *data, zip_uint64_t length);
 * const zip_uint8_t *zip_get_archive_prefix(struct zip *za, zip_uint64_t *lengthp);
 
-External Attributes
--------------------
-int zip_file_get_external_attributes(struct zip *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t *opsys, zip_uint32_t *attributes);
-int zip_file_set_external_attributes(struct zip *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t opsys, zip_uint32_t attributes);
-* clean up setting version-made-by
-* define operating systems
-#define ZIP_OPSYS_DOS 0u
-...
-
 API Issues
 ==========
 ! D zip_get_archive_comment has int *lenp argument.  Cleaner would be zip_uint32_t *.
@@ -52,6 +43,7 @@
 * zip_source_seek, zip_fseek
 * zipcmp: add option for file content comparison
 * zipcmp: compare bit flags if paranoid
+* zipcmp: compare external attributes/opsys if paranoid
 * consistency
   . for stored files, test compressed = uncompressed
   . data descriptor
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 5575752..a74f409 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -35,10 +35,12 @@
 	zip_file_error_clear.c \
 	zip_file_error_get.c \
 	zip_file_get_comment.c \
+	zip_file_get_external_attributes.c \
 	zip_file_get_offset.c \
 	zip_file_rename.c \
 	zip_file_replace.c \
 	zip_file_set_comment.c \
+	zip_file_set_external_attributes.c \
 	zip_file_strerror.c \
 	zip_filerange_crc.c \
 	zip_fopen.c \
diff --git a/lib/zip.h b/lib/zip.h
index 44d0ab8..d9a2b6c 100644
--- a/lib/zip.h
+++ b/lib/zip.h
@@ -177,6 +177,29 @@
 #endif
 #define ZIP_EM_UNKNOWN    0xffff  /* unknown algorithm */
 
+#define ZIP_OPSYS_DOS	  	0x00u
+#define ZIP_OPSYS_AMIGA	 	0x01u
+#define ZIP_OPSYS_OPENVMS	0x02u
+#define ZIP_OPSYS_UNIX	  	0x03u
+#define ZIP_OPSYS_VM_CMS	0x04u
+#define ZIP_OPSYS_ATARI_ST	0x05u
+#define ZIP_OPSYS_OS_2		0x06u
+#define ZIP_OPSYS_MACINTOSH	0x07u
+#define ZIP_OPSYS_Z_SYSTEM	0x08u
+#define ZIP_OPSYS_CPM	  	0x09u
+#define ZIP_OPSYS_WINDOWS_NTFS	0x0au
+#define ZIP_OPSYS_MVS	  	0x0bu
+#define ZIP_OPSYS_VSE	  	0x0cu
+#define ZIP_OPSYS_ACORN_RISC	0x0du
+#define ZIP_OPSYS_VFAT	  	0x0eu
+#define ZIP_OPSYS_ALTERNATE_MVS	0x0fu
+#define ZIP_OPSYS_BEOS	  	0x10u
+#define ZIP_OPSYS_TANDEM	0x11u
+#define ZIP_OPSYS_OS_400	0x12u
+#define ZIP_OPSYS_OS_X	  	0x13u
+
+#define ZIP_OPSYS_DEFAULT	ZIP_OPSYS_UNIX
+
 
 
 enum zip_source_cmd {
@@ -235,21 +258,32 @@
 #endif
 
 ZIP_EXTERN int zip_archive_set_tempdir(struct zip *, const char *);
-ZIP_EXTERN zip_int64_t zip_file_add(struct zip *, const char *, struct zip_source *, zip_flags_t);
-ZIP_EXTERN zip_int64_t zip_dir_add(struct zip *, const char *, zip_flags_t);
 ZIP_EXTERN int zip_close(struct zip *);
-ZIP_EXTERN void zip_discard(struct zip *);
 ZIP_EXTERN int zip_delete(struct zip *, zip_uint64_t);
-ZIP_EXTERN int zip_file_extra_field_delete(struct zip *, zip_uint64_t, zip_uint16_t, zip_flags_t);
-ZIP_EXTERN int zip_file_extra_field_delete_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN zip_int64_t zip_dir_add(struct zip *, const char *, zip_flags_t);
+ZIP_EXTERN void zip_discard(struct zip *);
 ZIP_EXTERN void zip_error_clear(struct zip *);
 ZIP_EXTERN void zip_error_get(struct zip *, int *, int *);
 ZIP_EXTERN int zip_error_get_sys_type(int);
 ZIP_EXTERN int zip_error_to_str(char *, zip_uint64_t, int, int);
 ZIP_EXTERN int zip_fclose(struct zip_file *);
 ZIP_EXTERN struct zip *zip_fdopen(int, int, int *);
+ZIP_EXTERN zip_int64_t zip_file_add(struct zip *, const char *, struct zip_source *, zip_flags_t);
 ZIP_EXTERN void zip_file_error_clear(struct zip_file *);
 ZIP_EXTERN void zip_file_error_get(struct zip_file *, int *, int *);
+ZIP_EXTERN int zip_file_extra_field_delete(struct zip *, zip_uint64_t, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN int zip_file_extra_field_delete_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN int zip_file_extra_field_set(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(struct zip *, zip_uint64_t, zip_flags_t);
+ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t *, zip_uint16_t *, zip_flags_t);
+ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *, zip_flags_t);
+ZIP_EXTERN const char *zip_file_get_comment(struct zip *, zip_uint64_t, zip_uint32_t *, zip_flags_t);
+ZIP_EXTERN int zip_file_get_external_attributes(struct zip *, zip_uint64_t, zip_flags_t, zip_uint8_t *, zip_uint32_t *);
+ZIP_EXTERN int zip_file_rename(struct zip *, zip_uint64_t, const char *, zip_flags_t);
+ZIP_EXTERN int zip_file_replace(struct zip *, zip_uint64_t, struct zip_source *, zip_flags_t);
+ZIP_EXTERN int zip_file_set_comment(struct zip *, zip_uint64_t, const char *, zip_uint16_t, zip_flags_t);
+ZIP_EXTERN int zip_file_set_external_attributes(struct zip *, zip_uint64_t, zip_flags_t, zip_uint8_t, zip_uint32_t);
 ZIP_EXTERN const char *zip_file_strerror(struct zip_file *);
 ZIP_EXTERN struct zip_file *zip_fopen(struct zip *, const char *, zip_flags_t);
 ZIP_EXTERN struct zip_file *zip_fopen_encrypted(struct zip *, const char *, zip_flags_t, const char *);
@@ -258,23 +292,14 @@
 ZIP_EXTERN zip_int64_t zip_fread(struct zip_file *, void *, zip_uint64_t);
 ZIP_EXTERN const char *zip_get_archive_comment(struct zip *, int *, zip_flags_t);
 ZIP_EXTERN int zip_get_archive_flag(struct zip *, zip_flags_t, zip_flags_t);
-ZIP_EXTERN const char *zip_file_get_comment(struct zip *, zip_uint64_t, zip_uint32_t *, zip_flags_t);
-ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t *, zip_uint16_t *, zip_flags_t);
-ZIP_EXTERN const zip_uint8_t *zip_file_extra_field_get_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *, zip_flags_t);
-ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(struct zip *, zip_uint64_t, zip_flags_t);
-ZIP_EXTERN zip_int16_t zip_file_extra_fields_count_by_id(struct zip *, zip_uint64_t, zip_uint16_t, zip_flags_t);
 ZIP_EXTERN const char *zip_get_name(struct zip *, zip_uint64_t, zip_flags_t);
 ZIP_EXTERN zip_int64_t zip_get_num_entries(struct zip *, zip_flags_t);
 ZIP_EXTERN zip_int64_t zip_name_locate(struct zip *, const char *, zip_flags_t);
 ZIP_EXTERN struct zip *zip_open(const char *, int, int *);
-ZIP_EXTERN int zip_file_rename(struct zip *, zip_uint64_t, const char *, zip_flags_t);
-ZIP_EXTERN int zip_file_replace(struct zip *, zip_uint64_t, struct zip_source *, zip_flags_t);
 ZIP_EXTERN int zip_set_archive_comment(struct zip *, const char *, zip_uint16_t);
 ZIP_EXTERN int zip_set_archive_flag(struct zip *, zip_flags_t, int);
 ZIP_EXTERN int zip_set_default_password(struct zip *, const char *);
-ZIP_EXTERN int zip_file_set_comment(struct zip *, zip_uint64_t, const char *, zip_uint16_t, zip_flags_t);
 ZIP_EXTERN int zip_set_file_compression(struct zip *, zip_uint64_t, zip_int32_t, zip_uint32_t);
-ZIP_EXTERN int zip_file_extra_field_set(struct zip *, zip_uint64_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_uint16_t, zip_flags_t);
 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 *, zip_uint64_t, zip_int64_t);
 ZIP_EXTERN struct zip_source *zip_source_filep(struct zip *, FILE *, zip_uint64_t, zip_int64_t);
diff --git a/lib/zip_dir_add.c b/lib/zip_dir_add.c
index 0a74bd6..1a662f4 100644
--- a/lib/zip_dir_add.c
+++ b/lib/zip_dir_add.c
@@ -1,6 +1,6 @@
 /*
   zip_dir_add.c -- add directory
-  Copyright (C) 1999-2012 Dieter Baron and Thomas Klausner
+  Copyright (C) 1999-2013 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>
@@ -46,7 +46,7 @@
 zip_dir_add(struct zip *za, const char *name, zip_flags_t flags)
 {
     size_t len;
-    zip_int64_t ret;
+    zip_int64_t idx;
     char *s;
     struct zip_source *source;
 
@@ -78,11 +78,18 @@
 	return -1;
     }
 	
-    ret = _zip_file_replace(za, ZIP_UINT64_MAX, s ? s : name, source, flags);
+    idx = _zip_file_replace(za, ZIP_UINT64_MAX, s ? s : name, source, flags);
 
     free(s);
-    if (ret < 0)
-	zip_source_free(source);
 
-    return ret;
+    if (idx < 0)
+	zip_source_free(source);
+    else {
+	if (zip_file_set_external_attributes(za, (zip_uint64_t)idx, 0, ZIP_OPSYS_DEFAULT, ZIP_EXT_ATTRIB_DEFAULT_DIR) < 0) {
+	    zip_delete(za, (zip_uint64_t)idx);
+	    return -1;
+	}
+    }
+
+    return idx;
 }
diff --git a/lib/zip_dirent.c b/lib/zip_dirent.c
index 99573a9..77069ae 100644
--- a/lib/zip_dirent.c
+++ b/lib/zip_dirent.c
@@ -260,7 +260,7 @@
     de->local_extra_fields_read = 0;
     de->cloned = 0;
 
-    de->version_madeby = 20;
+    de->version_madeby = 20 | (ZIP_OPSYS_DEFAULT << 8);
     de->version_needed = 20; /* 2.0 */
     de->bitflags = 0;
     de->comp_method = ZIP_CM_DEFAULT;
@@ -273,7 +273,7 @@
     de->comment = NULL;
     de->disk_number = 0;
     de->int_attrib = 0;
-    de->ext_attrib = 0;
+    de->ext_attrib = ZIP_EXT_ATTRIB_DEFAULT;
     de->offset = 0;
 }
 
diff --git a/lib/zip_file_get_external_attributes.c b/lib/zip_file_get_external_attributes.c
new file mode 100644
index 0000000..f1ad66a
--- /dev/null
+++ b/lib/zip_file_get_external_attributes.c
@@ -0,0 +1,53 @@
+/*
+  zip_file_get_external_attributes.c -- get opsys/external attributes
+  Copyright (C) 2013 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"
+
+int
+zip_file_get_external_attributes(struct zip *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t *opsys, zip_uint32_t *attributes)
+{
+    struct zip_dirent *de;
+    zip_uint32_t len;
+    const zip_uint8_t *str;
+
+    if ((de=_zip_get_dirent(za, idx, flags, NULL)) == NULL)
+	return -1;
+
+    if (opsys)
+	*opsys = (de->version_madeby >> 8) & 0xff;
+
+    if (attributes)
+	*attributes = de->ext_attrib;
+
+    return 0;
+}
diff --git a/lib/zip_file_set_external_attributes.c b/lib/zip_file_set_external_attributes.c
new file mode 100644
index 0000000..0820d6f
--- /dev/null
+++ b/lib/zip_file_set_external_attributes.c
@@ -0,0 +1,83 @@
+/*
+  zip_file_set_external_attributes.c -- set external attributes for entry
+  Copyright (C) 2013 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"
+
+int
+zip_file_set_external_attributes(struct zip *za, zip_uint64_t idx, zip_flags_t flags, zip_uint8_t opsys, zip_uint32_t attributes)
+{
+    struct zip_entry *e;
+    int changed;
+    zip_uint8_t unchanged_opsys;
+    zip_uint32_t unchanged_attributes;
+
+    if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
+	return -1;
+
+    if (ZIP_IS_RDONLY(za)) {
+	_zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
+	return -1;
+    }
+
+    e = za->entry+idx;
+
+    unchanged_opsys = e->orig ? e->orig->version_madeby>>8 : ZIP_OPSYS_DEFAULT;
+    unchanged_attributes = e->orig ? e->orig->ext_attrib : ZIP_EXT_ATTRIB_DEFAULT;
+
+    changed = (opsys != unchanged_opsys || attributes != unchanged_attributes);
+
+    if (changed) {
+        if (e->changes == NULL) {
+            if ((e->changes=_zip_dirent_clone(e->orig)) == NULL) {
+                _zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
+                return -1;
+            }
+        }
+        e->changes->version_madeby = (opsys << 8) | (e->changes->version_madeby & 0xff);
+	e->changes->ext_attrib = attributes;
+        e->changes->changed |= ZIP_DIRENT_ATTRIBUTES;
+    }
+    else if (e->changes) {
+	e->changes->changed &= ~ZIP_DIRENT_ATTRIBUTES;
+	if (e->changes->changed == 0) {
+	    _zip_dirent_free(e->changes);
+	    e->changes = NULL;
+	}
+	else {
+	    e->changes->version_madeby = (unchanged_opsys << 8) | (e->changes->version_madeby & 0xff);
+	    e->changes->ext_attrib = unchanged_attributes;
+	}
+    }
+
+    return 0;
+}
diff --git a/lib/zipint.h b/lib/zipint.h
index c5d0fd4..81c0179 100644
--- a/lib/zipint.h
+++ b/lib/zipint.h
@@ -157,7 +157,12 @@
 #define ZIP_EF_ZIP64		0x0001
 
 #define ZIP_EF_IS_INTERNAL(id)	((id) == ZIP_EF_UTF_8_COMMENT || (id) == ZIP_EF_UTF_8_NAME || (id) == ZIP_EF_ZIP64)
-
+
+/* according to unzip-6.0's zipinfo.c, this corresponds to a regular file with rw permissions for everyone */
+#define ZIP_EXT_ATTRIB_DEFAULT		0100666
+/* according to unzip-6.0's zipinfo.c, this corresponds to a directory with rwx permissions for everyone */
+#define ZIP_EXT_ATTRIB_DEFAULT_DIR	0040777
+
 
 /* This section contains API that won't materialize like this.  It's
    placed in the internal section, pending cleanup. */
@@ -302,6 +307,7 @@
 #define ZIP_DIRENT_FILENAME	0x0002u
 #define ZIP_DIRENT_COMMENT	0x0004u
 #define ZIP_DIRENT_EXTRA_FIELD	0x0008u
+#define ZIP_DIRENT_ATTRIBUTES	0x0010u
 #define ZIP_DIRENT_ALL		0xffffu
 
 struct zip_dirent {
diff --git a/man/Makefile.am b/man/Makefile.am
index bc0811e..8cc1183 100644
--- a/man/Makefile.am
+++ b/man/Makefile.am
@@ -26,8 +26,10 @@
 	zip_file_extra_field_set.mdoc \
 	zip_file_extra_fields_count.mdoc \
 	zip_file_get_comment.mdoc \
+	zip_file_get_external_attributes.mdoc \
 	zip_file_rename.mdoc \
 	zip_file_set_comment.mdoc \
+	zip_file_set_external_attributes.mdoc \
 	zip_file_strerror.mdoc \
 	zip_fopen.mdoc \
 	zip_fopen_encrypted.mdoc \
diff --git a/man/zip_file_get_comment.mdoc b/man/zip_file_get_comment.mdoc
index 39c6c5c..4193a22 100644
--- a/man/zip_file_get_comment.mdoc
+++ b/man/zip_file_get_comment.mdoc
@@ -29,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd February 20, 2013
+.Dd September 19, 2013
 .Dt ZIP_FILE_GET_COMMENT 3
 .Os
 .Sh NAME
@@ -97,7 +97,7 @@
 .Ar archive
 is set to indicate the error.
 .Sh ERRORS
-.Fn zip_get_file_comment
+.Fn zip_file_get_comment
 fails if:
 .Bl -tag -width Er
 .It Bq Er ZIP_ER_INVAL
diff --git a/man/zip_file_get_external_attributes.mdoc b/man/zip_file_get_external_attributes.mdoc
index 15789d3..82235ae 100644
--- a/man/zip_file_get_external_attributes.mdoc
+++ b/man/zip_file_get_external_attributes.mdoc
@@ -1,3 +1,137 @@
+.\" zip_file_get_external_attributes.mdoc -- get external attributes for file in zip
+.\" Copyright (C) 2013 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 September 19, 2013
+.Dt ZIP_FILE_GET_EXTERNAL_ATTRIBUTES 3
+.Os
+.Sh NAME
+.Nm zip_file_get_external_attributes
+.Nd get external attributes for file in zip
+.Sh LIBRARY
+libzip (-lzip)
+.Sh SYNOPSIS
+.In zip.h
+.Ft const char *
+.Fn zip_file_get_external_attributes "struct zip *archive" "zip_uint64_t index" "zip_flags_t flags" \
+"zip_uint8_t *opsys" "zip_uint32_t *attributes"
+.Sh DESCRIPTION
+The
+.Fn zip_file_get_external_attributes
+function returns the operating system and external attributes for the
+file at position
+.Ar index
+in the zip archive.
+The external attributes usually contain the operating system-specific
+file permissions.
+If
+.Ar flags
+is set to
+.Dv ZIP_FL_UNCHANGED ,
+the original unchanged values are returned.
+If
+.Ar opsys
+or
+.Ar attributes
+are
+.Dv NULL ,
+they are not filled in.
+.Pp
+The following operating systems are defined by the zip specification:
+.Bl -item -compact -offset indent
+.It
+ZIP_OPSYS_ACORN_RISC
+.It
+ZIP_OPSYS_ALTERNATE_MVS
+.It
+ZIP_OPSYS_AMIGA
+.It
+ZIP_OPSYS_ATARI_ST
+.It
+ZIP_OPSYS_BEOS
+.It
+ZIP_OPSYS_CPM
+.It
+ZIP_OPSYS_DOS
+.It
+ZIP_OPSYS_MACINTOSH
+.It
+ZIP_OPSYS_MVS
+.It
+ZIP_OPSYS_OPENVMS
+.It
+ZIP_OPSYS_OS_2
+.It
+ZIP_OPSYS_OS_400
+.It
+ZIP_OPSYS_OS_X
+.It
+ZIP_OPSYS_TANDEM
+.It
+ZIP_OPSYS_UNIX
+.It
+ZIP_OPSYS_VFAT
+.It
+ZIP_OPSYS_VM_CMS
+.It
+ZIP_OPSYS_VSE
+.It
+ZIP_OPSYS_WINDOWS_NTFS
+.It
+ZIP_OPSYS_Z_SYSTEM
+.El
+.Sh RETURN VALUES
+Upon successful completion, 0 is returned.
+In case of an error,
+.Dv \-1
+is returned and the error code in
+.Ar archive
+is set to indicate the error.
+.Sh ERRORS
+.Fn zip_file_get_external_attributes
+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_file_set_external_attributes 3
+.Sh EXAMPLES
+The following code can be used to expand
+.Ar attributes
+if the operating system is
+.Dv ZIP_OPSYS_DOS .
+.Bd -literal
 #include <sys/stat.h>
 
 #define FA_RDONLY       0x01            // FILE_ATTRIBUTE_READONLY
@@ -15,3 +149,9 @@
 
    return m;
 }
+.Ed
+.Sh AUTHORS
+.An -nosplit
+.An Dieter Baron Aq Mt dillo@nih.at
+and
+.An Thomas Klausner Aq Mt tk@giga.or.at
diff --git a/man/zip_file_set_comment.mdoc b/man/zip_file_set_comment.mdoc
index 832b013..bdd083a 100644
--- a/man/zip_file_set_comment.mdoc
+++ b/man/zip_file_set_comment.mdoc
@@ -1,5 +1,5 @@
 .\" zip_file_set_comment.mdoc -- set comment for file in zip
-.\" Copyright (C) 2006-2012 Dieter Baron and Thomas Klausner
+.\" Copyright (C) 2006-2013 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>
@@ -29,7 +29,7 @@
 .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 .\" IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd June 23, 2012
+.Dd September 19, 2013
 .Dt ZIP_FILE_SET_COMMENT 3
 .Os
 .Sh NAME
@@ -96,6 +96,10 @@
 is not a valid UTF-8 encoded string.
 .It Bq Er ZIP_ER_MEMORY
 Required memory could not be allocated.
+.It Bq Er ZIP_ER_RDONLY
+The
+.Ar archive
+was opened in read-only mode.
 .El
 .Sh SEE ALSO
 .Xr libzip 3 ,
diff --git a/man/zip_file_set_external_attributes.mdoc b/man/zip_file_set_external_attributes.mdoc
new file mode 100644
index 0000000..a3d6b83
--- /dev/null
+++ b/man/zip_file_set_external_attributes.mdoc
@@ -0,0 +1,87 @@
+.\" zip_file_set_external_attributes.mdoc -- set external attributes for file in zip
+.\" Copyright (C) 2013 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 September 19, 2013
+.Dt ZIP_FILE_SET_EXTERNAL_ATTRIBUTES 3
+.Os
+.Sh NAME
+.Nm zip_file_set_external_attributes
+.Nd set external attributes for file in zip
+.Sh LIBRARY
+libzip (-lzip)
+.Sh SYNOPSIS
+.In zip.h
+.Ft const char *
+.Fn zip_file_set_external_attributes "struct zip *archive" "zip_uint64_t index" "zip_flags_t flags" \
+"zip_uint8_t opsys" "zip_uint32_t attributes"
+.Sh DESCRIPTION
+The
+.Fn zip_file_set_external_attributes
+function sets the operating system and external attributes for the
+file at position
+.Ar index
+in the zip archive.
+Currently, no
+.Ar flags
+are supported.
+.Pp
+For a list of known
+.Ar opsys
+values, see
+.Xr zip_file_get_external_attributes 3 .
+.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_file_set_external_attributes
+fails if:
+.Bl -tag -width Er
+.It Bq Er ZIP_ER_INVAL
+.Ar index
+is not a valid file index in
+.Ar archive .
+.It Bq Er ZIP_ER_MEMORY
+Required memory could not be allocated.
+.It Bq Er ZIP_ER_RDONLY
+The
+.Ar archive
+was opened in read-only mode.
+.El
+.Sh SEE ALSO
+.Xr libzip 3 ,
+.Xr zip_file_get_external_attributes 3
+.Sh AUTHORS
+.An -nosplit
+.An Dieter Baron Aq Mt dillo@nih.at
+and
+.An Thomas Klausner Aq Mt tk@giga.or.at