- 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 git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@366 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
parent
33c16b873a
commit
d8ad5a5bc9
9 changed files with 226 additions and 20 deletions
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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 create_lar(const char *archivename, struct file *files)
|
|||
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 @@ int create_lar(const char *archivename, struct file *files)
|
|||
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 @@ int create_lar(const char *archivename, struct file *files)
|
|||
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 @@ int create_lar(const char *archivename, struct file *files)
|
|||
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 @@ int create_lar(const char *archivename, struct file *files)
|
|||
/* 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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 @@ int extract_lar(const char *archivename, struct file *files)
|
|||
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)
|
||||
|
|
|
|||
|
|
@ -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 @@ int main(int argc, char *argv[])
|
|||
|
||||
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 @@ int main(int argc, char *argv[])
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -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 @@ typedef uint32_t u32;
|
|||
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",
|
||||
};
|
||||
|
|
|
|||
|
|
@ -121,9 +121,15 @@ int add_files(const char *name)
|
|||
{
|
||||
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 @@ int add_files(const char *name)
|
|||
}
|
||||
// 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)) {
|
||||
|
|
|
|||
|
|
@ -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 @@ int list_lar(const char *archivename, struct file *files)
|
|||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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,11 +280,18 @@ int main(int argc, char *argv[])
|
|||
#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());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 @@ void do_nrv2b_compress(char* in, unsigned long in_len, char* out, unsigned long*
|
|||
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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue