Commit d6e1b285 authored by John M. (Jack) Maxfield's avatar John M. (Jack) Maxfield
Browse files

Add myzip0 and Makefile

parent 46617ce3
No related merge requests found
Pipeline #29987 failed with stage
in 0 seconds
Showing with 140 additions and 0 deletions
+140 -0
myzip0
myunzip0
all : myzip0 myunzip0
myzip0 : myzip0.c
cc myzip0.c -o myzip0
myunzip0 : myunzip0.c
cc myunzip0.c -o myunzip0
\ No newline at end of file
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
const uint32_t BUFFER_SIZE = 1024;
int write_u8(FILE *file, const uint8_t v)
{
return fwrite(&v, sizeof(uint8_t), 1, file);
}
int write_u16(FILE *file, const uint16_t v)
{
return fwrite(&v, sizeof(uint16_t), 1, file);
}
int write_u32(FILE *file, const uint32_t v)
{
return fwrite(&v, sizeof(uint32_t), 1, file);
}
int copy_file_to_file(FILE *input, FILE *output, uint32_t bytes)
{
uint8_t buffer[BUFFER_SIZE];
uint32_t bytes_written = 0;
for (uint32_t start = 0; start < bytes; start += BUFFER_SIZE)
{
uint32_t remaining_bytes = bytes - start;
uint32_t copy_this_iter = (remaining_bytes < BUFFER_SIZE) ?
remaining_bytes : BUFFER_SIZE;
fread(buffer, 1, copy_this_iter, input);
bytes_written += fwrite(buffer, 1, copy_this_iter, output);
}
return bytes_written;
}
int main(int argc, char *argv[])
{
if (argc != 3)
{
fprintf(stderr, "Usage: %s <output zip filename> <input file filename>\n", argv[0]);
return 1;
}
const char *output_file_name = argv[1];
const char *input_file_name = argv[2];
FILE *input_file = fopen(input_file_name, "r");
FILE *output_file = fopen(output_file_name, "w");
if (input_file == NULL)
{
fprintf(stderr, "Could not open \"%s\"\n", input_file_name);
return 1;
}
if (output_file == NULL)
{
fprintf(stderr, "Could not open \"%s\"\n", output_file_name);
return 2;
}
fseek(input_file, 0, SEEK_END);
uint32_t input_file_size = ftell(input_file);
fseek(input_file, 0, SEEK_SET);
/* (1) LOCAL FILE RECORD */
write_u32(output_file, 0x04034b50); /* local file signature */
write_u16(output_file, 20); /* extract version */
write_u16(output_file, 0); /* general purpose flag */
write_u16(output_file, 0); /* compression method */
write_u16(output_file, 0); /* last mod file time */
write_u16(output_file, 0); /* last mod file date */
write_u32(output_file, 0xDEADBEEF); /* crc */
write_u32(output_file, input_file_size); /* compressed file size */
write_u32(output_file, input_file_size); /* uncompressed file size */
write_u16(output_file, strlen(input_file_name)); /* file name len */
write_u16(output_file, 0); /* extra field length */
fputs(input_file_name, output_file); /* file name */
/* extra field */
/* copy input file to output */
copy_file_to_file(input_file, output_file, input_file_size);
uint32_t central_directory_start = ftell(output_file);
/* (2) CENTRAL DIRECTORY RECORD */
write_u32(output_file, 0x02014b50); /* central directory signature */
write_u8 (output_file, 30); /* specification version */
write_u8 (output_file, 65); /* made by */
write_u16(output_file, 20); /* extract version */
write_u16(output_file, 0); /* general purpose bit flag */
write_u16(output_file, 0); /* compression method */
write_u16(output_file, 0); /* last mod file time */
write_u16(output_file, 0); /* last mod file date */
write_u32(output_file, 0xdeadbeef); /* crc */
write_u32(output_file, input_file_size); /* compressed file size */
write_u32(output_file, input_file_size); /* uncompressed file size */
write_u16(output_file, strlen(input_file_name)); /* file name length */
write_u16(output_file, 0); /* extra field length */
write_u16(output_file, 0); /* file comment length */
write_u16(output_file, 0); /* disk number start */
write_u16(output_file, 1); /* internal file attributes */
write_u32(output_file, 1); /* external file attributes */
write_u32(output_file, 0); /* offset of local header */
fputs(input_file_name, output_file); /* file name */
/* extra field */
/* file comment */
uint32_t end_record_start = ftell(output_file);
/* (3) END OF CENTRAL DIRECTORY RECORD */
write_u32(output_file, 0x06054b50); /* end of central dir signature */
write_u16(output_file, 0); /* number of this disk */
write_u16(output_file, 0); /* number of the start disk */
write_u16(output_file, 1); /* total number of entries on this disk */
write_u16(output_file, 1); /* total number of entries */
write_u32(output_file, end_record_start - central_directory_start); /* size of central directory record */
write_u32(output_file, central_directory_start); /* offset of start of central directory */
write_u16(output_file, 0); /* .zip file comment length */
/* .zip file comment */
fclose(input_file);
fclose(output_file);
return 0;
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment