Update ZIP container code, now things are working...

pull/193/head
Michael Sweet 7 years ago
parent 7c2551e996
commit 4d322880f4
  1. 4
      config.h.in
  2. 4
      configure.ac
  3. 50
      mxmldoc.c
  4. 4
      xcode/mxml.xcodeproj/project.pbxproj
  5. 148
      zipc.c
  6. 1
      zipc.h

@ -45,10 +45,10 @@
/* /*
* Do we have libarchive's archive.h header? * Do we have <zlib.h>?
*/ */
#undef HAVE_ARCHIVE_H #undef HAVE_ZLIB_H
/* /*

@ -117,7 +117,9 @@ if test $ac_cv_c_long_long = yes; then
fi fi
dnl EPUB support (via libz and zipc) dnl EPUB support (via libz and zipc)
AC_SEARCH_LIBS(gzgets,z,[LIBS="-lz $LIBS"]) AC_SEARCH_LIBS(gzgets,z,[
AC_DEFINE(HAVE_ZLIB_H)
LIBS="-lz $LIBS"])
dnl Threading support dnl Threading support
AC_ARG_ENABLE(threads, [ --enable-threads enable multi-threading support]) AC_ARG_ENABLE(threads, [ --enable-threads enable multi-threading support])

@ -622,7 +622,7 @@ main(int argc, /* I - Number of command-line args */
break; break;
case OUTPUT_TOKENS : case OUTPUT_TOKENS :
fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" fputs("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<Tokens version=\"1.0\">\n", stdout); "<Tokens version=\"1.0\">\n", stdout);
write_tokens(stdout, mxmldoc, path); write_tokens(stdout, mxmldoc, path);
@ -3274,7 +3274,7 @@ write_description(
else if (*ptr & 128) else if (*ptr & 128)
{ {
/* /*
* Convert UTF-8 to Unicode constant... * Convert utf-8 to Unicode constant...
*/ */
int ch; /* Unicode character */ int ch; /* Unicode character */
@ -3422,14 +3422,14 @@ write_epub(const char *section, /* I - Section */
zipc_file_t *epubf; /* File in EPUB ZIP container */ zipc_file_t *epubf; /* File in EPUB ZIP container */
char xhtmlfile[1024], /* XHTML output filename */ char xhtmlfile[1024], /* XHTML output filename */
*xhtmlptr; /* Pointer into output filename */ *xhtmlptr; /* Pointer into output filename */
mxml_node_t *content_opf, /* content.opf file */ mxml_node_t *package_opf, /* package_opf file */
*package, /* package node */ *package, /* package node */
*metadata, /* metadata node */ *metadata, /* metadata node */
*manifest, /* manifest node */ *manifest, /* manifest node */
*spine, /* spine node */ *spine, /* spine node */
*temp; /* Other (leaf) node */ *temp; /* Other (leaf) node */
char identifier[256], /* dc:identifier string */ char identifier[256], /* dc:identifier string */
*content_opf_string; /* content.opf file as a string */ *package_opf_string; /* package_opf file as a string */
toc_t *toc; /* Table of contents */ toc_t *toc; /* Table of contents */
toc_entry_t *tentry; /* Current table of contents */ toc_entry_t *tentry; /* Current table of contents */
mxml_node_t *toc_ncx, /* toc.ncx file */ mxml_node_t *toc_ncx, /* toc.ncx file */
@ -3450,7 +3450,7 @@ write_epub(const char *section, /* I - Section */
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<container xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\" version=\"1.0\">\n" "<container xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\" version=\"1.0\">\n"
" <rootfiles>\n" " <rootfiles>\n"
" <rootfile full-path=\"OEBPS/content.opf\" media-type=\"application/oebps-package+xml\"/>\n" " <rootfile full-path=\"OEBPS/package.opf\" media-type=\"application/oebps-package+xml\"/>\n"
" </rootfiles>\n" " </rootfiles>\n"
"</container>\n"; "</container>\n";
@ -3762,7 +3762,7 @@ write_epub(const char *section, /* I - Section */
fclose(fp); fclose(fp);
/* /*
* Now make the content.opf file... * Now make the package_opf file...
*/ */
if ((epubptr = strrchr(epubfile, '/')) != NULL) if ((epubptr = strrchr(epubfile, '/')) != NULL)
@ -3773,9 +3773,9 @@ write_epub(const char *section, /* I - Section */
if ((epubptr = strstr(epubbase, ".epub")) != NULL) if ((epubptr = strstr(epubbase, ".epub")) != NULL)
*epubptr = '\0'; *epubptr = '\0';
content_opf = mxmlNewXML("1.0"); package_opf = mxmlNewXML("1.0");
package = mxmlNewElement(content_opf, "package"); package = mxmlNewElement(package_opf, "package");
mxmlElementSetAttr(package, "xmlns", "http://www.idpf.org/2007/opf"); mxmlElementSetAttr(package, "xmlns", "http://www.idpf.org/2007/opf");
mxmlElementSetAttr(package, "unique-identifier", epubbase); mxmlElementSetAttr(package, "unique-identifier", epubbase);
mxmlElementSetAttr(package, "version", "3.0"); mxmlElementSetAttr(package, "version", "3.0");
@ -3810,14 +3810,14 @@ write_epub(const char *section, /* I - Section */
manifest = mxmlNewElement(package, "manifest"); manifest = mxmlNewElement(package, "manifest");
temp = mxmlNewElement(manifest, "item"); // temp = mxmlNewElement(manifest, "item");
mxmlElementSetAttr(temp, "id", "ncx"); // mxmlElementSetAttr(temp, "id", "ncx");
mxmlElementSetAttr(temp, "href", "toc.ncx"); // mxmlElementSetAttr(temp, "href", "toc.ncx");
mxmlElementSetAttr(temp, "media-type", "application/x-dtbncx+xml"); // mxmlElementSetAttr(temp, "media-type", "application/x-dtbncx+xml");
temp = mxmlNewElement(manifest, "item"); temp = mxmlNewElement(manifest, "item");
mxmlElementSetAttr(temp, "id", "toc"); mxmlElementSetAttr(temp, "id", "nav");
mxmlElementSetAttr(temp, "href", "toc.xhtml"); mxmlElementSetAttr(temp, "href", "nav.xhtml");
mxmlElementSetAttr(temp, "media-type", "application/xhtml+xml"); mxmlElementSetAttr(temp, "media-type", "application/xhtml+xml");
mxmlElementSetAttr(temp, "properties", "nav"); mxmlElementSetAttr(temp, "properties", "nav");
@ -3829,12 +3829,12 @@ write_epub(const char *section, /* I - Section */
// <item id="imgl" href="images/sample.png" media-type="image/png" /> // <item id="imgl" href="images/sample.png" media-type="image/png" />
spine = mxmlNewElement(package, "spine"); spine = mxmlNewElement(package, "spine");
mxmlElementSetAttr(spine, "toc", "ncx"); // mxmlElementSetAttr(spine, "toc", "ncx");
temp = mxmlNewElement(spine, "itemref"); temp = mxmlNewElement(spine, "itemref");
mxmlElementSetAttr(temp, "idref", "body"); mxmlElementSetAttr(temp, "idref", "body");
content_opf_string = mxmlSaveAllocString(content_opf, epub_ws_cb); package_opf_string = mxmlSaveAllocString(package_opf, epub_ws_cb);
/* /*
* Make the toc.ncx file... * Make the toc.ncx file...
@ -3970,14 +3970,14 @@ write_epub(const char *section, /* I - Section */
} }
unlink(xhtmlfile); unlink(xhtmlfile);
/* OEBPS/content.opf file */ /* OEBPS/package.opf file */
zipcCreateFileWithString(epub, "OEBPS/content.opf", content_opf_string); zipcCreateFileWithString(epub, "OEBPS/package.opf", package_opf_string);
/* OEBPS/toc.ncx file */ /* OEBPS/toc.ncx file */
zipcCreateFileWithString(epub, "OEBPS/toc.ncx", toc_ncx_string); // zipcCreateFileWithString(epub, "OEBPS/toc.ncx", toc_ncx_string);
/* OEBPS/toc.xhtml file */ /* OEBPS/nav.xhtml file */
epubf = zipcCreateFile(epub, "OEBPS/toc.xhtml", 1); epubf = zipcCreateFile(epub, "OEBPS/nav.xhtml", 1);
if ((fp = fopen(toc_xhtmlfile, "r")) != NULL) if ((fp = fopen(toc_xhtmlfile, "r")) != NULL)
{ {
char buffer[65536]; /* Copy buffer */ char buffer[65536]; /* Copy buffer */
@ -4370,7 +4370,7 @@ write_html(const char *section, /* I - Section */
return; return;
} }
fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" fputs("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
"<plist version=\"1.0\">\n" "<plist version=\"1.0\">\n"
"<dict>\n" "<dict>\n"
@ -4425,7 +4425,7 @@ write_html(const char *section, /* I - Section */
return; return;
} }
fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" fputs("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<DocSetNodes version=\"1.0\">\n" "<DocSetNodes version=\"1.0\">\n"
"<TOC>\n" "<TOC>\n"
"<Node id=\"0\">\n" "<Node id=\"0\">\n"
@ -4457,7 +4457,7 @@ write_html(const char *section, /* I - Section */
return; return;
} }
fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" fputs("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<Tokens version=\"1.0\">\n", out); "<Tokens version=\"1.0\">\n", out);
write_tokens(out, doc, "index.html"); write_tokens(out, doc, "index.html");
@ -5781,7 +5781,7 @@ write_string(FILE *out, /* I - Output file */
else if (*s & 128) else if (*s & 128)
{ {
/* /*
* Convert UTF-8 to Unicode constant... * Convert utf-8 to Unicode constant...
*/ */
int ch; /* Unicode character */ int ch; /* Unicode character */

@ -440,7 +440,7 @@
"DEBUG=1", "DEBUG=1",
"$(inherited)", "$(inherited)",
); );
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
@ -488,7 +488,7 @@
ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99; GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES; GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES; GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;

148
zipc.c

@ -48,25 +48,24 @@
#define ZIPC_LOCAL_HEADER 0x04034b50 /* Start of a local file header */ #define ZIPC_LOCAL_HEADER 0x04034b50 /* Start of a local file header */
#define ZIPC_DIR_HEADER 0x02014b50 /* File header in central directory */ #define ZIPC_DIR_HEADER 0x02014b50 /* File header in central directory */
#define ZIPC_DIGITAL_SIG 0x05054b50 /* Digital signature at end */
#define ZIPC_END_RECORD 0x06054b50 /* End of central directory record */ #define ZIPC_END_RECORD 0x06054b50 /* End of central directory record */
#define ZIPC_MADE_BY 0x0314 /* Version made by UNIX using zip 2.0 */ #define ZIPC_MADE_BY 0x031e /* Version made by UNIX using zip 2.0 */
#define ZIPC_VERSION 0x0014 /* Version needed: 2.0 */ #define ZIPC_DIR_VERSION 0x000a /* Version needed: 1.0 */
#define ZIPC_FILE_VERSION 0x0014 /* Version needed: 2.0 */
#define ZIPC_FLAG_NONE 0 /* No flags */
#define ZIPC_FLAG_CMASK 0x0006 /* Compression fields */
#define ZIPC_FLAG_CNORMAL 0x0000 /* Normal compression */
#define ZIPC_FLAG_CMAX 0x0002 /* Maximum compression */ #define ZIPC_FLAG_CMAX 0x0002 /* Maximum compression */
#define ZIPC_FLAG_CFAST 0x0004 /* Fast compression */
#define ZIPC_FLAG_CSUPER 0x0006 /* Super fast compression */
#define ZIPC_FLAG_DATA 0x0008 /* Length and CRC-32 fields follow data */ #define ZIPC_FLAG_DATA 0x0008 /* Length and CRC-32 fields follow data */
#define ZIPC_COMP_STORE 0 /* No compression */ #define ZIPC_COMP_STORE 0 /* No compression */
#define ZIPC_COMP_DEFLATE 8 /* Deflate compression */ #define ZIPC_COMP_DEFLATE 8 /* Deflate compression */
#define ZIPC_INTERNAL_BIN 0x0000 /* Internal attributes = binary */
#define ZIPC_INTERNAL_TEXT 0x0001 /* Internal attributes = text */
#define ZIPC_EXTERNAL_DIR 0x41ed0010 /* External attributes = directory */
#define ZIPC_EXTERNAL_FILE 0x81a40000 /* External attributes = file */
/* /*
* Local types... * Local types...
@ -76,11 +75,11 @@ struct _zipc_s
{ {
FILE *fp; /* ZIP file */ FILE *fp; /* ZIP file */
const char *error; /* Last error message */ const char *error; /* Last error message */
int alloc_files, /* Allocated file entries in ZIP */ size_t alloc_files, /* Allocated file entries in ZIP */
num_files; /* Number of file entries in ZIP */ num_files; /* Number of file entries in ZIP */
zipc_file_t *files; /* File entries in ZIP */ zipc_file_t *files; /* File entries in ZIP */
unsigned int modtime; /* MS-DOS modification date/time */
z_stream stream; /* Deflate stream for current file */ z_stream stream; /* Deflate stream for current file */
unsigned int modtime; /* MS-DOS modification date/time */
char buffer[16384]; /* Deflate output buffer */ char buffer[16384]; /* Deflate output buffer */
}; };
@ -94,6 +93,8 @@ struct _zipc_file_s
size_t compressed_size; /* Size of file (compressed) */ size_t compressed_size; /* Size of file (compressed) */
size_t uncompressed_size; /* Size of file (uncompressed) */ size_t uncompressed_size; /* Size of file (uncompressed) */
size_t offset; /* Offset of this entry in file */ size_t offset; /* Offset of this entry in file */
unsigned short internal_attrs; /* Internal attributes */
unsigned int external_attrs; /* External attributes */
}; };
@ -141,9 +142,9 @@ zipcClose(zipc_t *zc) /* I - ZIP container */
status |= zipc_write_u32(zc, ZIPC_END_RECORD); status |= zipc_write_u32(zc, ZIPC_END_RECORD);
status |= zipc_write_u16(zc, 0); /* Disk number */ status |= zipc_write_u16(zc, 0); /* Disk number */
status |= zipc_write_u16(zc, 0); /* Disk number containing directory */ status |= zipc_write_u16(zc, 0); /* Disk number containing directory */
status |= zipc_write_u16(zc, zc->num_files); status |= zipc_write_u16(zc, (unsigned)zc->num_files);
status |= zipc_write_u16(zc, zc->num_files); status |= zipc_write_u16(zc, (unsigned)zc->num_files);
status |= zipc_write_u32(zc, end - start); status |= zipc_write_u32(zc, (unsigned)(end - start));
status |= zipc_write_u32(zc, (unsigned)start); status |= zipc_write_u32(zc, (unsigned)start);
status |= zipc_write_u16(zc, 0); /* file comment length */ status |= zipc_write_u16(zc, 0); /* file comment length */
@ -159,6 +160,42 @@ zipcClose(zipc_t *zc) /* I - ZIP container */
} }
/*
* 'zipcCreateDirectory()' - Create a directory in a ZIP container.
*
* The "filename" value is the path within the ZIP container. Directories are
* separated by the forward slash ("/").
*/
int /* O - 0 on success, -1 on error */
zipcCreateDirectory(
zipc_t *zc, /* I - ZIP container */
const char *filename) /* I - Directory name */
{
zipc_file_t *zf = zipc_add_file(zc, filename, 0);
/* ZIP container file */
int status = 0; /* Return status */
if (zf)
{
char *end = zf->filename + strlen(zf->filename);
if (end > zf->filename && end < (zf->filename + sizeof(zf->filename) - 1) && end[-1] != '/')
*end = '/';
zf->crc32 = 0;
zf->external_attrs = ZIPC_EXTERNAL_DIR;
status |= zipc_write_local_header(zc, zf);
}
else
status = -1;
return (status);
}
/* /*
* 'zipcCreateFile()' - Create a ZIP container file. * 'zipcCreateFile()' - Create a ZIP container file.
* *
@ -182,6 +219,7 @@ zipcCreateFile(
zipc_file_t *zf = zipc_add_file(zc, filename, compressed); zipc_file_t *zf = zipc_add_file(zc, filename, compressed);
/* ZIP container file */ /* ZIP container file */
zf->external_attrs = ZIPC_EXTERNAL_FILE;
if (zipc_write_local_header(zc, zf)) if (zipc_write_local_header(zc, zf))
return (NULL); return (NULL);
@ -215,7 +253,9 @@ zipcCreateFileWithString(
{ {
zf->uncompressed_size = len; zf->uncompressed_size = len;
zf->compressed_size = len; zf->compressed_size = len;
zf->crc32 = crc32(zf->crc32, (const Bytef *)contents, len); zf->crc32 = crc32(zf->crc32, (const Bytef *)contents, (unsigned)len);
zf->internal_attrs = ZIPC_INTERNAL_TEXT;
zf->external_attrs = ZIPC_EXTERNAL_FILE;
status |= zipc_write_local_header(zc, zf); status |= zipc_write_local_header(zc, zf);
status |= zipc_write(zc, contents, len); status |= zipc_write(zc, contents, len);
@ -262,8 +302,8 @@ zipcFileFinish(zipc_file_t *zf) /* I - ZIP container file */
break; break;
} }
status |= zipc_write(zf->zc, zc->buffer, (char *)zc->stream.next_out - zc->buffer); status |= zipc_write(zf->zc, zc->buffer, (size_t)((char *)zc->stream.next_out - zc->buffer));
zf->compressed_size += (char *)zc->stream.next_out - zc->buffer; zf->compressed_size += (size_t)((char *)zc->stream.next_out - zc->buffer);
zc->stream.next_out = (Bytef *)zc->buffer; zc->stream.next_out = (Bytef *)zc->buffer;
zc->stream.avail_out = sizeof(zc->buffer); zc->stream.avail_out = sizeof(zc->buffer);
@ -271,8 +311,8 @@ zipcFileFinish(zipc_file_t *zf) /* I - ZIP container file */
if ((char *)zc->stream.next_out > zc->buffer) if ((char *)zc->stream.next_out > zc->buffer)
{ {
status |= zipc_write(zf->zc, zc->buffer, (char *)zc->stream.next_out - zc->buffer); status |= zipc_write(zf->zc, zc->buffer, (size_t)((char *)zc->stream.next_out - zc->buffer));
zf->compressed_size += (char *)zc->stream.next_out - zc->buffer; zf->compressed_size += (size_t)((char *)zc->stream.next_out - zc->buffer);
} }
deflateEnd(&zc->stream); deflateEnd(&zc->stream);
@ -312,6 +352,8 @@ zipcFilePrintf(zipc_file_t *zf, /* I - ZIP container file */
} }
va_end(ap); va_end(ap);
zf->internal_attrs = ZIPC_INTERNAL_TEXT;
return (zipcFileWrite(zf, buffer, strlen(buffer))); return (zipcFileWrite(zf, buffer, strlen(buffer)));
} }
@ -330,6 +372,8 @@ int /* O - 0 on success, -1 on error */
zipcFilePuts(zipc_file_t *zf, /* I - ZIP container file */ zipcFilePuts(zipc_file_t *zf, /* I - ZIP container file */
const char *s) /* I - String to write */ const char *s) /* I - String to write */
{ {
zf->internal_attrs = ZIPC_INTERNAL_TEXT;
return (zipcFileWrite(zf, s, strlen(s))); return (zipcFileWrite(zf, s, strlen(s)));
} }
@ -355,7 +399,7 @@ zipcFileWrite(zipc_file_t *zf, /* I - ZIP container file */
zf->uncompressed_size += bytes; zf->uncompressed_size += bytes;
zf->crc32 = crc32(zf->crc32, (const Bytef *)data, bytes); zf->crc32 = crc32(zf->crc32, (const Bytef *)data, (unsigned)bytes);
if (zf->method == ZIPC_COMP_STORE) if (zf->method == ZIPC_COMP_STORE)
{ {
@ -381,8 +425,8 @@ zipcFileWrite(zipc_file_t *zf, /* I - ZIP container file */
{ {
if (zc->stream.avail_out < (int)(sizeof(zc->buffer) / 8)) if (zc->stream.avail_out < (int)(sizeof(zc->buffer) / 8))
{ {
status |= zipc_write(zf->zc, zc->buffer, (char *)zc->stream.next_out - zc->buffer); status |= zipc_write(zf->zc, zc->buffer, (size_t)((char *)zc->stream.next_out - zc->buffer));
zf->compressed_size += (char *)zc->stream.next_out - zc->buffer; zf->compressed_size += (size_t)((char *)zc->stream.next_out - zc->buffer);
zc->stream.next_out = (Bytef *)zc->buffer; zc->stream.next_out = (Bytef *)zc->buffer;
zc->stream.avail_out = sizeof(zc->buffer); zc->stream.avail_out = sizeof(zc->buffer);
@ -525,7 +569,11 @@ zipcFileXMLPrintf(
} }
if (bufptr > buffer) if (bufptr > buffer)
status |= zipcFileWrite(zf, buffer, bufptr - buffer); {
zf->internal_attrs = ZIPC_INTERNAL_TEXT;
status |= zipcFileWrite(zf, buffer, (size_t)(bufptr - buffer));
}
return (status); return (status);
} }
@ -578,23 +626,23 @@ zipcOpen(const char *filename, /* I - Filename of container */
* *
* Bits Description * Bits Description
* ------ ----------- * ------ -----------
* 0-4 Second * 0-4 Seconds / 2 (0-29)
* 5-10 Minute * 5-10 Minute (0-59)
* 11-15 Hour * 11-15 Hour (0-23)
* 16-20 Day (1-31) * 16-20 Day (1-31)
* 21-24 Month (1-12) * 21-24 Month (1-12)
* 25-31 Years since 1980 * 25-31 Years since 1980
*/ */
curtime = time(NULL); curtime = time(NULL);
curdate = gmtime(&curtime); curdate = localtime(&curtime);
zc->modtime = curdate->tm_sec | zc->modtime = (unsigned)(curdate->tm_sec / 2) |
(curdate->tm_min << 5) | ((unsigned)curdate->tm_min << 5) |
(curdate->tm_hour << 11) | ((unsigned)curdate->tm_hour << 11) |
(curdate->tm_mday << 16) | ((unsigned)curdate->tm_mday << 16) |
((curdate->tm_mon + 1) << 21) | ((unsigned)(curdate->tm_mon + 1) << 21) |
((curdate->tm_year - 80) << 25); ((unsigned)(curdate->tm_year - 80) << 25);
} }
return (zc); return (zc);
@ -644,7 +692,7 @@ zipc_add_file(zipc_t *zc, /* I - ZIP container */
temp->zc = zc; temp->zc = zc;
temp->crc32 = crc32(0, NULL, 0); temp->crc32 = crc32(0, NULL, 0);
temp->offset = ftell(zc->fp); temp->offset = (size_t)ftell(zc->fp);
if (compression) if (compression)
{ {
@ -698,20 +746,20 @@ zipc_write_dir_header(
status |= zipc_write_u32(zc, ZIPC_DIR_HEADER); status |= zipc_write_u32(zc, ZIPC_DIR_HEADER);
status |= zipc_write_u16(zc, ZIPC_MADE_BY); status |= zipc_write_u16(zc, ZIPC_MADE_BY);
status |= zipc_write_u16(zc, ZIPC_VERSION); status |= zipc_write_u16(zc, zf->external_attrs == ZIPC_EXTERNAL_DIR ? ZIPC_DIR_VERSION : ZIPC_FILE_VERSION);
status |= zipc_write_u16(zc, zf->flags); status |= zipc_write_u16(zc, zf->flags);
status |= zipc_write_u16(zc, zf->method); status |= zipc_write_u16(zc, zf->method);
status |= zipc_write_u32(zc, zc->modtime); status |= zipc_write_u32(zc, zc->modtime);
status |= zipc_write_u32(zc, zf->crc32); status |= zipc_write_u32(zc, zf->crc32);
status |= zipc_write_u32(zc, zf->compressed_size); status |= zipc_write_u32(zc, (unsigned)zf->compressed_size);
status |= zipc_write_u32(zc, zf->uncompressed_size); status |= zipc_write_u32(zc, (unsigned)zf->uncompressed_size);
status |= zipc_write_u16(zc, filenamelen); status |= zipc_write_u16(zc, (unsigned)filenamelen);
status |= zipc_write_u16(zc, 0); /* extra field length */ status |= zipc_write_u16(zc, 0); /* extra field length */
status |= zipc_write_u16(zc, 0); /* comment length */ status |= zipc_write_u16(zc, 0); /* comment length */
status |= zipc_write_u16(zc, 0); /* disk number start */ status |= zipc_write_u16(zc, 0); /* disk number start */
status |= zipc_write_u16(zc, 0); /* internal file attributes */ status |= zipc_write_u16(zc, zf->internal_attrs);
status |= zipc_write_u32(zc, 0); /* external file attributes */ status |= zipc_write_u32(zc, zf->external_attrs);
status |= zipc_write_u32(zc, zf->offset); status |= zipc_write_u32(zc, (unsigned)zf->offset);
status |= zipc_write(zc, zf->filename, filenamelen); status |= zipc_write(zc, zf->filename, filenamelen);
return (status); return (status);
@ -732,18 +780,18 @@ zipc_write_local_header(
size_t filenamelen = strlen(zf->filename); size_t filenamelen = strlen(zf->filename);
/* Length of filename */ /* Length of filename */
if (zf->uncompressed_size == 0) if (zf->uncompressed_size == 0 && zf->external_attrs != ZIPC_EXTERNAL_DIR)
flags |= ZIPC_FLAG_DATA; flags |= ZIPC_FLAG_DATA;
status |= zipc_write_u32(zc, ZIPC_LOCAL_HEADER); status |= zipc_write_u32(zc, ZIPC_LOCAL_HEADER);
status |= zipc_write_u16(zc, ZIPC_VERSION); status |= zipc_write_u16(zc, zf->external_attrs == ZIPC_EXTERNAL_DIR ? ZIPC_DIR_VERSION : ZIPC_FILE_VERSION);
status |= zipc_write_u16(zc, flags); status |= zipc_write_u16(zc, flags);
status |= zipc_write_u16(zc, zf->method); status |= zipc_write_u16(zc, zf->method);
status |= zipc_write_u32(zc, zc->modtime); status |= zipc_write_u32(zc, zc->modtime);
status |= zipc_write_u32(zc, zf->uncompressed_size == 0 ? 0 : zf->crc32); status |= zipc_write_u32(zc, zf->uncompressed_size == 0 ? 0 : zf->crc32);
status |= zipc_write_u32(zc, zf->compressed_size); status |= zipc_write_u32(zc, (unsigned)zf->compressed_size);
status |= zipc_write_u32(zc, zf->uncompressed_size); status |= zipc_write_u32(zc, (unsigned)zf->uncompressed_size);
status |= zipc_write_u16(zc, filenamelen); status |= zipc_write_u16(zc, (unsigned)filenamelen);
status |= zipc_write_u16(zc, 0); /* extra field length */ status |= zipc_write_u16(zc, 0); /* extra field length */
status |= zipc_write(zc, zf->filename, filenamelen); status |= zipc_write(zc, zf->filename, filenamelen);
@ -764,8 +812,8 @@ zipc_write_local_trailer(
status |= zipc_write_u32(zc, zf->crc32); status |= zipc_write_u32(zc, zf->crc32);
status |= zipc_write_u32(zc, zf->compressed_size); status |= zipc_write_u32(zc, (unsigned)zf->compressed_size);
status |= zipc_write_u32(zc, zf->uncompressed_size); status |= zipc_write_u32(zc, (unsigned)zf->uncompressed_size);
return (status); return (status);
} }

@ -50,6 +50,7 @@ typedef struct _zipc_file_s zipc_file_t;/* File/directory in ZIP container */
*/ */
extern int zipcClose(zipc_t *zc); extern int zipcClose(zipc_t *zc);
extern int zipcCreateDirectory(zipc_t *zc, const char *filename);
extern zipc_file_t *zipcCreateFile(zipc_t *zc, const char *filename, int compressed); extern zipc_file_t *zipcCreateFile(zipc_t *zc, const char *filename, int compressed);
extern int zipcCreateFileWithString(zipc_t *zc, const char *filename, const char *contents); extern int zipcCreateFileWithString(zipc_t *zc, const char *filename, const char *contents);
extern const char *zipcError(zipc_t *zc); extern const char *zipcError(zipc_t *zc);

Loading…
Cancel
Save