diff options
Diffstat (limited to 'navit/maptool/zip.c')
-rw-r--r-- | navit/maptool/zip.c | 528 |
1 files changed, 254 insertions, 274 deletions
diff --git a/navit/maptool/zip.c b/navit/maptool/zip.c index fa95c1674..33ca52eb1 100644 --- a/navit/maptool/zip.c +++ b/navit/maptool/zip.c @@ -26,342 +26,322 @@ #include "zipfile.h" struct zip_info { - int zipnum; - int dir_size; - long long offset; - int compression_level; - int maxnamelen; - int zip64; - short date; - short time; - FILE *res2; - FILE *index; - FILE *dir; + int zipnum; + int dir_size; + long long offset; + int compression_level; + int maxnamelen; + int zip64; + short date; + short time; + FILE *res2; + FILE *index; + FILE *dir; }; static int -zip_write(struct zip_info *info, void *data, int len) -{ - if (fwrite(data, len, 1, info->res2) != 1) - return 0; - return 1; +zip_write(struct zip_info *info, void *data, int len) { + if (fwrite(data, len, 1, info->res2) != 1) + return 0; + return 1; } #ifdef HAVE_ZLIB static int -compress2_int(Byte *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level) -{ - z_stream stream; - int err; - - stream.next_in = (Bytef*)source; - stream.avail_in = (uInt)sourceLen; - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; - - err = deflateInit2(&stream, level, Z_DEFLATED, -15, 9, Z_DEFAULT_STRATEGY); - if (err != Z_OK) return err; - - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; - - err = deflateEnd(&stream); - return err; +compress2_int(Byte *dest, uLongf *destLen, const Bytef *source, uLong sourceLen, int level) { + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; + + err = deflateInit2(&stream, level, Z_DEFLATED, -15, 9, Z_DEFAULT_STRATEGY); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; } #endif void -write_zipmember(struct zip_info *zip_info, char *name, int filelen, char *data, int data_size) -{ - struct zip_lfh lfh = { - 0x04034b50, - 0x0a, - 0x0, - 0x0, - zip_info->time, - zip_info->date, - 0x0, - 0x0, - 0x0, - filelen, - 0x0, - }; - struct zip_cd cd = { - 0x02014b50, - 0x17, - 0x00, - 0x0a, - 0x00, - 0x0000, - 0x0, - zip_info->time, - zip_info->date, - 0x0, - 0x0, - 0x0, - filelen, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0, - zip_info->offset, - }; - struct zip_cd_ext cd_ext = { - 0x1, - 0x8, - zip_info->offset, - }; - char *filename; - int crc=0,len,comp_size=data_size; - uLongf destlen=data_size+data_size/500+12; - char *compbuffer; - - compbuffer = g_malloc(destlen); - crc=crc32(0, NULL, 0); - crc=crc32(crc, (unsigned char *)data, data_size); - lfh.zipmthd=zip_info->compression_level ? 8:0; +write_zipmember(struct zip_info *zip_info, char *name, int filelen, char *data, int data_size) { + struct zip_lfh lfh = { + 0x04034b50, + 0x0a, + 0x0, + 0x0, + zip_info->time, + zip_info->date, + 0x0, + 0x0, + 0x0, + filelen, + 0x0, + }; + struct zip_cd cd = { + 0x02014b50, + 0x17, + 0x00, + 0x0a, + 0x00, + 0x0000, + 0x0, + zip_info->time, + zip_info->date, + 0x0, + 0x0, + 0x0, + filelen, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0, + zip_info->offset, + }; + struct zip_cd_ext cd_ext = { + 0x1, + 0x8, + zip_info->offset, + }; + char *filename; + int crc=0,len,comp_size=data_size; + uLongf destlen=data_size+data_size/500+12; + char *compbuffer; + + compbuffer = g_malloc(destlen); + crc=crc32(0, NULL, 0); + crc=crc32(crc, (unsigned char *)data, data_size); + lfh.zipmthd=zip_info->compression_level ? 8:0; #ifdef HAVE_ZLIB - if (zip_info->compression_level) { - int error=compress2_int((Byte *)compbuffer, &destlen, (Bytef *)data, data_size, zip_info->compression_level); - if (error == Z_OK) { - if (destlen < data_size) { - data=compbuffer; - comp_size=destlen; - } else - lfh.zipmthd=0; - } else { - fprintf(stderr,"compress2 returned %d\n", error); - } - } + if (zip_info->compression_level) { + int error=compress2_int((Byte *)compbuffer, &destlen, (Bytef *)data, data_size, zip_info->compression_level); + if (error == Z_OK) { + if (destlen < data_size) { + data=compbuffer; + comp_size=destlen; + } else + lfh.zipmthd=0; + } else { + fprintf(stderr,"compress2 returned %d\n", error); + } + } #endif - lfh.zipcrc=crc; - lfh.zipsize=comp_size; - lfh.zipuncmp=data_size; - cd.zipccrc=crc; - cd.zipcsiz=lfh.zipsize; - cd.zipcunc=data_size; - cd.zipcmthd=lfh.zipmthd; - if (zip_info->zip64) { - cd.zipofst=0xffffffff; - cd.zipcxtl+=sizeof(cd_ext); - } - filename=g_alloca(filelen+1); - strcpy(filename, name); - len=strlen(filename); - while (len < filelen) { - filename[len++]='_'; - } - filename[filelen]='\0'; - zip_write(zip_info, &lfh, sizeof(lfh)); - zip_write(zip_info, filename, filelen); - zip_info->offset+=sizeof(lfh)+filelen; - zip_write(zip_info, data, comp_size); - zip_info->offset+=comp_size; - dbg_assert(fwrite(&cd, sizeof(cd), 1, zip_info->dir)==1); - dbg_assert(fwrite(filename, filelen, 1, zip_info->dir)==1); - zip_info->dir_size+=sizeof(cd)+filelen; - if (zip_info->zip64) { - dbg_assert(fwrite(&cd_ext, sizeof(cd_ext), 1, zip_info->dir)==1); - zip_info->dir_size+=sizeof(cd_ext); - } - - g_free(compbuffer); + lfh.zipcrc=crc; + lfh.zipsize=comp_size; + lfh.zipuncmp=data_size; + cd.zipccrc=crc; + cd.zipcsiz=lfh.zipsize; + cd.zipcunc=data_size; + cd.zipcmthd=lfh.zipmthd; + if (zip_info->zip64) { + cd.zipofst=0xffffffff; + cd.zipcxtl+=sizeof(cd_ext); + } + filename=g_alloca(filelen+1); + strcpy(filename, name); + len=strlen(filename); + while (len < filelen) { + filename[len++]='_'; + } + filename[filelen]='\0'; + zip_write(zip_info, &lfh, sizeof(lfh)); + zip_write(zip_info, filename, filelen); + zip_info->offset+=sizeof(lfh)+filelen; + zip_write(zip_info, data, comp_size); + zip_info->offset+=comp_size; + dbg_assert(fwrite(&cd, sizeof(cd), 1, zip_info->dir)==1); + dbg_assert(fwrite(filename, filelen, 1, zip_info->dir)==1); + zip_info->dir_size+=sizeof(cd)+filelen; + if (zip_info->zip64) { + dbg_assert(fwrite(&cd_ext, sizeof(cd_ext), 1, zip_info->dir)==1); + zip_info->dir_size+=sizeof(cd_ext); + } + + g_free(compbuffer); } int -zip_write_index(struct zip_info *info) -{ - int size=ftell(info->index); - char *buffer; - - buffer=g_alloca(size); - fseek(info->index, 0, SEEK_SET); - - if (fread(buffer, size, 1, info->index) == 0){ - dbg(lvl_warning, "fread failed"); - return 1; - } - else{ - write_zipmember(info, "index", strlen("index"), buffer, size); - } - info->zipnum++; - return 0; +zip_write_index(struct zip_info *info) { + int size=ftell(info->index); + char *buffer; + + buffer=g_alloca(size); + fseek(info->index, 0, SEEK_SET); + + if (fread(buffer, size, 1, info->index) == 0) { + dbg(lvl_warning, "fread failed"); + return 1; + } else { + write_zipmember(info, "index", strlen("index"), buffer, size); + } + info->zipnum++; + return 0; } static void -zip_write_file_data(struct zip_info *info, FILE *in) -{ - size_t size; - char buffer[4096]; - while ((size=fread(buffer, 1, 4096, in))) - zip_write(info, buffer, size); +zip_write_file_data(struct zip_info *info, FILE *in) { + size_t size; + char buffer[4096]; + while ((size=fread(buffer, 1, 4096, in))) + zip_write(info, buffer, size); } int -zip_write_directory(struct zip_info *info) -{ - struct zip_eoc eoc = { - 0x06054b50, - 0x0000, - 0x0000, - 0x0000, - 0x0000, - 0x0, - 0x0, - 0x0, - }; - struct zip64_eoc eoc64 = { - 0x06064b50, - 0x0, - 0x0, - 0x0403, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - 0x0, - }; - struct zip64_eocl eocl = { - 0x07064b50, - 0x0, - 0x0, - 0x0, - }; - - fseek(info->dir, 0, SEEK_SET); - zip_write_file_data(info, info->dir); - if (info->zip64) { - eoc64.zip64esize=sizeof(eoc64)-12; - eoc64.zip64enum=info->zipnum; - eoc64.zip64ecenn=info->zipnum; - eoc64.zip64ecsz=info->dir_size; - eoc64.zip64eofst=info->offset; - zip_write(info, &eoc64, sizeof(eoc64)); - eocl.zip64lofst=info->offset+info->dir_size; - zip_write(info, &eocl, sizeof(eocl)); - } - eoc.zipenum=info->zipnum; - eoc.zipecenn=info->zipnum; - eoc.zipecsz=info->dir_size; - eoc.zipeofst=info->offset; - zip_write(info, &eoc, sizeof(eoc)); - sig_alrm(0); +zip_write_directory(struct zip_info *info) { + struct zip_eoc eoc = { + 0x06054b50, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0, + 0x0, + 0x0, + }; + struct zip64_eoc eoc64 = { + 0x06064b50, + 0x0, + 0x0, + 0x0403, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + 0x0, + }; + struct zip64_eocl eocl = { + 0x07064b50, + 0x0, + 0x0, + 0x0, + }; + + fseek(info->dir, 0, SEEK_SET); + zip_write_file_data(info, info->dir); + if (info->zip64) { + eoc64.zip64esize=sizeof(eoc64)-12; + eoc64.zip64enum=info->zipnum; + eoc64.zip64ecenn=info->zipnum; + eoc64.zip64ecsz=info->dir_size; + eoc64.zip64eofst=info->offset; + zip_write(info, &eoc64, sizeof(eoc64)); + eocl.zip64lofst=info->offset+info->dir_size; + zip_write(info, &eocl, sizeof(eocl)); + } + eoc.zipenum=info->zipnum; + eoc.zipecenn=info->zipnum; + eoc.zipecsz=info->dir_size; + eoc.zipeofst=info->offset; + zip_write(info, &eoc, sizeof(eoc)); + sig_alrm(0); #ifndef _WIN32 - alarm(0); + alarm(0); #endif - return 0; + return 0; } struct zip_info * -zip_new(void) -{ - return g_new0(struct zip_info, 1); +zip_new(void) { + return g_new0(struct zip_info, 1); } void -zip_set_zip64(struct zip_info *info, int on) -{ - info->zip64=on; +zip_set_zip64(struct zip_info *info, int on) { + info->zip64=on; } void -zip_set_compression_level(struct zip_info *info, int level) -{ - info->compression_level=level; +zip_set_compression_level(struct zip_info *info, int level) { + info->compression_level=level; } void -zip_set_maxnamelen(struct zip_info *info, int max) -{ - info->maxnamelen=max; +zip_set_maxnamelen(struct zip_info *info, int max) { + info->maxnamelen=max; } int -zip_get_maxnamelen(struct zip_info *info) -{ - return info->maxnamelen; +zip_get_maxnamelen(struct zip_info *info) { + return info->maxnamelen; } int -zip_add_member(struct zip_info *info) -{ - return info->zipnum++; +zip_add_member(struct zip_info *info) { + return info->zipnum++; } int -zip_set_timestamp(struct zip_info *info, char *timestamp) -{ - int year,month,day,hour,min,sec; - - if (sscanf(timestamp,"%d-%d-%dT%d:%d:%d",&year,&month,&day,&hour,&min,&sec) == 6) { - info->date=day | (month << 5) | ((year-1980) << 9); - info->time=(sec >> 1) | (min << 5) | (hour << 11); - return 1; - } - return 0; +zip_set_timestamp(struct zip_info *info, char *timestamp) { + int year,month,day,hour,min,sec; + + if (sscanf(timestamp,"%d-%d-%dT%d:%d:%d",&year,&month,&day,&hour,&min,&sec) == 6) { + info->date=day | (month << 5) | ((year-1980) << 9); + info->time=(sec >> 1) | (min << 5) | (hour << 11); + return 1; + } + return 0; } int -zip_open(struct zip_info *info, char *out, char *dir, char *index) -{ - info->res2=fopen(out,"wb+"); - if(!info->res2) { - fprintf(stderr,"Could not open output zip file %s\n", out); - return 0; - } - info->dir=fopen(dir,"wb+"); - if(!info->dir) { - fprintf(stderr,"Could not open zip directory %s\n", dir); - return 0; - } - info->index=fopen(index,"wb+"); - if(!info->index) { - fprintf(stderr,"Could not open index %s\n", index); - return 0; - } - return 1; +zip_open(struct zip_info *info, char *out, char *dir, char *index) { + info->res2=fopen(out,"wb+"); + if(!info->res2) { + fprintf(stderr,"Could not open output zip file %s\n", out); + return 0; + } + info->dir=fopen(dir,"wb+"); + if(!info->dir) { + fprintf(stderr,"Could not open zip directory %s\n", dir); + return 0; + } + info->index=fopen(index,"wb+"); + if(!info->index) { + fprintf(stderr,"Could not open index %s\n", index); + return 0; + } + return 1; } FILE * -zip_get_index(struct zip_info *info) -{ - return info->index; +zip_get_index(struct zip_info *info) { + return info->index; } int -zip_get_zipnum(struct zip_info *info) -{ - return info->zipnum; +zip_get_zipnum(struct zip_info *info) { + return info->zipnum; } void -zip_set_zipnum(struct zip_info *info, int num) -{ - info->zipnum=num; +zip_set_zipnum(struct zip_info *info, int num) { + info->zipnum=num; } void -zip_close(struct zip_info *info) -{ - fclose(info->index); - fclose(info->dir); - fclose(info->res2); +zip_close(struct zip_info *info) { + fclose(info->index); + fclose(info->dir); + fclose(info->res2); } void -zip_destroy(struct zip_info *info) -{ - g_free(info); +zip_destroy(struct zip_info *info) { + g_free(info); } |