Author: uwe Date: 2007-06-26 13:55:06 +0200 (Tue, 26 Jun 2007) New Revision: 366
Modified: LinuxBIOSv3/include/lar.h LinuxBIOSv3/util/lar/create.c LinuxBIOSv3/util/lar/extract.c LinuxBIOSv3/util/lar/lar.c LinuxBIOSv3/util/lar/lar.h LinuxBIOSv3/util/lar/lib.c LinuxBIOSv3/util/lar/list.c LinuxBIOSv3/util/lzma/minilzma.cc LinuxBIOSv3/util/nrv2b/nrv2b.c Log: - Extend lar format to support compression (incompatible format change!) - Adapt the compression utilities for integration into lar - Add compression capabilities to lar and expose in user interface - Provide a way to mark files as non-compressible
Signed-off-by: Patrick Georgi patrick@georgi-clan.de Acked-by: Uwe Hermann uwe@hermann-uwe.de
- Diese und die folgenden Zeilen werden ignoriert --
M include/lar.h M util/lzma/minilzma.cc M util/nrv2b/nrv2b.c M util/lar/lar.c M util/lar/create.c M util/lar/lar.h M util/lar/lib.c M util/lar/extract.c M util/lar/list.c
Modified: LinuxBIOSv3/include/lar.h =================================================================== --- LinuxBIOSv3/include/lar.h 2007-06-25 21:15:44 UTC (rev 365) +++ LinuxBIOSv3/include/lar.h 2007-06-26 11:55:06 UTC (rev 366) @@ -58,8 +58,11 @@ struct lar_header { char magic[8]; u32 len; + u32 reallen; u32 checksum; + u32 compchecksum; u32 offset; + u32 compression; };
struct mem_file {
Modified: LinuxBIOSv3/util/lar/create.c =================================================================== --- LinuxBIOSv3/util/lar/create.c 2007-06-25 21:15:44 UTC (rev 365) +++ LinuxBIOSv3/util/lar/create.c 2007-06-26 11:55:06 UTC (rev 366) @@ -3,6 +3,7 @@ * * Copyright (C) 2006-2007 coresystems GmbH * (Written by Stefan Reinauer stepan@coresystems.de for coresystems GmbH) + * Copyright (C) 2007 Patrick Georgi patrick@georgi-clan.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,10 +31,22 @@ #include <netinet/in.h> #include <libgen.h>
- #include "lib.h" #include "lar.h"
+extern enum compalgo algo; + +void compress_impossible(char *in, u32 in_len, char *out, u32 *out_len) { + fprintf(stderr, + "The selected compression algorithm wasn't compiled in.\n"); + exit(1); +} + +void do_no_compress(char *in, u32 in_len, char *out, u32 *out_len) { + memcpy(out, in, in_len); + out_len[0] = in_len; +} + int create_lar(const char *archivename, struct file *files) { int i, ret; @@ -41,14 +54,16 @@ int bb_header_len = 0; FILE *archive, *source; char *tempmem; - char *filebuf; + char *filebuf, *filetarget; char *pathname; u32 *walk; u32 csum; int pathlen, entrylen, filelen; + u32 compfilelen; long currentsize = 0; struct lar_header *header; struct stat statbuf; + enum compalgo thisalgo;
if (!files) { fprintf(stderr, "No files for archive %s\n", archivename); @@ -68,6 +83,13 @@ while (files) { char *name = files->name;
+ thisalgo = algo; + + if (strstr(name, "nocompress:") == name) { + name += 11; + thisalgo = none; + } + /* skip ./ if available */ if (name[0] == '.' && name[1] == '/') name += 2; @@ -97,24 +119,35 @@ pathlen = (pathlen + 15) & 0xfffffff0;/* Align to 16 bytes. */
/* Read file into memory. */ - filebuf = pathname + pathlen; + filebuf = malloc(filelen); + filetarget = pathname + pathlen; source = fopen(name, "r"); if (!source) { fprintf(stderr, "No such file %s\n", name); exit(1); } - fread(filebuf, statbuf.st_size, 1, source); + fread(filebuf, filelen, 1, source); fclose(source); + compress_functions[thisalgo](filebuf, filelen, filetarget, + &compfilelen); + if ((compfilelen >= filelen) && (thisalgo != none)) { + thisalgo = none; + compress_functions[thisalgo](filebuf, filelen, + filetarget, &compfilelen); + } + free(filebuf);
/* Create correct header. */ memcpy(header, MAGIC, 8); - header->len = htonl(statbuf.st_size); + header->compression = htonl(thisalgo); + header->reallen = htonl(filelen); + header->len = htonl(compfilelen); header->offset = htonl(sizeof(struct lar_header) + pathlen);
/* Calculate checksum. */ csum = 0; for (walk = (u32 *) tempmem; - walk < (u32 *) (tempmem + statbuf.st_size + + walk < (u32 *) (tempmem + compfilelen + sizeof(struct lar_header) + pathlen); walk++) { csum += ntohl(*walk); @@ -122,7 +155,7 @@ header->checksum = htonl(csum);
/* Write out entry to archive. */ - entrylen = (filelen + pathlen + sizeof(struct lar_header) + + entrylen = (compfilelen + pathlen + sizeof(struct lar_header) + 15) & 0xfffffff0;
fwrite(tempmem, entrylen, 1, archive); @@ -216,6 +249,7 @@ /* construct header */ bb=(struct lar_header *)bootblock_header; memcpy(bb->magic, MAGIC, 8); + bb->reallen = htonl(bootblock_len); bb->len = htonl(bootblock_len); bb->offset = htonl(bb_header_len);
Modified: LinuxBIOSv3/util/lar/extract.c =================================================================== --- LinuxBIOSv3/util/lar/extract.c 2007-06-25 21:15:44 UTC (rev 365) +++ LinuxBIOSv3/util/lar/extract.c 2007-06-26 11:55:06 UTC (rev 366) @@ -3,6 +3,7 @@ * * Copyright (C) 2006-2007 coresystems GmbH * (Written by Stefan Reinauer stepan@coresystems.de for coresystems GmbH) + * Copyright (C) 2007 Patrick Georgi patrick@georgi-clan.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -32,6 +33,16 @@ #include "lib.h" #include "lar.h"
+void uncompress_impossible(char *dst, char *src, u32 len) { + fprintf(stderr, + "Cannot uncompress data (algorithm not compiled in).\n"); + exit(1); +} + +void do_no_uncompress(char *dst, char *src, u32 len) { + memcpy(dst, src, len); +} + int extract_lar(const char *archivename, struct file *files) { int archivefile; @@ -116,8 +127,17 @@ exit(1); }
- fwrite(walk + ntohl(header->offset), ntohl(header->len), - 1, file_to_extract); + if (ntohl(header->compression) == none) { + fwrite(walk + ntohl(header->offset), + ntohl(header->len), 1, file_to_extract); + } else { + char *buf = malloc(ntohl(header->reallen)); + uncompress_functions[ntohl(header->compression)](buf, + walk + ntohl(header->offset), + ntohl(header->len)); + fwrite(buf, ntohl(header->reallen), 1, file_to_extract); + free(buf); + } fclose(file_to_extract);
walk += (ntohl(header->offset) + ntohl(header->len)
Modified: LinuxBIOSv3/util/lar/lar.c =================================================================== --- LinuxBIOSv3/util/lar/lar.c 2007-06-25 21:15:44 UTC (rev 365) +++ LinuxBIOSv3/util/lar/lar.c 2007-06-26 11:55:06 UTC (rev 366) @@ -39,6 +39,7 @@ static int isverbose = 0; static long larsize = 0; static char *bootblock = NULL; +enum compalgo algo = none;
static void usage(char *name) { @@ -72,6 +73,7 @@
static struct option long_options[] = { {"create", 0, 0, 'c'}, + {"compress-algo", 1, 0, 'C'}, {"extract", 0, 0, 'x'}, {"list", 0, 0, 'l'}, {"size", 1, 0, 's'}, @@ -87,12 +89,20 @@ exit(1); }
- while ((opt = getopt_long(argc, argv, "cxls:b:vVh?", + while ((opt = getopt_long(argc, argv, "cC:xls:b:vVh?", long_options, &option_index)) != EOF) { switch (opt) { case 'c': larmode = CREATE; break; + case 'C': + if (strcmp("lzma", optarg) == 0) { + algo = lzma; + } + if (strcmp("nrv2b", optarg) == 0) { + algo = nrv2b; + } + break; case 'l': larmode = LIST; break;
Modified: LinuxBIOSv3/util/lar/lar.h =================================================================== --- LinuxBIOSv3/util/lar/lar.h 2007-06-25 21:15:44 UTC (rev 365) +++ LinuxBIOSv3/util/lar/lar.h 2007-06-26 11:55:06 UTC (rev 366) @@ -3,6 +3,7 @@ * * Copyright (C) 2006 coresystems GmbH * (Written by Stefan Reinauer stepan@coresystems.de for coresystems GmbH) + * Copyright (C) 2007 Patrick Georgi patrick@georgi-clan.de * * This file is dual-licensed. You can choose between: * - The GNU GPL, version 2, as published by the Free Software Foundation @@ -48,6 +49,7 @@ */
#include <stdint.h> +#include "../../build/config.h"
#define MAGIC "LARCHIVE" #define MAX_PATHLEN 1024 @@ -58,6 +60,63 @@ struct lar_header { char magic[8]; u32 len; + u32 reallen; u32 checksum; + u32 compchecksum; u32 offset; + /* Compression: + * 0 = no compression + * 1 = lzma + * 2 = nrv2b + */ + u32 compression; }; + +enum compalgo { none = 0, lzma = 1, nrv2b = 2 }; + +typedef void (*compress_func) (char *, u32, char *, u32 *); +typedef void (*uncompress_func) (char *, char *, u32); + +void compress_impossible(char *in, u32 in_len, char *out, u32 *out_len); +void do_no_compress(char *in, u32 in_len, char *out, u32 *out_len); +#ifdef CONFIG_COMPRESSION_LZMA +void do_lzma_compress(char *in, u32 in_len, char *out, u32 *out_len); +#else +#define do_lzma_compress compress_impossible +#endif +#ifdef CONFIG_COMPRESSION_NRV2B +void do_nrv2b_compress(char *in, u32 in_len, char *out, u32 *out_len); +#else +#define do_nrv2b_compress compress_impossible +#endif + +void uncompress_impossible(char *, char *, u32); +void do_no_uncompress(char *, char *, u32); +#ifdef CONFIG_COMPRESSION_LZMA +void do_lzma_uncompress(char *, char *, u32); +#else +#define do_lzma_uncompress uncompress_impossible +#endif +#ifdef CONFIG_COMPRESSION_NRV2B +void do_nrv2b_uncompress(char *, char *, u32); +#else +#define do_nrv2b_uncompress uncompress_impossible +#endif + +static compress_func compress_functions[] = { + do_no_compress, + do_lzma_compress, + do_nrv2b_compress, +}; + +static uncompress_func uncompress_functions[] = { + do_no_uncompress, + do_lzma_uncompress, + do_nrv2b_uncompress, +}; + +static const char *algo_name[] = { + "", + "lzma", + "nrv2b", +};
Modified: LinuxBIOSv3/util/lar/lib.c =================================================================== --- LinuxBIOSv3/util/lar/lib.c 2007-06-25 21:15:44 UTC (rev 365) +++ LinuxBIOSv3/util/lar/lib.c 2007-06-26 11:55:06 UTC (rev 366) @@ -121,9 +121,15 @@ { struct stat filestat; int ret = -1; + const char *realname;
+ realname = name; + if (strstr(name, "nocompress:") == name) { + realname = name + 11; + } + /* printf("... add_files %s\n", name); */ - if (stat(name, &filestat) == -1) { + if (stat(realname, &filestat) == -1) { fprintf(stderr, "Error getting file attributes of %s\n", name); return -1; } @@ -145,7 +151,7 @@ } // Is it a directory? if (S_ISDIR(filestat.st_mode)) { - ret = handle_directory(name); + ret = handle_directory(realname); } // Is it a regular file? if (S_ISREG(filestat.st_mode)) {
Modified: LinuxBIOSv3/util/lar/list.c =================================================================== --- LinuxBIOSv3/util/lar/list.c 2007-06-25 21:15:44 UTC (rev 365) +++ LinuxBIOSv3/util/lar/list.c 2007-06-26 11:55:06 UTC (rev 366) @@ -3,6 +3,7 @@ * * Copyright (C) 2006-2007 coresystems GmbH * (Written by Stefan Reinauer stepan@coresystems.de for coresystems GmbH) + * Copyright (C) 2007 Patrick Georgi patrick@georgi-clan.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -91,8 +92,20 @@
printf(" %s ", walk + sizeof(struct lar_header));
- printf("(%d bytes @0x%lx)\n", ntohl(header->len), - (unsigned long)(walk - inmap) + ntohl(header->offset)); + if (ntohl(header->compression) == none) { + printf("(%d bytes @0x%lx)\n", + ntohl(header->len), + (unsigned long)(walk - inmap) + + ntohl(header->offset)); + } else { + printf("(%d bytes, %s compressed to %d bytes " + "@0x%lx)\n", + ntohl(header->reallen), + algo_name[ntohl(header->compression)], + ntohl(header->len), + (unsigned long)(walk - inmap) + + ntohl(header->offset)); + }
walk += (ntohl(header->len) + ntohl(header->offset) - 1) & 0xfffffff0;
Modified: LinuxBIOSv3/util/lzma/minilzma.cc =================================================================== --- LinuxBIOSv3/util/lzma/minilzma.cc 2007-06-25 21:15:44 UTC (rev 365) +++ LinuxBIOSv3/util/lzma/minilzma.cc 2007-06-26 11:55:06 UTC (rev 366) @@ -4,7 +4,8 @@ * Copyright (C) 2002 Eric Biederman * Copyright (C) 2005 Joel Yliluoma * Copyright (C) 2007 coresystems GmbH - * Adapted by Stefan Reinauer stepan@coresystems.de for coresystems GmbH. + * (Adapted by Stefan Reinauer stepan@coresystems.de for coresystems GmbH) + * Copyright (C) 2007 Patrick Georgi patrick@georgi-clan.de * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,8 +22,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA */
- - #include "C/Common/MyInitGuid.h" #include "C/7zip/Compress/LZMA/LZMAEncoder.h"
@@ -281,13 +280,20 @@ #else extern "C" {
-void do_lzma_compress(char* in, unsigned long in_len, char* out, unsigned long* out_len) { +void do_lzma_compress(char *in, unsigned long in_len, char *out, + unsigned long *out_len) { std::vector<unsigned char> result; - result = LZMACompress(std::vector<unsigned char>(in,in+in_len)); + result = LZMACompress(std::vector<unsigned char>(in, in + in_len)); *out_len = result.size(); - std::memcpy(out, &result[0], *out_len); + std::memcpy(out, &result[0], *out_len); }
+void do_lzma_uncompress(char *dst, char *src, unsigned long len) { + std::vector<unsigned char> result; + result = LZMADeCompress(std::vector<unsigned char>(src, src + len)); + std::memcpy(dst, &result[0], result.size()); } + +} #endif
Modified: LinuxBIOSv3/util/nrv2b/nrv2b.c =================================================================== --- LinuxBIOSv3/util/nrv2b/nrv2b.c 2007-06-25 21:15:44 UTC (rev 365) +++ LinuxBIOSv3/util/nrv2b/nrv2b.c 2007-06-26 11:55:06 UTC (rev 366) @@ -28,6 +28,11 @@ The conversion was performed by Eric Biederman ebiederman@lnxi.com. 20 August 2002 + + Added do_nrv2b_uncompress(). + by Patrick Georgi patrick@georgi-clan.de + 2007-06-26 +
**************************************************************/ #define UCLPACK_COMPAT 0 @@ -1304,6 +1309,56 @@ out = malloc(*out_len); ucl_nrv2b_99_compress(in, in_len, out, out_len, 0 ); } + +void do_nrv2b_uncompress(char* dst, char* src, unsigned long len) { + unsigned long ilen = 0, olen = 0, last_m_off = 1; + for (;;) { + unsigned int m_off, m_len; + while (GETBIT(bb, src, ilen)) { + FAIL(ilen >= src_len, "input overrun"); + FAIL(olen >= dst_len, "output overrun"); + dst[olen++] = src[ilen++]; + } + m_off = 1; + do { + m_off = (m_off * 2) + GETBIT(bb, src, ilen); + FAIL(ilen >= src_len, "input overrun"); + FAIL(m_off > 0xffffffU +3, "lookbehind overrun"); + } while (!GETBIT(bb, src, ilen)); + if (m_off == 2) { + m_off = last_m_off; + } else { + FAIL(ilen >= src_len, "input overrun"); + m_off = ((m_off - 3) * 256) + src[ilen++]; + if (m_off == 0xffffffffU) + break; + last_m_off = ++m_off; + } + m_len = GETBIT(bb, src, ilen); + m_len = (m_len * 2) + GETBIT(bb, src, ilen); + if (m_len == 0) { + m_len++; + do { + m_len = (m_len * 2) + GETBIT(bb, src, ilen); + FAIL(ilen >= src_len, "input overrun"); + FAIL(m_len >= dst_len, "output overrun"); + } while(!GETBIT(bb, src, ilen)); + m_len += 2; + } + m_len += (m_off > 0xd00); + FAIL(olen + m_len > dst_len, "output overrun"); + FAIL(m_off > olen, "lookbehind overrun"); + { + const uint8_t *m_pos; + m_pos = dst + olen - m_off; + dst[olen++] = *m_pos++; + do { + dst[olen++] = *m_pos++; + } while(--m_len > 0); + } + } + FAIL(ilen < src_len, "input not consumed"); +} #endif
#ifdef DECODE