/******************************************************************************
* @file unzip.c
*****************************************************************************/
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct cfh {
uint16_t made_by_ver; /* Version made by. */
- uint16_t extrcat_ver; /* Version needed to extract. */
+ uint16_t extract_ver; /* Version needed to extract. */
uint16_t gp_flag; /* General-purpose bit flag. */
uint16_t method; /* Compression method. */
uint16_t mod_time; /* Modification time. */
}
cfh->made_by_ver = array_to_integer (p, 2, 0), p += 2;
- cfh->extrcat_ver = array_to_integer (p, 2, 0), p += 2;
+ cfh->extract_ver = array_to_integer (p, 2, 0), p += 2;
cfh->gp_flag = array_to_integer (p, 2, 0), p += 2;
cfh->method = array_to_integer (p, 2, 0), p += 2;
cfh->mod_time = array_to_integer (p, 2, 0), p += 2;
struct lfh {
- uint16_t extrcat_ver; /* Version needed to extract. */
+ uint16_t extract_ver; /* Version needed to extract. */
uint16_t gp_flag; /* General-purpose bit flag. */
uint16_t method; /* Compression method. */
uint16_t mod_time; /* Modification time. */
return -1;
}
- lfh->extrcat_ver = array_to_integer (p, 2, 0), p += 2;
+ lfh->extract_ver = array_to_integer (p, 2, 0), p += 2;
lfh->gp_flag = array_to_integer (p, 2, 0), p += 2;
lfh->method = array_to_integer (p, 2, 0), p += 2;
lfh->mod_time = array_to_integer (p, 2, 0), p += 2;
static int validate_structs (struct cfh *cfh, struct lfh *lfh) {
- if (cfh->extrcat_ver != lfh->extrcat_ver) {
+ if (cfh->extract_ver != lfh->extract_ver) {
return -1;
}
continue;
}
- if (cfh.method != ZIP_DEFLATE) {
+ if (cfh.method != ZIP_STORE && cfh.method != ZIP_DEFLATE) {
- report_at (program_name, 0, REPORT_ERROR, "currently only ZIP_DEFLATE is supported");
+ report_at (program_name, 0, REPORT_ERROR, "currently only ZIP_STORE && ZIP_DEFLATE are supported");
break;
}
report_at (program_name, 0, REPORT_ERROR, "failed to process Local File Header");
- fseek (fp, cfh.lfh_offset, SEEK_SET);
+ fseek (fp, orig_offset, SEEK_SET);
free (temp);
break;
if (validate_structs (&cfh, &lfh)) {
report_at (program_name, 0, REPORT_ERROR, "Centeral File Header and Local File Header mismatch");
- fseek (fp, cfh.lfh_offset, SEEK_SET);
- free (data);
+ fseek (fp, orig_offset, SEEK_SET);
free (temp);
break;
if (!(data = malloc (cfh.comp_size))) {
- fseek (fp, cfh.lfh_offset, SEEK_SET);
+ fseek (fp, orig_offset, SEEK_SET);
free (temp);
break;
if (fread (data, 1, lfh.comp_size, fp) != lfh.comp_size) {
- fseek (fp, cfh.lfh_offset, SEEK_SET);
+ fseek (fp, orig_offset, SEEK_SET);
free (data);
free (temp);
}
- if (cfh.method == ZIP_DEFLATE) {
+ if (cfh.method == ZIP_STORE) {
+
+ assert (lfh.comp_size == lfh.uncomp_size);
+
+ if (!(outfile = fopen (temp, "w+b"))) {
+
+ report_at (program_name, 0, REPORT_ERROR, "failed to open '%s' for writing", temp);
+ remove (temp);
+
+ free (data);
+ free (temp);
+
+ break;
+
+ }
+
+ if (fwrite (data, 1, lfh.uncomp_size, outfile) != lfh.uncomp_size) {
+
+ report_at (program_name, 0, REPORT_ERROR, "failed to extract %s", temp);
+ fclose (outfile);
+
+ free (data);
+ remove (temp);
+
+ break;
+
+ }
+
+ free (data);
+ fclose (outfile);
+
+ } else if (cfh.method == ZIP_DEFLATE) {
if (!(outfile = fopen (temp, "w+b"))) {