the notes of ZIP workshop 1-2

introduction

this entry follows http://d.hatena.ne.jp/takahirox/20110605/1307259596

what i did

i made a zip archive tool with zip container format that i learned at the workshop. it doesn't compress files. just it packs raw data of files in a zip file.

description
  • it makes a zip file with zip container format.
  • CRC32 field has 0. so it might display errors when uncompression.
  • it doesn't compress files. just packs raw data of files in a zip file.
  • it is just a temporary tool.
    • datetime and so on has irresponsible values.
    • it limits 10 files to archive.
    • perhaps, it doesn't work correctly to archive files they aren't on a current directory.
  • i made it with my structures defines variables about zip headers.

example

you can make a zip file like this.

% ./archive_zip.o hoge.zip zip.h dump.c judge.c

and then, you can see what files are included in a zip file with windows explorer.

perhaps you see errors when uncompression with some uncompress tools like this.

but in my case, although errors are displayed it worked correctly.

the following shows the result of zip analysis tool that i made before.

% ./zip_analysis.o hoge.zip
this zip file includes 3 files.
- zip.h           1199 (1199) bytes
- dump.c          1587 (1587) bytes
- judge.c         1232 (1232) bytes

you can see that compressed size and uncompressed size are same.

this zip file is just contain raw data, so you can almost see included text data with cat command like this.

% cat hoge.zip
PK^C^D 
    E?>ョ    ッ^D  ッ^D  ^E   zip.h#include <stdint.h>

#define SIZEOF_ZIP_HEADER 30
#define SIZEOF_ZIP_END_HEADER 22
#define SIZEOF_ZIP_CENTRAL_HEADER 46

#pragma pack( 2 )

... snip ...

source code

you can get the source codes from google code.

zip.h

i defined structures about zip headers referring to the workshop.

typedef struct {
  uint8_t  signature[4];
  uint16_t version;
  uint16_t flags;
  uint16_t compression;
  uint16_t dos_time;
  uint16_t dos_date;
  uint32_t crc32;
  uint32_t compressed_size;
  uint32_t uncompressed_size;
  uint16_t file_name_length;
  uint16_t extra_field_length;
} ZIP_HEADER;

typedef struct {

... snip ...

} ZIP_CENTRAL_HEADER;

typedef struct {

... snip ...

} ZIP_END_HEADER;
archive_zip.c

first, getting file size with fseek and ftell.

then, setting parameters in the zip header structure.

after that, output the structure data with fwrite.

and finally, output filename and raw data.

it keeps on to the end.

    fseek( fp, 0, SEEK_END ) ;
    file_size = ftell( fp ) ;

    positions[ i ] = ftell( out ) ;

    // zip_headers[ i ].signature = { 0x50, 0x4b, 0x03, 0x04 } ;
    zip_headers[ i ].signature[ 0 ]     = 0x50 ;
    zip_headers[ i ].signature[ 1 ]     = 0x4b ;
    zip_headers[ i ].signature[ 2 ]     = 0x03 ;
    zip_headers[ i ].signature[ 3 ]     = 0x04 ;
    zip_headers[ i ].version            = 0x0a00 ;  // is it ok?
    zip_headers[ i ].flags              = 0x0000 ;  // is it ok?
    zip_headers[ i ].compression        = 0x0000 ;  // is it ok?
    zip_headers[ i ].dos_time           = 0x8045 ;  // temporary
    zip_headers[ i ].dos_date           = 0xae3e ;  // temporary
    zip_headers[ i ].crc32              = 0x00000000 ;  // temprary
    zip_headers[ i ].compressed_size    = file_size ;
    zip_headers[ i ].uncompressed_size  = file_size ;
    zip_headers[ i ].file_name_length   = strlen( argv[ i + 2 ] );
    zip_headers[ i ].extra_field_length = 0x0000 ;  // is it ok?

    // output zip_header
    fwrite( &zip_headers[ i ], sizeof( zip_headers[ i ] ), 1, out ) ;

    // output filename
    fputs( argv[ i + 2 ], out ) ;

    // output data
    fseek( fp, 0, SEEK_SET ) ; 
    while( ( c = getc( fp ) ) != EOF ) {
      putc( c, out ) ;
    }

conclusion

it excites me that's because i hadn't thought i can make a zip file by my hand.

i'm going to make something compress tool with what i learned at the workshop on next entry.