Below are patches to zip and unzip that add extended
attributes support when running on Linux.
Usage:
zip
Will store extended attributes in the archive file by
default unless the existing option:
"-X eXclude eXtra file attributes" is used.
unzip
Will NOT restore extended attributes by default.
Will only restore extended attributes if used with the
new option:
"-E restore extended attributes".
The new -E option can only be used in conjunction with
the existing:
"-X restore UID/GID info" option.
Users can still choose to restore only the UID/GID info
with the existing '-X' option.
Thanks,
Debora Velarde
dvelarde@us.ibm.com
diff -urpN zip-2.3.orig/unix/Makefile zip-2.3/unix/Makefile
--- zip-2.3.orig/unix/Makefile 2005-10-10
13:55:45.000000000 -0500
+++ zip-2.3/unix/Makefile 2005-10-24
15:38:44.000000000 -0500
@@ -59,7 +59,7 @@ OBJN = zipnote.o $(OBJU)
OBJC = zipcloak.o $(OBJU) crctab.o crypt_.o ttyio.o
OBJS = zipsplit.o $(OBJU)
-ZIP_H = zip.h ziperr.h tailor.h unix/osdep.h
+ZIP_H = zip.h ziperr.h tailor.h unix/osdep.h unix/xattr.h
# suffix rules
.SUFFIXES:
diff -urpN zip-2.3.orig/unix/unix.c zip-2.3/unix/unix.c
--- zip-2.3.orig/unix/unix.c 2005-10-10
13:55:45.000000000 -0500
+++ zip-2.3/unix/unix.c 2005-10-24
15:38:44.000000000 -0500
@@ -11,6 +11,7 @@
#ifndef UTIL /* the companion #endif is a bit of ways
down ... */
#include <time.h>
+#include "xattr.h"
#if defined(MINIX) || defined(__mpexl)
# ifdef S_IWRITE
@@ -40,6 +41,8 @@
# endif
#endif /* HAVE_DIRENT_H || _POSIX_VERSION */
+#include <attr/xattr.h>
+
#define PAD 0
#define PATH_END '/'
@@ -436,19 +439,80 @@ int set_extra_field(z, z_utim)
struct stat s;
#endif
+char * xa_list;
+char * xa_name;
+char * xa_value;
+ssize_t xa_list_len=0;
+ssize_t xa_name_len=0;
+ssize_t xa_value_len=0;
+int value_len=0;
+int largest_value_len=0;
+int ext_index=0;
+int xa_pairs_found=0;
+int value_index=1;
+int i=0, j=0;
+
/* For the full sized UT local field including the
UID/GID fields, we
* have to stat the file again. */
if (LSSTAT(z->name, &s))
return ZE_OPEN;
+
#define EB_L_UT_SIZE (EB_HEADSIZE +
EB_UT_LEN(2))
#define EB_C_UT_SIZE (EB_HEADSIZE +
EB_UT_LEN(1))
#define EB_L_UX2_SIZE (EB_HEADSIZE +
EB_UX2_MINLEN)
#define EB_C_UX2_SIZE EB_HEADSIZE
-#define EF_L_UNIX_SIZE (EB_L_UT_SIZE +
EB_L_UX2_SIZE)
-#define EF_C_UNIX_SIZE (EB_C_UT_SIZE +
EB_C_UX2_SIZE)
+#define EB_L_XA_SIZE (EB_HEADSIZE +
EB_XA_MINLEN)
+#define EB_C_XA_SIZE EB_HEADSIZE
- if ((z->extra = (char *)malloc(EF_L_UNIX_SIZE)) ==
NULL)
+ /* Get size of xattr name list */
+ /* Calling listxattr with NULL and zero returns the
size */
+ xa_list_len = listxattr(z->name, NULL, 0);
+
+ if (xa_list_len > 0) {
+
+ /* now that we know the size, alloc space for list */
+ if ((xa_list = malloc(xa_list_len+1)) == NULL)
+ return ZE_MEM;
+
+ /* Get the list of xattr names */
+ xa_list_len = listxattr(z->name, xa_list, xa_list_len);
+ if (xa_list_len < 0)
+ return ZE_XATTR;
+ xa_name = xa_list;
+ xa_name_len = xa_list_len;
+
+ /* figure out how many xattr names there are in the
list */
+ xa_pairs_found=get_xattr_count(xa_list,
xa_list_len);
+ if (xa_pairs_found < 1)
+ return ZE_XATTR;
+
+ /* Need to figure out the largest value_len before
calling malloc */
+ /* also need the sum of all value_lens; store it in
xa_value_len */
+ for (value_index=1; value_index <= xa_pairs_found;
value_index++) {
+ xa_name=get_xattr_name(xa_list, xa_list_len,
value_index);
+ if (xa_name == (char *)NULL)
+ return ZE_XATTR;
+ value_len=getxattr(z->name, xa_name, xa_value,
0);
+ if (value_len < 0)
+ return ZE_XATTR;
+ if (value_len > largest_value_len)
+ largest_value_len = value_len;
+ xa_value_len=xa_value_len + value_len + 1;
+ }
+ if ((xa_value = malloc(largest_value_len+1)) ==
NULL)
+ return ZE_MEM;
+ }
+
+#define EB_L_XN_SIZE (EB_HEADSIZE +
EB_XA_MINLEN + xa_name_len)
+#define EB_C_XN_SIZE EB_HEADSIZE
+#define EB_L_XV_SIZE (EB_HEADSIZE +
EB_XA_MINLEN + xa_value_len)
+#define EB_C_XV_SIZE EB_HEADSIZE
+#define EF_L_UNIX_SIZE (EB_L_UT_SIZE +
EB_L_UX2_SIZE + EB_L_XA_SIZE + EB_L_XN_SIZE +
EB_L_XV_SIZE)
+#define EF_C_UNIX_SIZE (EB_C_UT_SIZE +
EB_C_UX2_SIZE + EB_C_XA_SIZE + EB_C_XN_SIZE
+ EB_C_XV_SIZE)
+
+ z->ext = EF_L_UNIX_SIZE;
+ if ((z->extra = (char *)malloc(z->ext)) == NULL)
return ZE_MEM;
if ((z->cextra = (char *)malloc(EF_C_UNIX_SIZE)) ==
NULL)
return ZE_MEM;
@@ -474,7 +538,71 @@ int set_extra_field(z, z_utim)
z->extra[18] = (char)(s.st_uid >> 8);
z->extra[19] = (char)(s.st_gid);
z->extra[20] = (char)(s.st_gid >> 8);
- z->ext = EF_L_UNIX_SIZE;
+ z->extra[21] = 'X';
+ z->extra[22] = 'A';
+ z->extra[23] = (char) xa_pairs_found; /* Number of
xattr attributes*/
+ z->extra[24] = 0;
+ z->extra[25] = 'X';
+ z->extra[26] = 'N';
+ z->extra[27] = (char) xa_name_len; /* length of
xattr name list*/
+ z->extra[28] = 0;
+
+ ext_index=29;
+
+ if (xa_list_len > 0) {
+
+/* Put all the xattr names in extra field */
+ for (i=1; i<=xa_pairs_found; i++) {
+ xa_name=get_xattr_name(xa_list, xa_list_len, i);
+ if (xa_name == (char *)NULL)
+ return ZE_XATTR;
+ xa_name_len=strlen(xa_name);
+ if (xa_name_len < 1)
+ return ZE_XATTR;
+ for (j=0; j<xa_name_len; j++) {
+ z->extra[ext_index+j]=(char) xa_name[j];
+ }
+ ext_index = ext_index+j;
+ z->extra[ext_index] = '\0';
+ ext_index++;
+ }
+
+ z->extra[ext_index] = 'X';
+ ext_index++;
+ z->extra[ext_index] = 'V';
+ ext_index++;
+ z->extra[ext_index] = (char) xa_value_len; /*
length of xattr value list*/
+ ext_index++;
+ z->extra[ext_index] = 0;
+ ext_index++;
+
+/* Put all the xattr values in extra field */
+ for (value_index=1; value_index <= xa_pairs_found;
value_index++) {
+ xa_name=get_xattr_name(xa_list, xa_list_len,
value_index);
+ if (xa_name == (char *)NULL)
+ return ZE_XATTR;
+ value_len=getxattr(z->name, xa_name, xa_value,
0);
+ if (value_len < 1)
+ return ZE_XATTR;
+ xa_value=memset(xa_value, 0,
largest_value_len+1);
+ if (xa_value == (char *) NULL)
+ return ZE_MEM;
+ value_len=getxattr(z->name, xa_name, xa_value,
value_len);
+ if (value_len < 1)
+ return ZE_XATTR;
+
+ for (j=0; j<value_len; j++) {
+ z->extra[ext_index+j]=(char) xa_value[j];
+ }
+ ext_index = ext_index+j;
+ z->extra[ext_index] = '\0';
+ ext_index++;
+ }
+
+ } /* if xa_list_len > 0 */
+
+ free(xa_list);
+ free(xa_value);
memcpy(z->cextra, z->extra, EB_C_UT_SIZE);
z->cextra[EB_LEN] = (char)EB_UT_LEN(1);
diff -urpN zip-2.3.orig/unix/xattr.h zip-2.3/unix/xattr.h
--- zip-2.3.orig/unix/xattr.h 1969-12-31
18:00:00.000000000 -0600
+++ zip-2.3/unix/xattr.h 2005-10-24
15:42:43.000000000 -0500
@@ -0,0 +1,67 @@
+/*
+ Copyright (C) 2005 IBM Corporation
+ Copyright (c) 1990-1999 Info-ZIP. All rights reserved.
+
+ See the accompanying file LICENSE, version 1999-
Oct-05 or later
+ (the contents of which are also included in zip.h) for
terms of use.
+ If, for some reason, both of these files are missing,
the Info-ZIP license
+ also may be found at:
ftp://ftp.cdrom.com/pub/infozip/license.html
+*/
+
+
+int get_xattr_count(char * xa_list, int xa_list_size)
+{
+/* xattr names have the form name1.name2 */
+/* A file can have any number of xattr name pairs */
+/* This function returns the number of name pairs found
*/
+/* If list passed in is NULL or list size is less than 1
+ function returns 0 */
+
+ int i=0;
+ int p=0;
+
+ if ( (xa_list == (char *) NULL) || (xa_list_size < 1))
+ return 0;
+
+ while (i < xa_list_size) {
+ if ( xa_list[i] != '\0') {
+ i++;
+ } else {
+ i++;
+ p++;
+ }
+ }
+ return p;
+}
+
+char * get_xattr_name(char * xa_list, int xa_list_size,
int pair)
+{
+/* xattr names have the form name1.name2 */
+/* A file can have any number of xattr name pairs */
+/* This function returns a pointer to the specified name
pair */
+/* If list is NULL or size or pair are less than 1, then
+ function returns NULL */
+
+ int i=0;
+ int p=1;
+ char * tmp;
+
+ tmp=NULL;
+
+ if ( (xa_list == (char *) NULL) || (xa_list_size < 1) ||
(pair < 1) )
+ return NULL;
+
+ while ( (i < xa_list_size) && ( p != pair) ) {
+ if ( xa_list[i] != '\0') {
+ i++;
+ } else {
+ i++;
+ p++;
+ }
+ }
+
+ if ( (p==pair) && (i < xa_list_size) )
+ tmp=&xa_list[i];
+
+ return tmp;
+}
diff -urpN zip-2.3.orig/zip.c zip-2.3/zip.c
--- zip-2.3.orig/zip.c 2005-10-10 14:11:49.000000000 -
0500
+++ zip-2.3/zip.c 2005-10-24 15:38:44.000000000 -
0500
@@ -980,7 +980,7 @@ char **argv; /*
command line
zp_tz_is_valid = VALID_TIMEZONE(p);
#if (defined(AMIGA) || defined(DOS))
if (!zp_tz_is_valid)
- extra_fields = 0; /* disable storing "UT" time
stamps and xatter info*/
+ extra_fields = 0; /* disable storing "UT" time
stamps */
#endif /* AMIGA || DOS */
#endif /* IZ_CHECK_TZ && USE_EF_UT_TIME */
diff -urpN zip-2.3.orig/ziperr.h zip-2.3/ziperr.h
--- zip-2.3.orig/ziperr.h 2005-10-10 13:55:45.000000000 -
0500
+++ zip-2.3/ziperr.h 2005-10-24 15:38:44.000000000 -
0500
@@ -31,8 +31,9 @@
#define ZE_CREAT 15 /* couldn't open to write
*/
#define ZE_PARMS 16 /* bad command line */
#define ZE_OPEN 18 /* could not open a
specified file to read */
+#define ZE_XATTR 19 /* xattr error occurred */
-#define ZE_MAXERR 18 /* the highest error
number */
+#define ZE_MAXERR 19 /* the highest error
number */
/* Macro to determine whether to call perror() or not */
#define PERR(e)
(e==ZE_READ||e==ZE_WRITE||e==ZE_CREAT||e==ZE_
TEMP||e==ZE_OPEN)
@@ -58,6 +59,7 @@ char *errors[ZE_MAXERR] = {
/* 16 */ "Invalid command arguments",
/* 17 */ "",
/* 18 */ "File not found or no read permission"
+/* 19 */ "Extended attributes failure"
# ifdef AZTEC_C
, /* extremely lame compiler bug workaround
*/
# endif
diff -urpN zip-2.3.orig/zip.h zip-2.3/zip.h
--- zip-2.3.orig/zip.h 2005-10-10 13:55:45.000000000 -
0500
+++ zip-2.3/zip.h 2005-10-24 15:38:44.000000000 -
0500
@@ -171,6 +171,9 @@ struct plist {
#define EF_SPARK 0x4341 /* David Pilling's
Acorn/SparkFS ("AC") */
#define EF_THEOS 0x6854 /* THEOS ("Th") */
#define EF_TANDEM 0x4154 /* Tandem NSK
("TA") */
+#define EF_XATTR 0x4158 /* XATTR ("XA") */
+#define EF_XA_NAME 0x4e58 /* XATTR NAME
("XN") */
+#define EF_XA_VALUE 0x5658 /* XATTR VALUE
("XV") */
/* Definitions for extra field handling: */
#define EF_SIZE_MAX ((unsigned)0xFFFF) /* hard
limit of total e.f. length */
@@ -199,6 +202,8 @@ struct plist {
#define EB_UX2_GID 2 /* byte offset of GID
in "Ux" field data */
#define EB_UX2_VALID (1 << 8) /* UID/GID
present */
+#define EB_XA_MINLEN 4 /* minimal XA field
contains count */
+
/* ASCII definitions for line terminators in text files: */
#define LF 10 /* '\n' on ASCII machines; must
be 10 due to EBCDIC */
#define CR 13 /* '\r' on ASCII machines; must
be 13 due to EBCDIC */
diff -urpN zip-2.3.orig/zip.h.4gb zip-2.3/zip.h.4gb
--- zip-2.3.orig/zip.h.4gb 2005-10-10
13:55:45.000000000 -0500
+++ zip-2.3/zip.h.4gb 2005-10-24 15:38:44.000000000 -
0500
@@ -171,6 +171,9 @@ struct plist {
#define EF_SPARK 0x4341 /* David Pilling's
Acorn/SparkFS ("AC") */
#define EF_THEOS 0x6854 /* THEOS ("Th") */
#define EF_TANDEM 0x4154 /* Tandem NSK
("TA") */
+#define EF_XATTR 0x4158 /* XATTR ("XA") */
+#define EF_XA_NAME 0x4e58 /* XATTR NAME
("XN") */
+#define EF_XA_VALUE 0x5658 /* XATTR VALUE
("XV") */
/* Definitions for extra field handling: */
#define EF_SIZE_MAX ((unsigned)0xFFFF) /* hard
limit of total e.f. length */
@@ -199,6 +202,8 @@ struct plist {
#define EB_UX2_GID 2 /* byte offset of GID
in "Ux" field data */
#define EB_UX2_VALID (1 << 8) /* UID/GID
present */
+#define EB_XA_MINLEN 4 /* minimal XA field
contains count */
+
/* ASCII definitions for line terminators in text files: */
#define LF 10 /* '\n' on ASCII machines; must
be 10 due to EBCDIC */
#define CR 13 /* '\r' on ASCII machines; must
be 13 due to EBCDIC */
diff -urpN zip-2.3.orig/zip.h.zip zip-2.3/zip.h.zip
--- zip-2.3.orig/zip.h.zip 2005-10-10
13:55:45.000000000 -0500
+++ zip-2.3/zip.h.zip 2005-10-24 15:38:44.000000000 -
0500
@@ -170,6 +170,10 @@ struct plist {
#define EF_SPARK 0x4341 /* David Pilling's
Acorn/SparkFS ("AC") */
#define EF_THEOS 0x6854 /* THEOS ("Th") */
#define EF_TANDEM 0x4154 /* Tandem NSK
("TA") */
+#define EF_XATTR 0x4158 /* XATTR ("XA") */
+#define EF_XA_NAME 0x4e58 /* XATTR NAME
("XN") */
+#define EF_XA_VALUE 0x5658 /* XATTR VALUE
("XV") */
+
/* Definitions for extra field handling: */
#define EF_SIZE_MAX ((unsigned)0xFFFF) /* hard
limit of total e.f. length */
@@ -198,6 +202,8 @@ struct plist {
#define EB_UX2_GID 2 /* byte offset of GID
in "Ux" field data */
#define EB_UX2_VALID (1 << 8) /* UID/GID
present */
+#define EB_XA_MINLEN 4 /* minimal XA field
contains count */
+
/* ASCII definitions for line terminators in text files: */
#define LF 10 /* '\n' on ASCII machines; must
be 10 due to EBCDIC */
#define CR 13 /* '\r' on ASCII machines; must
be 13 due to EBCDIC */
diff -urpN unzip-5.51.orig/extract.c unzip-5.51/extract.c
--- unzip-5.51.orig/extract.c 2005-09-08
14:25:57.000000000 -0500
+++ unzip-5.51/extract.c 2005-10-24
16:09:09.000000000 -0500
@@ -1908,6 +1908,9 @@ static int TestExtraField
(__G__ ef, ef_l
case EF_ASIUNIX:
case EF_IZVMS:
case EF_IZUNIX:
+ case EF_XATTR:
+ case EF_XA_NAME:
+ case EF_XA_VALUE:
case EF_VMCMS:
case EF_MVS:
case EF_SPARK:
diff -urpN unzip-5.51.orig/fileio.c unzip-5.51/fileio.c
--- unzip-5.51.orig/fileio.c 2005-09-08
14:25:57.000000000 -0500
+++ unzip-5.51/fileio.c 2005-10-24
16:09:09.000000000 -0500
@@ -1833,6 +1833,9 @@ int check_for_newer(__G__
filename) /*
#ifdef USE_EF_UT_TIME
iztimes z_utime;
#endif
+#ifdef USE_EF_XATTR
+ izxattr z_xattr;
+#endif
#ifdef AOS_VS
long dyy, dmm, ddd, dhh, dmin, dss;
@@ -1902,7 +1905,11 @@ int check_for_newer(__G__
filename) /*
G.tz_is_valid &&
#endif
(ef_scan_for_izux(G.extra_field,
G.lrec.extra_field_length, 0,
+#ifdef USE_EF_XATTR
+ G.lrec.last_mod_dos_datetime,
&z_utime, NULL, &z_xattr)
+#else
G.lrec.last_mod_dos_datetime,
&z_utime, NULL)
+#endif
& EB_UT_FL_MTIME))
{
TTrace((stderr, "check_for_newer: using Unix
extra field mtime\n"));
diff -urpN unzip-5.51.orig/list.c unzip-5.51/list.c
--- unzip-5.51.orig/list.c 2005-09-08
14:25:57.000000000 -0500
+++ unzip-5.51/list.c 2005-10-24 16:09:09.000000000 -
0500
@@ -104,6 +104,9 @@ int list_files(__G) /* return
PK-type
iztimes z_utime;
struct tm *t;
#endif
+#ifdef USE_EF_XATTR
+ izxattr z_xattr;
+#endif
unsigned yr, mo, dy, hh, mm;
ulg csiz;
unsigned long long tot_csize=0, tot_ucsize=0;
@@ -268,7 +271,12 @@ int list_files(__G) /* return
PK-type
G.tz_is_valid &&
#endif
(ef_scan_for_izux(G.extra_field,
G.crec.extra_field_length, 1,
-
G.crec.last_mod_dos_datetime, &z_utime, NULL)
+
G.crec.last_mod_dos_datetime, &z_utime,
+#ifdef USE_EF_XATTR
+ NULL, &z_xattr)
+#else
+ NULL)
+#endif
& EB_UT_FL_MTIME))
{
TIMET_TO_NATIVE(z_utime.mtime) /*
NOP unless MSC 7.0, Mac */
@@ -509,6 +517,9 @@ int get_time_stamp(__G__
last_modtime, n
#ifdef USE_EF_UT_TIME
iztimes z_utime;
#endif
+#ifdef USE_EF_XATTR
+ iztimes z_xattr;
+#endif
min_info info;
@@ -594,7 +605,12 @@ int get_time_stamp(__G__
last_modtime, n
G.tz_is_valid &&
#endif
(ef_scan_for_izux(G.extra_field,
G.crec.extra_field_length, 1,
-
G.crec.last_mod_dos_datetime, &z_utime, NULL)
+
G.crec.last_mod_dos_datetime, &z_utime,
+#ifdef USE_EF_XATTR
+ NULL, &z_xattr)
+#else
+ NULL)
+#endif
& EB_UT_FL_MTIME))
{
if (*last_modtime < z_utime.mtime)
diff -urpN unzip-5.51.orig/Makefile unzip-5.51/Makefile
--- unzip-5.51.orig/Makefile 2005-09-08
14:25:57.000000000 -0500
+++ unzip-5.51/Makefile 2005-10-24
16:09:09.000000000 -0500
@@ -81,14 +81,14 @@ CRC32 = crc32
OSDEP_H =
# object files
-OBJS1 = unzip$O $(CRC32)$O crctab$O crypt$O
envargs$O explode$O
+OBJS1 = unzip$O $(CRC32)$O crctab$O crypt$O
envargs$O explode$O xattr$O
OBJS2 = extract$O fileio$O globals$O inflate$O list$O
match$O
OBJS3 = process$O ttyio$O unreduce$O unshrink$O
zipinfo$O
OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $M$O
LOBJS = $(OBJS)
OBJSDLL = $(OBJS:.o=.pic.o) api.pic.o
OBJX = unzipsfx$O $(CRC32)$O crctab_$O crypt_$O
extract_$O fileio_$O \
- globals_$O inflate_$O match_$O
process_$O ttyio_$O $M_$O
+ globals_$O inflate_$O match_$O
process_$O ttyio_$O xattr_$O $M_$O
LOBJX = $(OBJX)
OBJF = funzip$O $(CRC32)$O cryptf$O globalsf$O
inflatef$O ttyiof$O
#OBJS_OS2 = $(OBJS1:.o=.obj) $(OBJS2:.o=.obj)
os2.obj
@@ -300,6 +300,7 @@ ttyio$O: ttyio.c $(UNZIP_H)
zip.h crypt.
unreduce$O: unreduce.c $(UNZIP_H)
unshrink$O: unshrink.c $(UNZIP_H)
unzip$O: unzip.c $(UNZIP_H) crypt.h unzvers.h
consts.h
+xattr$O: xattr.c $(UNZIP_H)
zipinfo$O: zipinfo.c $(UNZIP_H)
unzipsfx$O: unzip.c $(UNZIP_H) crypt.h
unzvers.h consts.h # unzipsfx only
@@ -342,6 +343,11 @@ match_$O: match.c
$(UNZIP_H)
# unzips
$(CC) -c $(CF) -DSFX match_.c
$(RM) match_.c
+xattr_$O: xattr.c $(UNZIP_H)
# unzipsfx only
+ -$(CP) xattr.c xattr_.c
+ $(CC) -c $(CF) -DSFX xattr_.c
+ $(RM) xattr_.c
+
process_$O: process.c $(UNZIP_H)
# unzipsfx only
-$(CP) process.c process_.c
$(CC) -c $(CF) -DSFX process_.c
diff -urpN unzip-5.51.orig/process.c unzip-5.51/process.c
--- unzip-5.51.orig/process.c 2005-09-08
14:25:57.000000000 -0500
+++ unzip-5.51/process.c 2005-10-24
16:09:09.000000000 -0500
@@ -1300,15 +1300,22 @@ int process_local_file_hdr
(__G) /* re
/*******************************/
/* Function ef_scan_for_izux() */
/*******************************/
-
+#ifdef USE_EF_XATTR
+unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c,
dos_mdatetime,
+ z_utim, z_uidgid, z_xattr)
+#else
unsigned ef_scan_for_izux(ef_buf, ef_len, ef_is_c,
dos_mdatetime,
z_utim, z_uidgid)
+#endif
ZCONST uch *ef_buf; /* buffer containing extra field */
unsigned ef_len; /* total length of extra field */
int ef_is_c; /* flag indicating "is central extra
field" */
ulg dos_mdatetime; /* last_mod_file_date_time in
DOS format */
iztimes *z_utim; /* return storage: atime, mtime,
ctime */
ush *z_uidgid; /* return storage: uid and gid */
+#ifdef USE_EF_XATTR
+ izxattr *z_xattr; /* return storage: xattr names,
values, lens, count */
+#endif
{
unsigned flags = 0;
unsigned eb_id;
@@ -1342,6 +1349,12 @@ unsigned ef_scan_for_izux
(ef_buf, ef_len
if (ef_len == 0 || ef_buf == NULL || (z_utim == 0 &&
z_uidgid == NULL))
return 0;
+#ifdef USE_EF_XATTR
+ if (z_xattr == NULL)
+ return 0;
+ z_xattr->count=0;
+#endif
+
TTrace((stderr,"\nef_scan_for_izux: scanning extra
field of length %u\n",
ef_len));
@@ -1358,6 +1371,56 @@ unsigned ef_scan_for_izux
(ef_buf, ef_len
}
switch (eb_id) {
+#ifdef USE_EF_XATTR
+ case EF_XATTR:
+ z_xattr->count=eb_len;
+ if (z_xattr->count > 0) {
+ ef_buf += EB_HEADSIZE;
+ ef_len -= EB_HEADSIZE;
+ eb_id = makeword(EB_ID + ef_buf);
+ } else {
+ break;
+ }
+ case EF_XA_NAME:
+ if (z_xattr->count > 0) {
+ ef_buf += EB_HEADSIZE;
+ ef_len -= EB_HEADSIZE;
+ if ((z_xattr->xa_name=malloc(ef_len)) ==
(char *)NULL) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString
(CannotAllocateBuffers)));
+ return 0;
+ }
+ z_xattr->xa_name_len=copy_xattr(ef_buf,
z_xattr->xa_name, z_xattr->count);
+ if (z_xattr->xa_name_len < 0) {
+ TTrace((stderr,
+ " XATTR name error; ignore e.f.!
\n"));
+ break; /* stop scanning
this field */
+ }
+ ef_buf += z_xattr->xa_name_len;
+ ef_len -= z_xattr->xa_name_len;
+ } else {
+ break;
+ }
+ case EF_XA_VALUE:
+ if (z_xattr->count > 0) {
+ ef_buf += EB_HEADSIZE;
+ ef_len -= EB_HEADSIZE;
+ if ((z_xattr->xa_value=malloc(ef_len)) ==
(char *)NULL) {
+ Info(slide, 0x401, ((char *)slide,
+ LoadFarString
(CannotAllocateBuffers)));
+ return 0;
+ }
+ z_xattr->xa_value_len=copy_xattr(ef_buf,
z_xattr->xa_value, z_xattr->count);
+ if (z_xattr->xa_value_len <= 0) {
+ TTrace((stderr,
+ " XATTR value error; ignore e.f.!
\n"));
+ break; /* stop scanning
this field */
+ }
+ ef_buf += z_xattr->xa_value_len;
+ ef_len -= z_xattr->xa_value_len;
+ }
+ break;
+#endif
case EF_TIME:
flags &= ~0x0ff; /* ignore previous IZUNIX or
EF_TIME fields */
have_new_type_eb = TRUE;
diff -urpN unzip-5.51.orig/unix/Makefile unzip-
5.51/unix/Makefile
--- unzip-5.51.orig/unix/Makefile 2005-09-08
14:25:57.000000000 -0500
+++ unzip-5.51/unix/Makefile 2005-10-24
16:09:09.000000000 -0500
@@ -81,14 +81,14 @@ CRC32 = crc32
OSDEP_H =
# object files
-OBJS1 = unzip$O $(CRC32)$O crctab$O crypt$O
envargs$O explode$O
+OBJS1 = unzip$O $(CRC32)$O crctab$O crypt$O
envargs$O explode$O xattr$O
OBJS2 = extract$O fileio$O globals$O inflate$O list$O
match$O
OBJS3 = process$O ttyio$O unreduce$O unshrink$O
zipinfo$O
OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $M$O
LOBJS = $(OBJS)
OBJSDLL = $(OBJS:.o=.pic.o) api.pic.o
OBJX = unzipsfx$O $(CRC32)$O crctab_$O crypt_$O
extract_$O fileio_$O \
- globals_$O inflate_$O match_$O
process_$O ttyio_$O $M_$O
+ globals_$O inflate_$O match_$O
process_$O ttyio_$O xattr_$O $M_$O
LOBJX = $(OBJX)
OBJF = funzip$O $(CRC32)$O cryptf$O globalsf$O
inflatef$O ttyiof$O
#OBJS_OS2 = $(OBJS1:.o=.obj) $(OBJS2:.o=.obj)
os2.obj
@@ -300,6 +300,7 @@ ttyio$O: ttyio.c $(UNZIP_H)
zip.h crypt.
unreduce$O: unreduce.c $(UNZIP_H)
unshrink$O: unshrink.c $(UNZIP_H)
unzip$O: unzip.c $(UNZIP_H) crypt.h unzvers.h
consts.h
+xattr$O: xattr.c $(UNZIP_H)
zipinfo$O: zipinfo.c $(UNZIP_H)
unzipsfx$O: unzip.c $(UNZIP_H) crypt.h
unzvers.h consts.h # unzipsfx only
@@ -342,6 +343,11 @@ match_$O: match.c
$(UNZIP_H)
# unzips
$(CC) -c $(CF) -DSFX match_.c
$(RM) match_.c
+xattr_$O: xattr.c $(UNZIP_H)
# unzipsfx only
+ -$(CP) xattr.c xattr_.c
+ $(CC) -c $(CF) -DSFX xattr_.c
+ $(RM) xattr_.c
+
process_$O: process.c $(UNZIP_H)
# unzipsfx only
-$(CP) process.c process_.c
$(CC) -c $(CF) -DSFX process_.c
diff -urpN unzip-5.51.orig/unix/unix.c unzip-
5.51/unix/unix.c
--- unzip-5.51.orig/unix/unix.c 2005-09-08
14:25:57.000000000 -0500
+++ unzip-5.51/unix/unix.c 2005-10-24
16:09:09.000000000 -0500
@@ -83,6 +83,7 @@ typedef struct uxdirattr { /*
struc
int have_uidgid; /* flag */
ush uidgid[2];
char fnbuf[1]; /* buffer stub for directory
name */
+ izxattr z_xattr; /* struct for xattr names and
values */
} uxdirattr;
#define UxAtt(d) ((uxdirattr *)d) /* typecast shortcut */
#endif /* SET_DIR_ATTRIB */
@@ -932,12 +933,13 @@ int mkdir(path, mode)
#if (!defined(MTS) || defined(SET_DIR_ATTRIB))
-static int get_extattribs OF((__GPRO__ iztimes *pzt,
ush z_uidgid[2]));
+static int get_extattribs OF((__GPRO__ iztimes *pzt,
ush z_uidgid[2], izxattr *pzxattr));
-static int get_extattribs(__G__ pzt, z_uidgid)
+static int get_extattribs(__G__ pzt, z_uidgid, pzxattr)
__GDEF
iztimes *pzt;
ush z_uidgid[2];
+ izxattr *pzxattr;
{
/*---------------------------------------------------------------------------
Convert from MSDOS-format local time and date to
Unix-format 32-bit GMT
@@ -957,7 +959,13 @@ static int get_extattribs
(__G__ pzt, z_u
#else
pzt,
#endif
- z_uidgid) : 0);
+ z_uidgid,
+#ifdef USE_EF_XATTR
+ pzxattr) : 0);
+#else
+ NULL) : 0);
+#endif
+
if (eb_izux_flg & EB_UT_FL_MTIME) {
TTrace((stderr, "\nget_extattribs: Unix e.f. modif.
time = %ld\n",
pzt->mtime));
@@ -1000,7 +1008,14 @@ void close_outfile(__G) /*
GRR: chang
ztimbuf t2; /* modtime, actime */
} zt;
ush z_uidgid[2];
+ izxattr z_xattr;
int have_uidgid_flg;
+ int rc=0;
+ char *name;
+ char *value;
+ int i;
+ int value_len;
+ int largest_value_len=0;
fchmod(fileno(G.outfile), 0400);
@@ -1090,7 +1105,7 @@ void close_outfile(__G) /*
GRR: chang
}
#endif
- have_uidgid_flg = get_extattribs(__G__ &(zt.t3),
z_uidgid);
+ have_uidgid_flg = get_extattribs(__G__ &(zt.t3),
z_uidgid, &z_xattr);
/* if -X option was specified and we have UID/GID
info, restore it */
if (have_uidgid_flg) {
@@ -1108,6 +1123,54 @@ void close_outfile(__G) /*
GRR: chang
}
}
+#ifdef USE_EF_XATTR
+/* if -E option was specified attempt to restore
extended attribute info */
+ if (uO.E_flag && (!have_uidgid_flg)) {
+ Info(slide, 0x201, ((char *)slide,
+ " (warning) unable to restore extended
attributes for %s\n", FnFilter1(G.filename)));
+ }
+ if (uO.E_flag && have_uidgid_flg) {
+ /* Restore extended attributes info */
+ if (z_xattr.count > 0) {
+ /* Need to figure out the largest value_len
before calling malloc */
+ for (i=1; i<=z_xattr.count; i++) {
+ name = get_xattr_name(z_xattr.xa_name,
z_xattr.xa_name_len, i);
+ value_len=getxattr(z_xattr.xa_name, name,
value, 0);
+ if (value_len > largest_value_len)
+ largest_value_len = value_len;
+ }
+ if ((value = malloc(largest_value_len+1)) ==
(char *)NULL) {
+ Info(slide, 0x201, ((char *)slide,
+ "warning: xattr (%s) failed: no mem\n",
+ FnFilter1(G.filename)));
+ return;
+ } else {
+ /* Set all xattr name and value pairs */
+ for (i=1; i<=z_xattr.count; i++) {
+ name = get_xattr_name
(z_xattr.xa_name, z_xattr.xa_name_len, i);
+ if (name == (char *) NULL) {
+ Info(slide, 0x201, ((char *)slide,
+ " (warning) cannot restore extended
attributes for %s\n", FnFilter1(G.filename)));
+ }
+ value = get_xattr_value(z_xattr.xa_value,
z_xattr.xa_value_len, i);
+ if (value == (char *) NULL) {
+ Info(slide, 0x201, ((char *)slide,
+ " (warning) cannot restore extended
attributes for %s\n", FnFilter1(G.filename)));
+ }
+ rc = setxattr(G.filename, name, value,
strlen(value), 0);
+ if (rc != 0) {
+ Info(slide, 0x201, ((char *)slide,
+ " (warning) cannot restore extended
attributes for %s\n", FnFilter1(G.filename)));
+ }
+ }
+ }
+ } else {
+ Info(slide, 0x201, ((char *)slide,
+ " (warning) cannot restore extended
attributes for %s\n", FnFilter1(G.filename)));
+ }
+ }
+#endif
+
/* set the file's access and modification times */
if (utime(G.filename, &(zt.t2))) {
#ifdef AOS_VS
@@ -1160,7 +1223,7 @@ int defer_dir_attribs(__G__
pd)
d_entry->perms = G.pInfo->file_attr;
d_entry->have_uidgid = get_extattribs(__G__ &
(d_entry->u.t3),
- d_entry->uidgid);
+ d_entry->uidgid, &
(d_entry->z_xattr));
return PK_OK;
} /* end function defer_dir_attribs() */
diff -urpN unzip-5.51.orig/unix/unxcfg.h unzip-
5.51/unix/unxcfg.h
--- unzip-5.51.orig/unix/unxcfg.h 2005-09-08
14:25:57.000000000 -0500
+++ unzip-5.51/unix/unxcfg.h 2005-10-24
16:09:09.000000000 -0500
@@ -122,6 +122,8 @@
#endif
#define RESTORE_UIDGID
+#define USE_EF_XATTR
+
/* Static variables that we have to add to Uz_Globs: */
#define SYSTEM_SPECIFIC_GLOBALS \
int created_dir, renamed_fullpath;\
diff -urpN unzip-5.51.orig/unzip.c unzip-5.51/unzip.c
--- unzip-5.51.orig/unzip.c 2005-09-08
14:25:57.000000000 -0500
+++ unzip-5.51/unzip.c 2005-10-24
16:09:09.000000000 -0500
@@ -143,6 +143,8 @@ static ZCONST char Far
InvalidOptionsMsg
-fn or any combination of -c, -l, -p, -t, -u and -v options
invalid\n";
static ZCONST char Far IgnoreOOptionMsg[] =
"caution: both -n and -o specified; ignoring -o\n";
+static ZCONST char Far InvalidEModifierMsg[] = "error:\
+ -E modifier cannot be used without -X modifier\n";
/* usage() strings */
#ifndef SFX
@@ -238,12 +240,30 @@ M pipe through \"more\"
pager
#else /* !VMS */
#ifdef BEO_UNX
static ZCONST char Far local2[] = " -X restore
UID/GID info";
+#ifdef USE_EF_XATTR
+#ifdef MORE
+ static ZCONST char Far local3[] = " \
+-E restore extended attributes -M pipe
through \"more\" pager\n";
+#else /* !MORE */
+ static ZCONST char Far local3[] = " \
+-E restore extended attributes\n";
+#endif
+#else /* !USE_EF_XATTR */
+#ifdef MORE
+ static ZCONST char Far local3[] = "\
+ -M pipe through
\"more\" pager\n";
+#else /* !MORE */
+ static ZCONST char Far local3[] = "\n";
+#endif
+#endif
+/*
#ifdef MORE
static ZCONST char Far local3[] = "\
-M pipe through
\"more\" pager\n";
#else
static ZCONST char Far local3[] = "\n";
#endif
+*/
#else /* !BEO_UNX */
#ifdef TANDEM
static ZCONST char Far local2[] = "\
@@ -1222,6 +1242,15 @@ int uz_opts(__G__ pargc,
pargv)
}
break;
#endif /* MACOS */
+#ifdef UNIX
+ case ('E'): /* -E [UNIX] restore extended
attributes */
+ if( negative ) {
+ uO.E_flag = FALSE, negative = 0;
+ } else {
+ uO.E_flag = TRUE;
+ }
+ break;
+#endif /* MACOS */
case ('f'): /* "freshen" (extract only newer
files) */
if (negative)
uO.fflag = uO.uflag = FALSE, negative
= 0;
@@ -1521,6 +1550,13 @@ opts_done: /* yes, very
ugly...but only
Info(slide, 0x401, ((char *)slide, LoadFarString
(InvalidOptionsMsg)));
error = TRUE;
}
+#ifdef UNIX
+ if (uO.E_flag && (!uO.X_flag))
+ {
+ Info(slide, 0x401, ((char *)slide, LoadFarString
(InvalidEModifierMsg)));
+ error = TRUE;
+ }
+#endif
if (uO.aflag > 2)
uO.aflag = 2;
#ifdef VMS
diff -urpN unzip-5.51.orig/unzip.h unzip-5.51/unzip.h
--- unzip-5.51.orig/unzip.h 2005-09-08
14:25:57.000000000 -0500
+++ unzip-5.51/unzip.h 2005-10-24
16:09:09.000000000 -0500
@@ -438,6 +438,9 @@ typedef struct _UzpOpts {
#ifdef MACOS
int E_flag; /* -E: [MacOS] show Mac extra field
during restoring */
#endif
+#ifdef UNIX
+ int E_flag; /* -E: [Unix] restore extended
attributes */
+#endif
int fflag; /* -f: "freshen" (extract only newer
files) */
#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
int acorn_nfs_ext; /* -F: RISC OS types & NFS
filetype extensions */
@@ -571,6 +574,7 @@ typedef struct
central_directory_file_he
#define PK_FIND 11 /* no files found */
#define PK_DISK 50 /* disk full */
#define PK_EOF 51 /* unexpected EOF */
+#define PK_XATTR 52 /* extended attributes
error */
#define IZ_CTRLC 80 /* user hit ^C to terminate
*/
#define IZ_UNSUP 81 /* no files found: all
unsup. compr/encrypt. */
diff -urpN unzip-5.51.orig/unzpriv.h unzip-5.51/unzpriv.h
--- unzip-5.51.orig/unzpriv.h 2005-09-08
14:25:57.000000000 -0500
+++ unzip-5.51/unzpriv.h 2005-10-24
16:09:09.000000000 -0500
@@ -1433,6 +1433,9 @@
#define EF_THEOSO 0x4854 /* old Theos port */
#define EF_MD5 0x4b46 /* Fred Kantor's MD5
("FK") */
#define EF_ASIUNIX 0x756e /* ASi's Unix ("nu") */
+#define EF_XATTR 0x4158 /* XATTR ("XA") */
+#define EF_XA_NAME 0x4e58 /* XATTR NAME
("XN") */
+#define EF_XA_VALUE 0x5658 /* XATTR VALUE
("XV") */
#define EB_HEADSIZE 4 /* length of extra field
block header */
#define EB_ID 0 /* offset of block ID in
header */
@@ -1459,6 +1462,8 @@
#define EB_UT_FL_ATIME (1 << 1) /* atime
present */
#define EB_UT_FL_CTIME (1 << 2) /* ctime
present */
+#define EB_XA_MINLEN 4 /* minimal XA size */
+
#define EB_FLGS_OFFS 4 /* offset of flags area
in generic compressed
extra field blocks (BEOS, MAC,
and others) */
#define EB_OS2_HLEN 4 /* size of OS2/ACL
compressed data header */
@@ -1576,6 +1581,14 @@ typedef struct iztimes {
time_t ctime; /* used for creation time; NOT
same as st_ctime */
} iztimes;
+typedef struct izxattr {
+ char *xa_name; /* xattr names list */
+ char *xa_value; /* xattr values list */
+ ssize_t xa_name_len; /* size of xa_names list */
+ ssize_t xa_value_len; /* size of xa_value list */
+ int count; /* number of xattr name and
value pairs */
+} izxattr;
+
#ifdef SET_DIR_ATTRIB
typedef struct direntry { /* head of system-specific
struct holding */
struct direntry *next; /* defered directory
attributes info */
@@ -1812,7 +1825,12 @@ int get_cdir_ent
OF((__G
int process_local_file_hdr OF((__GPRO));
unsigned ef_scan_for_izux OF((ZCONST uch
*ef_buf, unsigned ef_len,
int ef_is_c, ulg
dos_mdatetime,
+#ifdef USE_EF_XATTR
+ iztimes *z_utim, ush
*z_uidgid,
+ izxattr *z_xattr));
+#else
iztimes *z_utim, ush
*z_uidgid));
+#endif
#if (defined(RISCOS) || defined(ACORN_FTYPE_NFS))
zvoid *getRISCOSexfield OF((ZCONST uch
*ef_buf, unsigned ef_len));
#endif
@@ -1850,6 +1868,15 @@ void fnprint OF
((__G
#endif /* !SFX */
/*---------------------------------------------------------------------------
+ Functions in xattr.c:
+ ---------------------------------------------------------------------------*/
+
+int get_xattr_count(char *xa_list, int xa_list_size);
+char * get_xattr_name(char *xa_list, int xa_list_size,
int pair);
+char * get_xattr_value(char *xa_list, int xa_list_size,
int pair);
+int copy_xattr(char *xa_list, char *new_list, int pair);
+
+/*---------------------------------------------------------------------------
Functions in fileio.c:
---------------------------------------------------------------------------*/
diff -urpN unzip-5.51.orig/xattr.c unzip-5.51/xattr.c
--- unzip-5.51.orig/xattr.c 1969-12-31
18:00:00.000000000 -0600
+++ unzip-5.51/xattr.c 2005-10-24
16:12:01.000000000 -0500
@@ -0,0 +1,127 @@
+/*
+*/
+/* xattr.c
+ *
+ * Author: Debora Velarde <dvelarde@us.ibm.com>
+ * Created: Sept 14, 2005
+ */
+
+
+#define __XATTR_C /* identifies this source module */
+#define UNZIP_INTERNAL
+#include "unzip.h"
+
+int get_xattr_count(char *xa_list, int xa_list_size)
+{
+/* xattr names have the form name1.name2 */
+/* A file can have any number of xattr name pairs */
+/* This function returns the number of name pairs found
*/
+/* If list passed in is NULL or list size is less than 1
+ function retunrs 0 */
+
+ int i=0;
+ int p=0;
+
+ if ( (xa_list == (char *) NULL) || (xa_list_size < 1))
+ return 0;
+
+
+ while (i < xa_list_size) {
+ if ( xa_list[i] != '\0') {
+ i++;
+ } else {
+ i++; //move index to one past \0
+ p++;
+ }
+ }
+
+ return p;
+}
+
+char * get_xattr_name(char *xa_list, int xa_list_size,
int pair)
+{
+/* xattr names have the form name1.name2 */
+/* A file can have any number of xattr name pairs */
+/* This function returns a pointer to the specified name
pair */
+/* If list is NULL or size or pair are less than 1, then
+ function returns NULL */
+
+ int i=0;
+ int p=1;
+ char *tmp;
+
+ tmp=NULL;
+
+ if ( (xa_list == (char *) NULL) || (xa_list_size < 1) ||
(pair < 1) )
+ return NULL;
+
+ while ( (i < xa_list_size) && ( p != pair) ) {
+ if ( xa_list[i] != '\0') {
+ i++;
+ } else {
+ i++; //move index to one past \0
+ p++;
+ }
+ }
+
+ if ( (p==pair) && (i < xa_list_size) )
+ tmp=&xa_list[i];
+
+ return tmp;
+}
+
+char * get_xattr_value(char *xa_list, int xa_list_size,
int pair)
+{
+/* A file can have any number of xattr name and value
pairs */
+/* This function returns a pointer to the specified value
pair */
+/* If list is NULL or size or pair are less than 1, then
+ function returns NULL */
+
+ int i=0;
+ int p=1;
+ char *tmp;
+
+ tmp=NULL;
+
+ if ( (xa_list == (char *) NULL) || (xa_list_size < 1) ||
(pair < 1) )
+ return NULL;
+
+ while ( (i < xa_list_size) && ( p != pair) ) {
+ if ( xa_list[i] != '\0') {
+ i++;
+ } else {
+ i++; //move index to one past \0
+ p++;
+ }
+ }
+
+ if ( (p==pair) && (i < xa_list_size) )
+ tmp=&xa_list[i];
+
+ return tmp;
+}
+
+int copy_xattr(char *xa_list, char *new_list, int pair)
+{
+/* A file can have any number of xattr name and value
pairs */
+/* This function copies all the names or value from
xa_list to new_list */
+/* This function returns the size of new_list */
+/* If either list being copied or new list is NULL, then
retunrs -1 */
+/* If pair is less than 1 returns -1 */
+
+ int i=0;
+ int p=0;
+
+ if ( (xa_list == (char *) NULL) || (new_list == (char *)
NULL) || (pair < 1) )
+ return -1;
+
+ while ( p < pair ) {
+ new_list[i] = xa_list[i];
+ if ( xa_list[i] == '\0') {
+ p++;
+ }
+ i++;
+ }
+
+ return i;
+}
diff -urpN unzip-5.51.orig/zipinfo.c unzip-5.51/zipinfo.c
--- unzip-5.51.orig/zipinfo.c 2005-09-08
14:25:57.000000000 -0500
+++ unzip-5.51/zipinfo.c 2005-10-24
16:09:09.000000000 -0500
@@ -330,6 +330,8 @@ static ZCONST char Far efMD5
[] = "Fred K
static ZCONST char Far efASiUnix[] = "ASi Unix";
static ZCONST char Far efTandem[] = "Tandem NSK";
static ZCONST char Far efTheos[] = "Theos";
+static ZCONST char Far efXAname[] = "xattr name";
+static ZCONST char Far efXAvalue[] = "xattr value";
static ZCONST char Far efUnknown[] = "unknown";
static ZCONST char Far OS2EAs[] = ".\n\
@@ -935,6 +937,9 @@ static int zi_long(__G__
pEndprev) /*
#ifdef USE_EF_UT_TIME
iztimes z_utime;
#endif
+#ifdef USE_EF_XATTR
+ izxattr z_xattr;
+#endif
int error, error_in_archive=PK_COOL;
unsigned hostnum, hostver, extnum, extver,
methnum, xattr;
char workspace[12], attribs[22];
@@ -1076,7 +1081,12 @@ static int zi_long(__G__
pEndprev) /*
G.tz_is_valid &&
#endif
(ef_scan_for_izux(G.extra_field,
G.crec.extra_field_length, 1,
- G.crec.last_mod_dos_datetime,
&z_utime, NULL)
+ G.crec.last_mod_dos_datetime,
&z_utime,
+#ifdef USE_EF_XATTR
+ NULL, &z_xattr)
+#else
+ NULL)
+#endif
& EB_UT_FL_MTIME))
{
TIMET_TO_NATIVE(z_utime.mtime) /* NOP
unless MSC 7.0 or Macintosh */
@@ -1422,6 +1432,12 @@ static int zi_long(__G__
pEndprev) /*
#endif
ef_fieldname = efTheos;
break;
+ case EF_XA_NAME:
+ ef_fieldname = efXAname;
+ break;
+ case EF_XA_VALUE:
+ ef_fieldname = efXAvalue;
+ break;
default:
ef_fieldname = efUnknown;
break;
@@ -1755,6 +1771,9 @@ static int zi_short(__G) /*
return PK-
iztimes z_utime;
time_t *z_modtim;
#endif
+#ifdef USE_EF_XATTR
+ izxattr z_xattr;
+#endif
int k, error, error_in_archive=PK_COOL;
unsigned hostnum, hostver, methnum, xattr;
char *p, workspace[12], attribs[16];
@@ -2053,7 +2072,12 @@ static int zi_short(__G) /*
return PK-
G.tz_is_valid &&
#endif
(ef_scan_for_izux(G.extra_field,
G.crec.extra_field_length, 1,
- G.crec.last_mod_dos_datetime,
&z_utime, NULL)
+
G.crec.last_mod_dos_datetime, &z_utime,
+#ifdef USE_EF_XATTR
+ NULL, &z_xattr)
+#else
+ NULL)
+#endif
& EB_UT_FL_MTIME)
? &z_utime.mtime : NULL;
TIMET_TO_NATIVE(z_utime.mtime) /* NOP
unless MSC 7.0 or Macintosh */
Logged In: YES
user_id=1172496
Originator: NO
This probably won't make Zip 3.0 but should be one of the items at the top of the list for Zip 3.1. One issue is the maximum size of an extra field block of 64k which is for all extra fields for the entry.
Logged In: YES
user_id=1172496
Originator: NO
After looking through this solution, it was determined that a single extra field similar to other extra fields that store attributes should be used for storing this information. We have an initial design that also addresses the need for 32-bit UIDs in Unix. This may get implemented in the next few months in Zip 3.1, if it doesn't make it out in Zip 3.0 now scheduled for maybe November if testing goes well.
Logged In: YES
user_id=1172496
Originator: NO
It looks like this issue will be discussed shortly.
This may be worked in the next few months.