diff options
-rw-r--r-- | mdk-stage1/mar/Makefile | 2 | ||||
-rw-r--r-- | mdk-stage1/mar/mar-extract-only.c | 223 | ||||
-rw-r--r-- | mdk-stage1/mar/mar-extract-only.h | 8 | ||||
-rw-r--r-- | mdk-stage1/mar/mar-frontend.c | 85 | ||||
-rw-r--r-- | mdk-stage1/mar/mar.h | 12 |
5 files changed, 137 insertions, 193 deletions
diff --git a/mdk-stage1/mar/Makefile b/mdk-stage1/mar/Makefile index 5723bdf9d..dc5316a1a 100644 --- a/mdk-stage1/mar/Makefile +++ b/mdk-stage1/mar/Makefile @@ -31,7 +31,7 @@ FLAGS = -Wall -Werror -Os -fomit-frame-pointer -c mar: mar-frontend.o mar-extract-only-standalone.o - gcc -o mar mar-frontend.o mar-extract-only-standalone.o -lz + gcc -o mar mar-frontend.o mar-extract-only-standalone.o -lbz2 $(STRIPCMD) $@ libmar.a: mar-extract-only.o diff --git a/mdk-stage1/mar/mar-extract-only.c b/mdk-stage1/mar/mar-extract-only.c index ec99da114..2d3898cfc 100644 --- a/mdk-stage1/mar/mar-extract-only.c +++ b/mdk-stage1/mar/mar-extract-only.c @@ -24,13 +24,14 @@ * (and it DOES perform tests and return values, blaaaah..) */ +#include "mar-extract-only.h" #include "mar.h" #ifdef _STANDALONE_ void -gzerr(gzFile f) /* decrease code size */ +zerr(BZFILE * f) /* decrease code size */ { - fprintf(stderr, gzerror(f, &gz_errnum)); + fprintf(stderr, BZ2_bzerror(f, &z_errnum)); } void log_perror(char *msg) @@ -45,20 +46,89 @@ log_message(char *msg) #else /* _STANDALONE_ */ #include "../log.h" void -gzerr(gzFile f) /* decrease code size */ +zerr(BZFILE * f) /* decrease code size */ { - log_message(gzerror(f, &gz_errnum)); + log_message(BZ2_bzerror(f, &z_errnum)); } #endif /* _STANDALONE_ */ +static int +mar_open_file(char *filename, struct mar_stream *s) +{ + int end_filetable = 0; + struct mar_element * previous_element = NULL; + + /* mar_zfile */ + s->mar_zfile = BZ2_bzopen(filename, "rb"); + if (!s->mar_zfile) + { + log_perror(filename); + return -1; + } + + while (end_filetable == 0) + { + char buf[512]; + int ptr = 0; + /* read filename */ + do + { + if (BZ2_bzread(s->mar_zfile, &(buf[ptr]), sizeof(char)) != sizeof(char)) + { + zerr(s->mar_zfile); + return -1; + } + ptr++; + } while ((buf[ptr-1] != 0) && (ptr < 512)); + /* ptr == 1 when we arrive on the "char 0" of the end of the filetable */ + if (ptr > 1) + { + struct mar_element * e = (struct mar_element *) malloc(sizeof(struct mar_element)); + e->filename = strdup(buf); + /* read file_length */ + if (BZ2_bzread(s->mar_zfile, &(e->file_length), sizeof(int)) != sizeof(int)) + { + zerr(s->mar_zfile); + return -1; + } + /* read data_offset */ + if (BZ2_bzread(s->mar_zfile, &(e->data_offset), sizeof(int)) != sizeof(int)) + { + zerr(s->mar_zfile); + return -1; + } + /* write down chaining */ + if (previous_element) + previous_element->next_element = e; + else + s->first_element = e; + previous_element = e; + } + else + end_filetable = 1; + + } + /* chaining for last element */ + previous_element->next_element = NULL; + + return 0; +} + + char ** -mar_list_contents(struct mar_stream *s) +mar_list_contents(char * mar_filename) { - struct mar_element * elem = s->first_element; + struct mar_stream s; + struct mar_element * elem; char * tmp_contents[500]; char ** answ; int i = 0; + + if (mar_open_file(mar_filename, &s)) + return NULL; + + elem = s.first_element; while (elem) { tmp_contents[i++] = strdup(elem->filename); @@ -70,48 +140,28 @@ mar_list_contents(struct mar_stream *s) return answ; } + int -mar_calc_integrity(struct mar_stream *s) +mar_extract_file(char *mar_filename, char *filename_to_extract, char *dest_dir) { - char buf[4096]; - int current_crc = 0; - if (gzseek(s->mar_gzfile, sizeof(int), SEEK_SET) != sizeof(int)) - { - gzerr(s->mar_gzfile); - return -1; - } - while (!gzeof(s->mar_gzfile)) - { - int bytes = gzread(s->mar_gzfile, buf, sizeof(buf)); - if (bytes == -1) - { - gzerr(s->mar_gzfile); - return -1; - } - while (bytes > 0) - { - bytes--; - current_crc += buf[bytes]; - } - } - return current_crc; -} + struct mar_stream s; + struct mar_element * elem; + if (mar_open_file(mar_filename, &s)) + return -1; -int -mar_extract_file(struct mar_stream *s, char *filename, char *dest_dir) -{ - struct mar_element * elem = s->first_element; + elem = s.first_element; while (elem) { - if (strcmp(elem->filename, filename) == 0) + if (strcmp(elem->filename, filename_to_extract) == 0) { + char garb_buf[4096]; char *buf; char *dest_file; - int fd; - dest_file = (char *) alloca(strlen(dest_dir) + strlen(filename) + 1); + int fd, i; + dest_file = (char *) alloca(strlen(dest_dir) + strlen(filename_to_extract) + 1); strcpy(dest_file, dest_dir); - strcat(dest_file, filename); + strcat(dest_file, filename_to_extract); fd = creat(dest_file, 00660); if (fd == -1) { @@ -124,14 +174,18 @@ mar_extract_file(struct mar_stream *s, char *filename, char *dest_dir) log_perror(dest_file); return -1; } - if (gzseek(s->mar_gzfile, elem->data_offset, SEEK_SET) != elem->data_offset) - { - gzerr(s->mar_gzfile); - return -1; + i = elem->data_offset; + while (i > 0) { + int to_read = i > sizeof(garb_buf) ? sizeof(garb_buf) : i; + if (BZ2_bzread(s.mar_zfile, garb_buf, to_read) != to_read) { + log_message("MAR: unexpected EOF in stream"); + return -1; + } + i -= to_read; } - if (gzread(s->mar_gzfile, buf, elem->file_length) != elem->file_length) + if (BZ2_bzread(s.mar_zfile, buf, elem->file_length) != elem->file_length) { - gzerr(s->mar_gzfile); + zerr(s.mar_zfile); return -1; } if (write(fd, buf, elem->file_length) != elem->file_length) @@ -140,90 +194,13 @@ mar_extract_file(struct mar_stream *s, char *filename, char *dest_dir) return -1; } close(fd); /* do not check return value for code size */ + BZ2_bzclose(s.mar_zfile); return 0; } elem = elem->next_element; } + BZ2_bzclose(s.mar_zfile); return 1; /* 1 for file_not_found_in_archive */ } -int -mar_open_file(char *filename, struct mar_stream *s) -{ - int end_filetable = 0; - struct mar_element * previous_element = NULL; - - /* mar_gzfile */ - s->mar_gzfile = gzopen(filename, "rb"); - if (!s->mar_gzfile) - { - log_perror(filename); - return -1; - } - - /* crc32 */ - if (gzread(s->mar_gzfile, &(s->crc32), sizeof(int)) != sizeof(int)) - { - gzerr(s->mar_gzfile); - return -1; - } - - /* verify integrity */ - if (s->crc32 != mar_calc_integrity(s)) - log_message("ERROR! mar_open_file: CRC check failed (trying to continue)"); - - if (gzseek(s->mar_gzfile, sizeof(int), SEEK_SET) != sizeof(int)) - { - gzerr(s->mar_gzfile); - return -1; - } - - while (end_filetable == 0) - { - char buf[512]; - int ptr = 0; - /* read filename */ - do - { - if (gzread(s->mar_gzfile, &(buf[ptr]), sizeof(char)) != sizeof(char)) - { - gzerr(s->mar_gzfile); - return -1; - } - ptr++; - } while ((buf[ptr-1] != 0) && (ptr < 512)); - /* ptr == 1 when we arrive on the "char 0" of the end of the filetable */ - if (ptr > 1) - { - struct mar_element * e = (struct mar_element *) malloc(sizeof(struct mar_element)); - e->filename = strdup(buf); - /* read file_length */ - if (gzread(s->mar_gzfile, &(e->file_length), sizeof(int)) != sizeof(int)) - { - gzerr(s->mar_gzfile); - return -1; - } - /* read data_offset */ - if (gzread(s->mar_gzfile, &(e->data_offset), sizeof(int)) != sizeof(int)) - { - gzerr(s->mar_gzfile); - return -1; - } - /* write down chaining */ - if (previous_element) - previous_element->next_element = e; - else - s->first_element = e; - previous_element = e; - } - else - end_filetable = 1; - - } - /* chaining for last element */ - previous_element->next_element = NULL; - - return 0; -} - diff --git a/mdk-stage1/mar/mar-extract-only.h b/mdk-stage1/mar/mar-extract-only.h index 8a68cc13d..6fa34efe4 100644 --- a/mdk-stage1/mar/mar-extract-only.h +++ b/mdk-stage1/mar/mar-extract-only.h @@ -26,11 +26,7 @@ #ifndef MAR_EXTRACT_ONLY_H #define MAR_EXTRACT_ONLY_H -#include "mar.h" - -int mar_open_file(char *filename, struct mar_stream *s); -int mar_extract_file(struct mar_stream *s, char *filename, char *dest_dir); -int mar_calc_integrity(struct mar_stream *s); -char ** mar_list_contents(struct mar_stream *s); +int mar_extract_file(char *mar_filename, char *filename_to_extract, char *dest_dir); +char ** mar_list_contents(char *mar_filename); #endif diff --git a/mdk-stage1/mar/mar-frontend.c b/mdk-stage1/mar/mar-frontend.c index 69fba17b3..82f870d57 100644 --- a/mdk-stage1/mar/mar-frontend.c +++ b/mdk-stage1/mar/mar-frontend.c @@ -27,17 +27,6 @@ #include "mar.h" #include "mar-extract-only.h" -void -mar_list_files(struct mar_stream *s) -{ - struct mar_element * elem = s->first_element; - printf("%-20s%8s\n", "FILENAME", "LENGTH"); - while (elem) - { - printf("%-20s%8d\n", elem->filename, elem->file_length); - elem = elem->next_element; - } -} int file_size(char *filename) @@ -57,32 +46,36 @@ file_size(char *filename) */ /* ``files'' is a NULL-terminated array of char* */ +char * fnf_tag = "FILE_NOT_FOUND&"; + int mar_create_file(char *dest_file, char **files) { int filenum = 0; - int current_offset_filetable; - int current_offset_rawdata; + int current_offset_filetable = 0; + int current_delta_rawdata = 0; + int filetable_size; char * temp_marfile_buffer; int total_length; /* calculate offset of ``raw_files_data'' */ - current_offset_rawdata = sizeof(int) + sizeof(char); /* crc32, ``char 0'' */ + total_length = sizeof(char); /* ``char 0'' */ while (files[filenum]) { - current_offset_rawdata += 2*sizeof(int) /* file_length, data_offset */ + strlen(files[filenum]) + 1; + total_length += 2*sizeof(int) /* file_length, data_offset */ + strlen(files[filenum]) + 1; filenum++; } DEBUG_MAR(printf("D: mar::create_marfile number-of-files %d offset-data-start %d\n", filenum, current_offset_rawdata);); + filetable_size = total_length; + /* calculate length of final uncompressed marfile, for malloc */ - total_length = current_offset_rawdata; /* first part of the marfile: the crc plus filetable */ filenum = 0; while (files[filenum]) { int fsiz = file_size(files[filenum]); if (fsiz == -1) - files[filenum] = "FILE_NOT_FOUND&"; + files[filenum] = fnf_tag; else total_length += fsiz; filenum++; @@ -91,11 +84,10 @@ mar_create_file(char *dest_file, char **files) temp_marfile_buffer = (char *) malloc(total_length); /* create the whole file in-memory (not with alloca! it can be bigger than typical limit for stack of programs (ulimit -s) */ DEBUG_MAR(printf("D: mar::create_marfile total-length %d\n", total_length);); - current_offset_filetable = sizeof(int); /* first file is after the crc */ filenum = 0; while (files[filenum]) { - if (strcmp(files[filenum], "FILE_NOT_FOUND&")) { + if (strcmp(files[filenum], fnf_tag)) { FILE * f = fopen(files[filenum], "r"); int fsize; if (!f) @@ -115,18 +107,18 @@ mar_create_file(char *dest_file, char **files) current_offset_filetable += sizeof(int); /* data_offset */ - memcpy(&temp_marfile_buffer[current_offset_filetable], ¤t_offset_rawdata, sizeof(int)); + memcpy(&temp_marfile_buffer[current_offset_filetable], ¤t_delta_rawdata, sizeof(int)); current_offset_filetable += sizeof(int); /* data_raw_data */ - if (fread(&temp_marfile_buffer[current_offset_rawdata], 1, fsize, f) != fsize) + if (fread(&temp_marfile_buffer[current_delta_rawdata + filetable_size], 1, fsize, f) != fsize) { perror(files[filenum]); return -1; } fclose(f); - current_offset_rawdata += fsize; + current_delta_rawdata += fsize; } filenum++; @@ -135,30 +127,20 @@ mar_create_file(char *dest_file, char **files) /* write down ``char 0'' to terminate file table */ memset(&temp_marfile_buffer[current_offset_filetable], 0, sizeof(char)); - /* calculate crc with all the data we now got */ - { - int current_crc = 0; - int i; - for (i=sizeof(int); i<total_length ; i++) - current_crc += temp_marfile_buffer[i]; - memcpy(&temp_marfile_buffer[0], ¤t_crc, sizeof(int)); - DEBUG_MAR(printf("D: mar::create_marfile computed-crc %d\n", current_crc);); - } - /* ok, buffer is ready, let's write it on-disk */ { - gzFile f = gzopen(dest_file, "w9"); + BZFILE * f = BZ2_bzopen(dest_file, "w9"); if (!f) { perror(dest_file); return -1; } - if (gzwrite(f, temp_marfile_buffer, total_length) != total_length) + if (BZ2_bzwrite(f, temp_marfile_buffer, total_length) != total_length) { - fprintf(stderr, gzerror(f, &gz_errnum)); + fprintf(stderr, BZ2_bzerror(f, &z_errnum)); return -1; } - gz_errnum = gzclose(f); + BZ2_bzclose(f); } printf("mar: created archive %s (%d files, length %d)\n", dest_file, filenum, total_length); @@ -183,30 +165,21 @@ main(int argc, char **argv) { if (strcmp(argv[1], "-l") == 0) { - struct mar_stream s; - if (mar_open_file(argv[2], &s) != 0) - { - fprintf(stderr, "E: open-marfile-failed\n"); - exit(-1); - } - mar_list_files(&s); + char ** contents = mar_list_contents(argv[2]); + if (contents) + while (contents && *contents) { + printf("\t%s\n", *contents); + contents++; + } exit(0); } - if ((strcmp(argv[1], "-x") == 0) && argc >= 4) + if ((strcmp(argv[1], "-x") == 0) && argc == 4) { - struct mar_stream s; - int i = 3; - if (mar_open_file(argv[2], &s) != 0) + int res = mar_extract_file(argv[2], argv[3], "./"); + if (res == 1) + fprintf(stderr, "W: file-not-found-in-archive %s\n", argv[3]); + if (res == -1) exit(-1); - while (i < argc) - { - int res = mar_extract_file(&s, argv[i], "./"); - if (res == 1) - fprintf(stderr, "W: file-not-found-in-archive %s\n", argv[i]); - if (res == -1) - exit(-1); - i++; - } exit(0); } if ((strcmp(argv[1], "-c") == 0) && argc >= 4) diff --git a/mdk-stage1/mar/mar.h b/mdk-stage1/mar/mar.h index e9633ab92..672d7ded8 100644 --- a/mdk-stage1/mar/mar.h +++ b/mdk-stage1/mar/mar.h @@ -15,7 +15,7 @@ /* * mar - The Mandrake Archiver * - * An archiver that supports compression (through zlib). + * An archiver that supports compression (through bzlib). * * Designed to be small so these bad designs are inside: * . archive and compression are mixed together @@ -36,14 +36,13 @@ #include <errno.h> #include <unistd.h> -#include <zlib.h> +#include <bzlib.h> /* * Format of a mar file: * - * int crc32 \ * ASCIIZ filename \ | - * int file_length | repeated | gzipped + * int file_length | repeated | bzipped * int pointer_in_archive / | * char 0 | * raw_files_data / @@ -60,12 +59,11 @@ struct mar_element struct mar_stream { - int crc32; /* crc32 of the mar stream; it is the addition of all the 8-bit char's from the stream */ struct mar_element * first_element; /* pointer to the first element inside the mar stream */ - gzFile mar_gzfile; /* associated gzFile (opened) */ + BZFILE * mar_zfile; /* associated zfile (opened) */ }; -int gz_errnum; +int z_errnum; #define DEBUG_MAR(x) |