Zip64 write support; zipcmp -p compares comments.
diff --git a/lib/zip.h b/lib/zip.h index 2edec7b..4f00f68 100644 --- a/lib/zip.h +++ b/lib/zip.h
@@ -77,6 +77,7 @@ #define ZIP_FL_NAME_STRICT 128 /* follow specification strictly */ #define ZIP_FL_LOCAL 256 /* in local header */ #define ZIP_FL_CENTRAL 512 /* in central directory */ +/* 1024 reserved for internal use */ /* archive global flags flags */ @@ -86,6 +87,7 @@ /* create a new extra field */ +#define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX #define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX /* flags for compression and encryption sources */ @@ -213,6 +215,8 @@ struct zip_file; struct zip_source; +typedef zip_uint32_t zip_flags_t; + typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t, enum zip_source_cmd); @@ -223,8 +227,8 @@ 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_delete_file_extra_field(struct zip *, zip_uint64_t, zip_uint32_t, zip_uint16_t); -ZIP_EXTERN int zip_delete_file_extra_field_by_id(struct zip *, zip_uint64_t, zip_uint32_t, zip_uint16_t, zip_uint16_t); +ZIP_EXTERN int zip_delete_file_extra_field(struct zip *, zip_uint64_t, zip_flags_t, zip_uint16_t); +ZIP_EXTERN int zip_delete_file_extra_field_by_id(struct zip *, zip_uint64_t, zip_flags_t, zip_uint16_t, zip_uint16_t); 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); @@ -246,10 +250,10 @@ 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 zip_uint8_t *zip_get_file_extra_field(struct zip *, zip_uint64_t, zip_uint32_t, zip_uint16_t, zip_uint16_t *, zip_uint16_t *); -ZIP_EXTERN const zip_uint8_t *zip_get_file_extra_field_by_id(struct zip *, zip_uint64_t, zip_uint32_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *); -ZIP_EXTERN zip_int16_t zip_get_file_num_extra_fields(struct zip *, zip_uint64_t, zip_uint32_t); -ZIP_EXTERN zip_int16_t zip_get_file_num_extra_fields_by_id(struct zip *, zip_uint64_t, zip_uint32_t, zip_uint16_t); +ZIP_EXTERN const zip_uint8_t *zip_get_file_extra_field(struct zip *, zip_uint64_t, zip_flags_t, zip_uint16_t, zip_uint16_t *, zip_uint16_t *); +ZIP_EXTERN const zip_uint8_t *zip_get_file_extra_field_by_id(struct zip *, zip_uint64_t, zip_flags_t, zip_uint16_t, zip_uint16_t, zip_uint16_t *); +ZIP_EXTERN zip_int16_t zip_get_file_num_extra_fields(struct zip *, zip_uint64_t, zip_flags_t); +ZIP_EXTERN zip_int16_t zip_get_file_num_extra_fields_by_id(struct zip *, zip_uint64_t, zip_flags_t, zip_uint16_t); ZIP_EXTERN const char *zip_get_name(struct zip *, zip_uint64_t, int); ZIP_EXTERN zip_uint64_t zip_get_num_entries(struct zip *, int); ZIP_EXTERN int zip_get_num_files(struct zip *); /* deprecated, use zip_get_num_entries instead */ @@ -264,7 +268,7 @@ const char *, int); ZIP_EXTERN int zip_set_file_compression(struct zip *, zip_uint64_t, zip_int32_t, zip_uint32_t); -ZIP_EXTERN int zip_set_file_extra_field(struct zip *, zip_uint64_t, zip_uint32_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_uint16_t); +ZIP_EXTERN int zip_set_file_extra_field(struct zip *, zip_uint64_t, zip_flags_t, zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_uint16_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 *,
diff --git a/lib/zip_close.c b/lib/zip_close.c index aee16aa..bd0d9b7 100644 --- a/lib/zip_close.c +++ b/lib/zip_close.c
@@ -51,8 +51,10 @@ -static int add_data(struct zip *, struct zip_source *, struct zip_dirent *, - FILE *); +/* max deflate size increase: size + ceil(size/16k)*5+6 */ +#define MAX_DEFLATE_SIZE_32 4293656963 + +static int add_data(struct zip *, struct zip_source *, struct zip_dirent *, FILE *); static int copy_data(FILE *, off_t, FILE *, struct zip_error *); static int copy_source(struct zip *, struct zip_source *, FILE *); static int write_cdir(struct zip *, const struct zip_filelist *, int, FILE *); @@ -75,10 +77,9 @@ int reopen_on_error; int new_torrentzip; enum zip_encoding_type com_enc, enc; - int changed, is_zip64; + int changed; reopen_on_error = 0; - is_zip64 = 0; /* for wiz */ if (za == NULL) return -1; @@ -201,7 +202,7 @@ else { zip_uint64_t offset; - if (_zip_dirent_write(de, out, 1, &za->error) < 0) { + if (_zip_dirent_write(de, out, ZIP_FL_LOCAL, &za->error) < 0) { error = 1; break; } @@ -278,26 +279,53 @@ struct zip_stat st; struct zip_source *s2; int ret; + int is_zip64; + zip_flags_t flags; if (zip_source_stat(src, &st) < 0) { _zip_error_set_from_source(&za->error, src); return -1; } - offstart = ftello(ft); - - if (_zip_dirent_write(de, ft, 1, &za->error) < 0) - return -1; - if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) { st.valid |= ZIP_STAT_COMP_METHOD; st.comp_method = ZIP_CM_STORE; } - if (de->comp_method == ZIP_CM_DEFAULT) { - /* XXX: set changed? */ - de->comp_method = ZIP_CM_DEFLATE; + if (de->comp_method == ZIP_CM_DEFAULT && st.comp_method != ZIP_CM_STORE) + de->comp_method = st.comp_method; + else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) { + st.valid |= ZIP_STAT_COMP_SIZE; + st.comp_size = st.size; } + else { + /* we'll recompress */ + st.valid &= ~ZIP_STAT_COMP_SIZE; + } + + + flags = ZIP_EF_LOCAL; + + if ((st.valid & ZIP_STAT_SIZE) == 0) + flags |= ZIP_FL_FORCE_ZIP64; + else { + de->uncomp_size = st.size; + + if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) { + if ((((de->comp_method == ZIP_CM_DEFLATE || de->comp_method == ZIP_CM_DEFAULT) && st.size > MAX_DEFLATE_SIZE_32) + || de->comp_method != ZIP_CM_STORE && de->comp_method != ZIP_CM_DEFLATE && de->comp_method != ZIP_CM_DEFAULT)) + flags |= ZIP_FL_FORCE_ZIP64; + } + else + de->comp_size = st.comp_size; + } + + + offstart = ftello(ft); + + if ((is_zip64=_zip_dirent_write(de, ft, flags, &za->error)) < 0) + return -1; + if (st.comp_method == ZIP_CM_STORE || (de->comp_method != ZIP_CM_DEFAULT && st.comp_method != de->comp_method)) { struct zip_source *s_store, *s_crc; @@ -369,7 +397,15 @@ return -1; } - de->last_mod = st.mtime; + if ((st.valid & (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD|ZIP_STAT_CRC|ZIP_STAT_SIZE)) { + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; + } + + if (st.valid & ZIP_STAT_MTIME) + de->last_mod = st.mtime; + else + time(&de->last_mod); de->comp_method = st.comp_method; de->crc = st.crc; de->uncomp_size = st.size; @@ -378,9 +414,16 @@ if (zip_get_archive_flag(za, ZIP_AFL_TORRENT, 0)) _zip_dirent_torrent_normalize(de); - if (_zip_dirent_write(de, ft, 1, &za->error) < 0) + if ((ret=_zip_dirent_write(de, ft, flags, &za->error)) < 0) return -1; - + + if (is_zip64 != ret) { + /* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */ + _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; + } + + if (fseeko(ft, offend, SEEK_SET) < 0) { _zip_error_set(&za->error, ZIP_ER_SEEK, errno); return -1;
diff --git a/lib/zip_dirent.c b/lib/zip_dirent.c index 0e025a0..523c524 100644 --- a/lib/zip_dirent.c +++ b/lib/zip_dirent.c
@@ -132,27 +132,53 @@ zip_uint64_t offset, size; struct zip_string *comment; int i; + int is_zip64; + int ret; offset = ftello(fp); + is_zip64 = 0; + for (i=0; i<survivors; i++) { struct zip_entry *entry = za->entry+filelist[i].idx; - if (_zip_dirent_write(entry->changes ? entry->changes : entry->orig, fp, 0, &za->error) != 0) + if ((ret=_zip_dirent_write(entry->changes ? entry->changes : entry->orig, fp, ZIP_FL_CENTRAL, &za->error)) < 0) return -1; + if (ret) + is_zip64 = 1; } size = ftello(fp) - offset; - - /* EOCD64 */ + + if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX) + is_zip64 = 1; + + if (is_zip64) { + fwrite(EOCD64_MAGIC, 1, 4, fp); + _zip_write8(EOCD64LEN, fp); + _zip_write2(45, fp); + _zip_write2(45, fp); + _zip_write4(1, fp); + _zip_write4(1, fp); + _zip_write8(survivors, fp); + _zip_write8(survivors, fp); + _zip_write8(size, fp); + _zip_write8(offset, fp); + + fwrite(EOCD64LOC_MAGIC, 1, 4, fp); + _zip_write4(1, fp); + _zip_write8(offset+size, fp); + _zip_write4(1, fp); + + } /* clearerr(fp); */ fwrite(EOCD_MAGIC, 1, 4, fp); _zip_write4(0, fp); - _zip_write2((unsigned short)survivors, fp); - _zip_write2((unsigned short)survivors, fp); - _zip_write4(size, fp); - _zip_write4(offset, fp); + _zip_write2(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors, fp); + _zip_write2(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors, fp); + _zip_write4(size >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : size, fp); + _zip_write4(offset >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : offset, fp); comment = za->comment_changed ? za->comment_changes : za->comment_orig; @@ -240,6 +266,18 @@ +int +_zip_dirent_needs_zip64(const struct zip_dirent *de, zip_flags_t flags) +{ + if (de->uncomp_size >= ZIP_UINT32_MAX || de->comp_size >= ZIP_UINT32_MAX + || ((flags & ZIP_FL_CENTRAL) && de->offset >= ZIP_UINT32_MAX)) + return 1; + + return 0; +} + + + struct zip_dirent * _zip_dirent_new(void) { @@ -435,6 +473,8 @@ if (zde->disk_number == ZIP_UINT16_MAX) zde->disk_number = _zip_read4(&ef); } + + zde->extra_fields = _zip_ef_delete_by_id(zde->extra_fields, ZIP_EF_ZIP64, ZIP_EXTRA_FIELD_ALL, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL); } if (bufp) @@ -532,27 +572,31 @@ -/* _zip_dirent_write(zde, fp, localp, error): +/* _zip_dirent_write(zde, fp, flags, error): Writes zip directory entry zde to file fp. - If localp != 0, it writes a local header instead of a central - directory entry. + If flags & ZIP_EF_LOCAL, it writes a local header instead of a central + directory entry. If flags & ZIP_EF_FORCE_ZIP64, a ZIP64 extra field is written, even if not needed. - Returns 0 if successful. On error, error is filled in and -1 is + Returns 0 if successful, 1 if successful and wrote ZIP64 extra field. On error, error is filled in and -1 is returned. */ int -_zip_dirent_write(struct zip_dirent *zde, FILE *fp, int localp, +_zip_dirent_write(struct zip_dirent *zde, FILE *fp, int flags, struct zip_error *error) { unsigned short dostime, dosdate; + zip_uint16_t zip64_ef_size; - fwrite(localp ? LOCAL_MAGIC : CENTRAL_MAGIC, 1, 4, fp); + zip64_ef_size = 0; - if (!localp) + fwrite((flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 1, 4, fp); + + + if ((flags & ZIP_FL_LOCAL) == 0) _zip_write2(zde->version_madeby, fp); - _zip_write2(zde->version_needed, fp); + _zip_write2(zde->version_needed, fp); /* XXX: at least 4.5 if zip64 */ _zip_write2(zde->bitflags, fp); _zip_write2(zde->comp_method, fp); @@ -561,27 +605,58 @@ _zip_write2(dosdate, fp); _zip_write4(zde->crc, fp); - _zip_write4(zde->comp_size, fp); - _zip_write4(zde->uncomp_size, fp); - + if (zde->comp_size < ZIP_UINT32_MAX) + _zip_write4(zde->comp_size, fp); + else { + _zip_write4(ZIP_UINT32_MAX-1, fp); + zip64_ef_size += 8; + } + if (zde->uncomp_size < ZIP_UINT32_MAX) + _zip_write4(zde->uncomp_size, fp); + else { + _zip_write4(ZIP_UINT32_MAX-1, fp); + zip64_ef_size += 8; + } + + if (flags & ZIP_FL_LOCAL) { + if (zip64_ef_size > 0 || (flags & ZIP_FL_FORCE_ZIP64)) + zip64_ef_size = 16; + } + else if (zde->offset >= ZIP_UINT32_MAX) + zip64_ef_size += 8; + _zip_write2(_zip_string_length(zde->filename), fp); - _zip_write2(_zip_ef_size(zde->extra_fields, localp ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL), fp); + _zip_write2(_zip_ef_size(zde->extra_fields, flags) + (zip64_ef_size ? (zip64_ef_size+4) : 0), fp); - if (!localp) { + if ((flags & ZIP_FL_LOCAL) == 0) { _zip_write2(_zip_string_length(zde->comment), fp); _zip_write2(zde->disk_number, fp); _zip_write2(zde->int_attrib, fp); _zip_write4(zde->ext_attrib, fp); - _zip_write4(zde->offset, fp); + if (zde->offset < ZIP_UINT32_MAX) + _zip_write4(zde->offset, fp); + else + _zip_write4(ZIP_UINT32_MAX-1, fp); } if (zde->filename) _zip_string_write(zde->filename, fp); if (zde->extra_fields) - _zip_ef_write(zde->extra_fields, localp ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, fp); + _zip_ef_write(zde->extra_fields, flags, fp); - if (!localp) { + if (zip64_ef_size > 0) { + _zip_write2(ZIP_EF_ZIP64, fp); + _zip_write2(zip64_ef_size, fp); + if ((flags & ZIP_EF_LOCAL) || zde->uncomp_size >= ZIP_UINT32_MAX) + _zip_write8(zde->uncomp_size, fp); + if ((flags & ZIP_EF_LOCAL) || zde->comp_size >= ZIP_UINT32_MAX) + _zip_write8(zde->comp_size, fp); + if (((flags & ZIP_EF_LOCAL) == 0) && zde->offset >= ZIP_UINT32_MAX) + _zip_write8(zde->offset, fp); + } + + if ((flags & ZIP_FL_LOCAL) == 0) { if (zde->comment) _zip_string_write(zde->comment, fp); } @@ -591,7 +666,7 @@ return -1; } - return 0; + return zip64_ef_size > 0; } @@ -765,6 +840,23 @@ void +_zip_write8(zip_uint64_t i, FILE *fp) +{ + putc(i&0xff, fp); + putc((i>>8)&0xff, fp); + putc((i>>16)&0xff, fp); + putc((i>>24)&0xff, fp); + putc((i>>32)&0xff, fp); + putc((i>>40)&0xff, fp); + putc((i>>48)&0xff, fp); + putc((i>>56)&0xff, fp); + + return; +} + + + +void _zip_u2d_time(time_t time, unsigned short *dtime, unsigned short *ddate) { struct tm *tm;
diff --git a/lib/zip_extra_field.c b/lib/zip_extra_field.c index 1c5a414..9799880 100644 --- a/lib/zip_extra_field.c +++ b/lib/zip_extra_field.c
@@ -41,6 +41,45 @@ +struct zip_extra_field * +_zip_ef_delete_by_id(struct zip_extra_field *ef, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags) +{ + struct zip_extra_field *head, *prev; + int i; + + i = 0; + head = ef; + prev = NULL; + for (; ef; ef=(prev ? prev->next : head)) { + if ((ef->flags & flags & ZIP_EF_BOTH) && ef->id == id) { + if (id_idx == ZIP_EXTRA_FIELD_ALL || i == id_idx) { + ef->flags &= ~(flags & ZIP_EF_BOTH); + if ((ef->flags & ZIP_EF_BOTH) == 0) { + if (prev) + prev->next = ef->next; + else + head = ef->next; + ef->next = NULL; + _zip_ef_free(ef); + + if (id_idx == ZIP_EXTRA_FIELD_ALL) + continue; + } + } + + i++; + if (i > id_idx) + break; + } + prev = ef; + } + + return head; +} + + + + void _zip_ef_free(struct zip_extra_field *ef) { @@ -57,7 +96,7 @@ const zip_uint8_t * -_zip_ef_get_by_id(struct zip_extra_field *ef, zip_uint16_t *lenp, zip_uint16_t id, zip_uint16_t id_idx, zip_uint16_t flags, struct zip_error *error) +_zip_ef_get_by_id(struct zip_extra_field *ef, zip_uint16_t *lenp, zip_uint16_t id, zip_uint16_t id_idx, zip_flags_t flags, struct zip_error *error) { static const zip_uint8_t empty[1]; @@ -123,7 +162,7 @@ struct zip_extra_field * -_zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_uint16_t flags) +_zip_ef_new(zip_uint16_t id, zip_uint16_t size, const zip_uint8_t *data, zip_flags_t flags) { struct zip_extra_field *ef; @@ -149,7 +188,7 @@ struct zip_extra_field * -_zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_uint16_t flags, struct zip_error *error) +_zip_ef_parse(const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags, struct zip_error *error) { struct zip_extra_field *ef, *ef2, *ef_head; int i; @@ -194,7 +233,7 @@ zip_uint16_t -_zip_ef_size(struct zip_extra_field *ef, zip_uint16_t flags) +_zip_ef_size(struct zip_extra_field *ef, zip_flags_t flags) { zip_uint16_t size; @@ -210,7 +249,7 @@ void -_zip_ef_write(struct zip_extra_field *ef, zip_uint16_t flags, FILE *f) +_zip_ef_write(struct zip_extra_field *ef, zip_flags_t flags, FILE *f) { for (; ef; ef=ef->next) { if (ef->flags & flags & ZIP_EF_BOTH) {
diff --git a/lib/zip_extra_field_api.c b/lib/zip_extra_field_api.c index 4aafa2e..17bbd60 100644 --- a/lib/zip_extra_field_api.c +++ b/lib/zip_extra_field_api.c
@@ -177,6 +177,9 @@ ZIP_EXTERN int zip_set_file_extra_field(struct zip *za, zip_uint64_t idx, zip_uint32_t flags, zip_uint16_t ef_id, zip_uint16_t ef_idx, const zip_uint8_t *data, zip_uint16_t len) { + /* XXX: ZIP_ER_INVAL if ef_id == ZIP_EF_ZIP64 */ + /* XXX: size of ef + new <= ZIP_UINT16_MAX */ + /* XXX */ return -1; }
diff --git a/lib/zip_source_crc.c b/lib/zip_source_crc.c index 59e8a19..d8cc6ce 100644 --- a/lib/zip_source_crc.c +++ b/lib/zip_source_crc.c
@@ -139,7 +139,10 @@ After all, this only works for uncompressed data. */ st->size = ctx->size; st->crc = ctx->crc; - st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC; + st->comp_size = ctx->size; + st->comp_method = ZIP_CM_STORE; + st->encryption_method = ZIP_EM_NONE; + st->valid |= ZIP_STAT_SIZE|ZIP_STAT_CRC|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_ENCRYPTION_METHOD;; } } return 0;
diff --git a/lib/zipint.h b/lib/zipint.h index 0c334c5..b9f26a7 100644 --- a/lib/zipint.h +++ b/lib/zipint.h
@@ -197,6 +197,8 @@ #define ZIP_EF_CENTRAL ZIP_FL_CENTRAL /* include in central directory */ #define ZIP_EF_BOTH (ZIP_EF_LOCAL|ZIP_EF_CENTRAL) /* include in both */ +#define ZIP_FL_FORCE_ZIP64 1024 /* force zip64 extra field (_zip_dirent_write) */ + /* encoding type */ enum zip_encoding_type { @@ -371,6 +373,7 @@ void _zip_dirent_free(struct zip_dirent *); void _zip_dirent_finalize(struct zip_dirent *); void _zip_dirent_init(struct zip_dirent *); +int _zip_dirent_needs_zip64(const struct zip_dirent *, zip_flags_t); struct zip_dirent *_zip_dirent_new(void); int _zip_dirent_read(struct zip_dirent *, FILE *, const unsigned char **, zip_uint32_t *, int, struct zip_error *); @@ -378,13 +381,14 @@ void _zip_dirent_torrent_normalize(struct zip_dirent *); int _zip_dirent_write(struct zip_dirent *, FILE *, int, struct zip_error *); +struct zip_extra_field *_zip_ef_delete_by_id(struct zip_extra_field *, zip_uint16_t, zip_uint16_t, zip_flags_t); void _zip_ef_free(struct zip_extra_field *); -const zip_uint8_t *_zip_ef_get_by_id(struct zip_extra_field *, zip_uint16_t *, zip_uint16_t, zip_uint16_t, zip_uint16_t, struct zip_error *); +const zip_uint8_t *_zip_ef_get_by_id(struct zip_extra_field *, zip_uint16_t *, zip_uint16_t, zip_uint16_t, zip_flags_t, struct zip_error *); struct zip_extra_field *_zip_ef_merge(struct zip_extra_field *, struct zip_extra_field *); -struct zip_extra_field *_zip_ef_new(zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_uint16_t); -struct zip_extra_field *_zip_ef_parse(const zip_uint8_t *, zip_uint16_t, zip_uint16_t, struct zip_error *); -zip_uint16_t _zip_ef_size(struct zip_extra_field *, zip_uint16_t); -void _zip_ef_write(struct zip_extra_field *, zip_uint16_t, FILE *); +struct zip_extra_field *_zip_ef_new(zip_uint16_t, zip_uint16_t, const zip_uint8_t *, zip_flags_t); +struct zip_extra_field *_zip_ef_parse(const zip_uint8_t *, zip_uint16_t, zip_flags_t, struct zip_error *); +zip_uint16_t _zip_ef_size(struct zip_extra_field *, zip_flags_t); +void _zip_ef_write(struct zip_extra_field *, zip_flags_t, FILE *); void _zip_entry_finalize(struct zip_entry *); void _zip_entry_init(struct zip_entry *); @@ -448,6 +452,7 @@ void _zip_write2(zip_uint16_t, FILE *); void _zip_write4(zip_uint32_t, FILE *); +void _zip_write8(zip_uint64_t, FILE *); #endif /* zipint.h */