Author: stepan Date: 2007-08-20 01:31:58 +0200 (Mon, 20 Aug 2007) New Revision: 470
Removed: LinuxBIOSv3/util/lar/create.c LinuxBIOSv3/util/lar/extract.c LinuxBIOSv3/util/lar/list.c Modified: LinuxBIOSv3/util/lar/Makefile LinuxBIOSv3/util/lar/lar.c LinuxBIOSv3/util/lar/lar.h LinuxBIOSv3/util/lar/lib.c LinuxBIOSv3/util/lar/lib.h Log: In preparation for adding new LAR functionality - this patch consolidates creating and accessing the LAR into new code utilizing mmap which facilitates moving about within the archive.
This code also turns the bootblock path name as a constant value. It also requires that the user specify a size when the LAR is created.
This patch was missing do_no_uncompress() which was fixed before commit. This part should be reviewed.
Signed-off-by: Jordan crouse jordan.crouse@amd.com Acked-by: Stefan Reinauer stepan@coresystems.de
Modified: LinuxBIOSv3/util/lar/Makefile =================================================================== --- LinuxBIOSv3/util/lar/Makefile 2007-08-19 22:58:42 UTC (rev 469) +++ LinuxBIOSv3/util/lar/Makefile 2007-08-19 23:31:58 UTC (rev 470) @@ -18,7 +18,7 @@ ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA ##
-LAROBJ := lar.o create.o extract.o list.o lib.o bootblock.o +LAROBJ := lar.o stream.o lib.o
LARDIR := lardir
Deleted: LinuxBIOSv3/util/lar/create.c =================================================================== --- LinuxBIOSv3/util/lar/create.c 2007-08-19 22:58:42 UTC (rev 469) +++ LinuxBIOSv3/util/lar/create.c 2007-08-19 23:31:58 UTC (rev 470) @@ -1,278 +0,0 @@ -/* - * lar - LinuxBIOS archiver - * - * 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 - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h> -#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; - int diff = 0; - int bb_header_len = 0; - FILE *archive, *source; - char *tempmem; - 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); - exit(1); - } - - if (verbose()) - printf("Opening %s\n", archivename); - - archive = fopen(archivename, "w"); - if (!archive) { - fprintf(stderr, "Could not open archive %s for writing\n", - archivename); - exit(1); - } - - 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; - - if (verbose()) - printf(" Adding %s to archive\n", name); - - ret = stat(name, &statbuf); - if (ret) { - fprintf(stderr, "No such file %s\n", name); - exit(1); - } - filelen = statbuf.st_size; - - tempmem = malloc(sizeof(struct lar_header) + MAX_PATHLEN - + filelen + 16); - if (!tempmem) { - fprintf(stderr, "Out of memory.\n"); - return (1); - } - memset(tempmem, 0, sizeof(struct lar_header) + MAX_PATHLEN - + filelen + 16); - - header = (struct lar_header *)tempmem; - pathname = tempmem + sizeof(struct lar_header); - pathlen = snprintf(pathname, MAX_PATHLEN - 1, name) + 1; - pathlen = (pathlen + 15) & 0xfffffff0; /* Align to 16 bytes. */ - - /* Read file into memory. */ - filebuf = malloc(filelen); - filetarget = pathname + pathlen; - source = fopen(name, "r"); - if (!source) { - fprintf(stderr, "No such file %s\n", name); - exit(1); - } - 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->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 + compfilelen + - sizeof(struct lar_header) + pathlen); - walk++) { - csum += ntohl(*walk); - } - header->checksum = htonl(csum); - - /* Write out entry to archive. */ - entrylen = (compfilelen + pathlen + sizeof(struct lar_header) + - 15) & 0xfffffff0; - - fwrite(tempmem, entrylen, 1, archive); - - free(tempmem); - - /* size counter */ - currentsize += entrylen; - - files = files->next; - } - - /* Calculate difference, if a size has been specified. - * If diff is below zero, the size has been exceeded. - * If diff is above zero, it specifies the number of - * padding bytes required for the image. - * Otherwise diff stays 0 and no action is taken below. - */ - if (get_larsize()) - diff = get_larsize() - currentsize; - - /* If there's a bootblock loaded, some space is required - * _after_ the padding. - * Calculate this size here, but write the bootblock later. - */ - - if (bootblock_len) { - if (verbose()) - printf("Detected bootblock of %d bytes\n", - bootblock_len); - - bb_header_len = sizeof(struct lar_header) + - ((strlen(basename(get_bootblock())) + 15) & 0xfffffff0); - - bb_header_len = (bb_header_len + 15) & 0xfffffff0; - - if (verbose()) - printf("Required bootblock header of %d bytes\n", - bb_header_len); - - diff -= bootblock_len; - diff -= bb_header_len; - } - - /* The image became too big. Print an error message and exit, - * deleting the file. So nobody used an invalid image by accident. - * - * Don't delete the image in "Out of memory" situations. If memory - * is _that_ tight that a few bytes don't fit anymore, everything - * else will fail as well, so just print an error and exit the - * program as soon as possible. - */ - - if (diff < 0) { - fprintf(stderr, - "Error: LAR archive exceeded size (%ld > %ld)\n", - currentsize, get_larsize()); - - /* Open files can not be deleted. */ - fclose(archive); - /* File is too big, delete it. */ - unlink(archivename); - return -1; - } - - /* Pad the image. */ - - if (diff > 0) { - char *padding; - /* generate padding (0xff is flash friendly) */ - padding = malloc(diff); - if (!padding) { - fprintf(stderr, "Out of memory.\n"); - exit(1); - } - memset(padding, 0xff, diff); - fwrite(padding, diff, 1, archive); - free(padding); - } - - if (bootblock_len) { - char *bootblock_header; - struct lar_header *bb; - - bootblock_header = malloc(bb_header_len); - if (!bootblock_header) { - fprintf(stderr, "Out of memory.\n"); - exit(1); - } - - memset(bootblock_header, 0, bb_header_len); - - /* 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); - - /* TODO checksum */ - - /* Write filename. we calculated the buffer size, - * so no overflow danger here. - */ - strcpy(bootblock_header + sizeof(struct lar_header), - basename(get_bootblock())); - - fwrite(bootblock_header, bb_header_len, 1, archive); - fwrite(bootblock_code, bootblock_len, 1, archive); - } - - fclose(archive); - - if (verbose()) - printf("done.\n"); - - return 0; -}
Deleted: LinuxBIOSv3/util/lar/extract.c =================================================================== --- LinuxBIOSv3/util/lar/extract.c 2007-08-19 22:58:42 UTC (rev 469) +++ LinuxBIOSv3/util/lar/extract.c 2007-08-19 23:31:58 UTC (rev 470) @@ -1,155 +0,0 @@ -/* - * lar - LinuxBIOS archiver - * - * 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 - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <netinet/in.h> - -#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; - char *inmap; - char *walk; - char *fullname, *pathname, *pos; - struct lar_header *header; - struct stat statbuf; - int archivelen; - int do_extract; - int i; - - if (stat(archivename, &statbuf) != 0) { - printf("Error opening %s: %s\n", archivename, strerror(errno)); - exit(1); - } - - if (verbose()) - printf("Opening %s\n", archivename); - - archivefile = open(archivename, O_RDONLY); - if (archivefile == -1) { - printf("Error while opening %s: %s\n", - archivename, strerror(errno)); - exit(1); - } - archivelen = statbuf.st_size; - - inmap = mmap(NULL, statbuf.st_size, PROT_READ, - MAP_SHARED, archivefile, 0); - - for (walk = inmap; walk < inmap + statbuf.st_size; walk += 16) { - FILE *file_to_extract; - - if (strcmp(walk, MAGIC) != 0) - continue; - - header = (struct lar_header *)walk; - fullname = walk + sizeof(struct lar_header); - - /* FIXME: check checksum. */ - - do_extract = 1; - if (files) { - struct file *fwalk = files; - do_extract = 0; - while (fwalk) { - if (strcmp(fullname, fwalk->name) == 0) { - do_extract = 1; - break; - } - fwalk = fwalk->next; - } - } - - /* Don't extract this one, skip it. */ - if (!do_extract) - continue; - - if (verbose()) - printf(" Extracting file %s\n", - walk + sizeof(struct lar_header)); - - /* Create the directory if it does not exist. */ - pathname = strdup(fullname); - if (!pathname) { - fprintf(stderr, "Out of memory.\n"); - exit(1); - } - - pos = strrchr(pathname, '/'); - if (pos) { - pos[1] = 0; - /* printf("Pathname %s\n",pathname); */ - mkdirp_below(".", pathname, 0755); - } - free(pathname); - - file_to_extract = fopen(fullname, "w"); - if (!file_to_extract) { - fprintf(stderr, "error creating file %s.\n", fullname); - exit(1); - } - - 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) - - 1) & 0xfffffff0; - } - - munmap(inmap, statbuf.st_size); - close(archivefile); - - if (verbose()) - printf("done.\n"); - - return 0; -}
Modified: LinuxBIOSv3/util/lar/lar.c =================================================================== --- LinuxBIOSv3/util/lar/lar.c 2007-08-19 22:58:42 UTC (rev 469) +++ LinuxBIOSv3/util/lar/lar.c 2007-08-19 23:31:58 UTC (rev 470) @@ -62,6 +62,64 @@ return bootblock; }
+int create_lar(const char *archivename, struct file *files) +{ + struct lar *lar = lar_new_archive(archivename, larsize); + + if (lar == NULL) { + fprintf(stderr, "Unable to create %s as a LAR archive.\n", + archivename); + exit(1); + } + + for( ; files; files = files->next) { + if (lar_add_file(lar, files->name)) { + fprintf(stderr, "Error adding %s to the LAR.\n", files->name); + lar_close_archive(lar); + exit(1); + } + } + + if (lar_add_bootblock(lar, bootblock)) { + fprintf(stderr, "Error adding the bootblock to the LAR.\n"); + lar_close_archive(lar); + exit(1); + } + + lar_close_archive(lar); + return 0; +} + +int list_lar(const char *archivename, struct file *files) +{ + struct lar *lar = lar_open_archive(archivename); + + if (lar == NULL) { + fprintf(stderr, "Unable to open LAR archive %s\n", archivename); + exit(1); + } + + lar_list_files(lar, files); + lar_close_archive(lar); + return 0; +} + +int extract_lar(const char *archivename, struct file *files) +{ + int ret; + + struct lar *lar = lar_open_archive(archivename); + + if (lar == NULL) { + fprintf(stderr, "Unable to open LAR archive %s\n", archivename); + exit(1); + } + + ret = lar_extract_files(lar, files); + lar_close_archive(lar); + return ret; +} + int main(int argc, char *argv[]) { int opt; @@ -173,16 +231,9 @@
/* adding a bootblock only makes sense when creating a lar */ if (!larsize) { - printf("Warning: When specifying a bootblock " - "you should also set an archive size.\n"); + printf("When creating a LAR archive, you must specify an archive size.\n"); + exit(1); } - - /* load the bootblock */ - if (larmode == CREATE) { - load_bootblock(bootblock); - fixup_bootblock(); - } - }
if (optind < argc) {
Modified: LinuxBIOSv3/util/lar/lar.h =================================================================== --- LinuxBIOSv3/util/lar/lar.h 2007-08-19 22:58:42 UTC (rev 469) +++ LinuxBIOSv3/util/lar/lar.h 2007-08-19 23:31:58 UTC (rev 470) @@ -54,7 +54,11 @@ #define MAX_PATHLEN 1024 #define BOOTBLOCK_SIZE 16384
+#define BOOTBLOCK_NAME "bootblock" +#define BOOTBLOCK_NAME_LEN 16 + typedef uint32_t u32; +typedef uint8_t u8;
struct lar_header { char magic[8]; @@ -71,6 +75,16 @@ u32 compression; };
+/**\struct + * A structure containing information about a currently open and mapped + * LAR archive + */ +struct lar { + int fd; /**< The file descriptor of the open archive */ + u8 *map; /**< A pointer to the mmap()ed file */ + u32 size; /**< Size of the mmaped file */ +}; + enum compalgo { none = 0, lzma = 1, nrv2b = 2 };
typedef void (*compress_func) (char *, u32, char *, u32 *);
Modified: LinuxBIOSv3/util/lar/lib.c =================================================================== --- LinuxBIOSv3/util/lar/lib.c 2007-08-19 22:58:42 UTC (rev 469) +++ LinuxBIOSv3/util/lar/lib.c 2007-08-19 23:31:58 UTC (rev 470) @@ -29,6 +29,7 @@ #include <sys/stat.h> #include <sys/types.h>
+#include "lar.h" #include "lib.h"
#define MAX_PATH 1024 @@ -36,6 +37,46 @@ static struct file *files = NULL;
/** + * The default "compress impossible" hook to call when no other compression + * is used + */ +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); +} + +/** + * The default "compress" hook to call when no other compression is used + */ +void do_no_compress(char *in, u32 in_len, char *out, u32 *out_len) +{ + memcpy(out, in, in_len); + out_len[0] = in_len; +} + +/** + * The default "uncompress" hook to call when no other compression is used + */ + +void do_no_uncompress(char *dst, char *src, u32 len) +{ + memcpy(dst, src, len); +} + +/** + * The default "uncompress" hook to call when no other compression is used + */ +void uncompress_impossible(char *dst, char *src, u32 len) +{ + fprintf(stderr, + "Cannot uncompress data (algorithm not compiled in).\n"); + exit(1); +} + + +/** * Create a new directory including any missing parent directories. * * NOTE: This function does not do complete path resolution as described in @@ -114,6 +155,12 @@ return ret; }
+ +int mkdirp(const char *dirpath, mode_t mode) +{ + return mkdirp_below(".", dirpath, mode); +} + static int handle_directory(const char *name) { int n;
Modified: LinuxBIOSv3/util/lar/lib.h =================================================================== --- LinuxBIOSv3/util/lar/lib.h 2007-08-19 22:58:42 UTC (rev 469) +++ LinuxBIOSv3/util/lar/lib.h 2007-08-19 23:31:58 UTC (rev 470) @@ -49,6 +49,16 @@ struct file *get_files(void); void free_files(void);
+/* Prototypes for the LAR I/O functions */ +struct lar * lar_new_archive(const char *archive, unsigned int size); +struct lar * lar_open_archive(const char *archive); +void lar_close_archive(struct lar *lar); + +void lar_list_files(struct lar *lar, struct file *files); +int lar_add_file(struct lar *lar, const char *name); +int lar_add_bootblock(struct lar *lar, const char *bootblock); +int lar_extract_files(struct lar *lar, struct file *files); + /* prototypes for extract.c functions */ int extract_lar(const char *archivename, struct file *files);
Deleted: LinuxBIOSv3/util/lar/list.c =================================================================== --- LinuxBIOSv3/util/lar/list.c 2007-08-19 22:58:42 UTC (rev 469) +++ LinuxBIOSv3/util/lar/list.c 2007-08-19 23:31:58 UTC (rev 470) @@ -1,121 +0,0 @@ -/* - * lar - LinuxBIOS archiver - * - * 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 - * the Free Software Foundation; version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <netinet/in.h> - -#include "lib.h" -#include "lar.h" - -int list_lar(const char *archivename, struct file *files) -{ - int archivefile; - char *inmap; - char *walk; - char *fullname; - struct lar_header *header; - struct stat statbuf; - int archivelen; - int do_extract; - int i; - - if (stat(archivename, &statbuf) != 0) { - fprintf(stderr, "Error opening %s: %s\n", - archivename, strerror(errno)); - exit(1); - } - - if (verbose()) - printf("Opening %s\n", archivename); - - archivefile = open(archivename, O_RDONLY); - if (archivefile == -1) { - printf("Error while opening %s: %s\n", - archivename, strerror(errno)); - exit(1); - } - archivelen = statbuf.st_size; - - inmap = mmap(NULL, statbuf.st_size, PROT_READ, - MAP_SHARED, archivefile, 0); - - for (walk = inmap; walk < inmap + statbuf.st_size; walk += 16) { - if (strcmp(walk, MAGIC) != 0) - continue; - - header = (struct lar_header *)walk; - fullname = walk + sizeof(struct lar_header); - - do_extract = 1; - if (files) { - struct file *fwalk = files; - do_extract = 0; - while (fwalk) { - if (strcmp(fullname, fwalk->name) == 0) { - do_extract = 1; - break; - } - fwalk = fwalk->next; - } - } - - /* Don't extract this one, skip it. */ - if (!do_extract) { - continue; - } - - printf(" %s ", walk + sizeof(struct lar_header)); - - 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; - } - - munmap(inmap, statbuf.st_size); - close(archivefile); - - if (verbose()) - printf("done.\n"); - - return 0; -}