Beginnings of torrentzip support: - add archive global flags, with support for getting and setting them. - detect wether archive is torrentzipped --HG-- branch : HEAD
diff --git a/lib/Makefile.am b/lib/Makefile.am index ec794e4..a55920c 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am
@@ -30,6 +30,7 @@ zip_fread.c \ zip_free.c \ zip_get_archive_comment.c \ + zip_get_archive_flag.c \ zip_get_file_comment.c \ zip_get_num_files.c \ zip_get_name.c \ @@ -40,6 +41,7 @@ zip_rename.c \ zip_replace.c \ zip_set_archive_comment.c \ + zip_set_archive_flag.c \ zip_set_file_comment.c \ zip_source_buffer.c \ zip_source_file.c \
diff --git a/lib/zip.h b/lib/zip.h index 3342b10..014df7a 100644 --- a/lib/zip.h +++ b/lib/zip.h
@@ -3,7 +3,7 @@ /* zip.h -- exported declarations. - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2008 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> @@ -66,6 +66,10 @@ #define ZIP_FL_COMPRESSED 4 /* read compressed data */ #define ZIP_FL_UNCHANGED 8 /* use original data, ignoring changes */ +/* archive global flags flags */ + +#define ZIP_AFL_TORRENT 1 /* torrent zipped */ + /* libzip error codes */ #define ZIP_ER_OK 0 /* N No error */ @@ -188,6 +192,7 @@ ZIP_EXTERN struct zip_file *zip_fopen_index(struct zip *, int, int); ZIP_EXTERN ssize_t zip_fread(struct zip_file *, void *, size_t); ZIP_EXTERN const char *zip_get_archive_comment(struct zip *, int *, int); +ZIP_EXTERN int zip_get_archive_flag(struct zip *, int, int); ZIP_EXTERN const char *zip_get_file_comment(struct zip *, int, int *, int); ZIP_EXTERN const char *zip_get_name(struct zip *, int, int); ZIP_EXTERN int zip_get_num_files(struct zip *); @@ -196,6 +201,7 @@ ZIP_EXTERN int zip_rename(struct zip *, int, const char *); ZIP_EXTERN int zip_replace(struct zip *, int, struct zip_source *); ZIP_EXTERN int zip_set_archive_comment(struct zip *, const char *, int); +ZIP_EXTERN int zip_set_archive_flag(struct zip *, int, int); ZIP_EXTERN int zip_set_file_comment(struct zip *, int, const char *, int); ZIP_EXTERN struct zip_source *zip_source_buffer(struct zip *, const void *, off_t, int);
diff --git a/lib/zip_new.c b/lib/zip_new.c index c72a604..3e8ccee 100644 --- a/lib/zip_new.c +++ b/lib/zip_new.c
@@ -64,6 +64,7 @@ za->entry = NULL; za->nfile = za->nfile_alloc = 0; za->file = NULL; + za->flags = za->ch_flags = 0; return za; }
diff --git a/lib/zip_open.c b/lib/zip_open.c index 2d6590f..d3306c8 100644 --- a/lib/zip_open.c +++ b/lib/zip_open.c
@@ -1,6 +1,6 @@ /* zip_open.c -- open zip archive - Copyright (C) 1999-2007 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2008 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> @@ -35,6 +35,7 @@ #include <sys/stat.h> #include <errno.h> +#include <limits.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -44,6 +45,7 @@ static void set_error(int *, struct zip_error *, int); static struct zip *_zip_allocate_new(const char *, int *); static int _zip_checkcons(FILE *, struct zip_cdir *, struct zip_error *); +static void _zip_check_torrentzip(struct zip *); static struct zip_cdir *_zip_find_central_dir(FILE *, int, int *, off_t); static int _zip_file_exists(const char *, int, int *); static int _zip_headercomp(struct zip_dirent *, int, @@ -114,6 +116,9 @@ for (i=0; i<cdir->nentry; i++) _zip_entry_new(za); + _zip_check_torrentzip(za); + za->ch_flags = za->flags; + return za; } @@ -193,13 +198,14 @@ return NULL; } - if (cd->comment_len) + if (cd->comment_len) { if ((cd->comment=(char *)_zip_memdup(eocd+EOCDLEN, cd->comment_len, error)) == NULL) { free(cd); return NULL; } + } cdp = eocd; if (cd->size < (unsigned int)(eocd-buf)) { @@ -297,6 +303,52 @@ +/* _zip_check_torrentzip: + check wether ZA has a valid TORRENTZIP comment, i.e. is torrentzipped */ + +static void +_zip_check_torrentzip(struct zip *za) +{ + uLong crc_got, crc_should; + char *end; + Bytef buf[BUFSIZE]; + unsigned int n, remain; + + if (za->zp == NULL || za->cdir == NULL) + return; + + if (za->cdir->comment_len != TORRENT_SIG_LEN+8 + || strncmp(za->cdir->comment, TORRENT_SIG, TORRENT_SIG_LEN) != 0) + return; + + errno = 0; + crc_should = strtoul(za->cdir->comment+TORRENT_SIG_LEN, &end, 16); + if ((crc_should == UINT_MAX && errno != 0) || (end && *end)) + return; + + crc_got = crc32(0L, Z_NULL, 0); + + if (fseek(za->zp, za->cdir->offset, SEEK_SET) != 0) + return; + remain = za->cdir->size; + + while (remain > 0) { + n = remain > BUFSIZE ? BUFSIZE : remain; + if ((n=fread(buf, 1, n, za->zp)) <= 0) + return; + + crc_got = crc32(crc_got, buf, n); + + remain -= n; + } + + if (crc_got == crc_should) + za->flags |= ZIP_AFL_TORRENT; +} + + + + /* _zip_headercomp: compares two headers h1 and h2; if they are local headers, set local1p or local2p respectively to 1, else 0. Return 0 if they
diff --git a/lib/zipint.h b/lib/zipint.h index 775a036..7107585 100644 --- a/lib/zipint.h +++ b/lib/zipint.h
@@ -70,6 +70,8 @@ #define LOCAL_MAGIC "PK\3\4" #define EOCD_MAGIC "PK\5\6" #define DATADES_MAGIC "PK\7\8" +#define TORRENT_SIG "TORRENTZIPPED-" +#define TORRENT_SIG_LEN 14 #define CDENTRYSIZE 46u #define LENTRYSIZE 30 #define MAXCOMLEN 65536 @@ -111,6 +113,9 @@ FILE *zp; /* file */ struct zip_error error; /* error information */ + unsigned int flags; /* archive global flags */ + unsigned int ch_flags; /* changed archive global flags */ + struct zip_cdir *cdir; /* central directory */ char *ch_comment; /* changed archive comment */ int ch_comment_len; /* length of changed zip archive