From 88f2f6402a87c951190642766baf7ed9e9836067 Mon Sep 17 00:00:00 2001 From: Uwe Hermann Date: Sat, 10 Mar 2007 16:20:01 +0000 Subject: [PATCH] This is a major update to the lar archiver. It simplifies the build process and is a base change to make the whole linuxbios.rom a lar file. * fix a whole lot of lar bugs (that never showed up in production yet) * add proper option parsing to lar * add verbose option * add option to automatically pad lar archive to a certain size * add proper file handling (specifying a directory will now pack all files in that directory into the lar, instead of a 4k dummy file) * catch lots of user errors, less implicit assumptions * merge all header files into lib.h (except lar.h which is needed by other programs using the lar format). lib.h is still very small. * print errors to stderr * (slipped in) copy linuxbios.rom to bios.bin for qemu ;-) * adapt arch/x86/Makefile to use the new features. * set version to 0.9 * lots of security bugs fixed (thanks to Uwe!) * catch low memory conditions in strdup Signed-off-by: Stefan Reinauer Acked-by: Uwe Hermann git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@234 f3766cd6-281f-0410-b1cd-43a5c92072e9 --- arch/x86/Makefile | 10 ++- util/lar/README | 2 +- util/lar/create.c | 81 ++++++++++++++++----- util/lar/create.h | 26 ------- util/lar/example.c | 6 +- util/lar/extract.c | 42 +++++++---- util/lar/extract.h | 26 ------- util/lar/lar.c | 172 +++++++++++++++++++++++++++++++++++++++----- util/lar/lib.c | 173 ++++++++++++++++++++++++++++++++++++++++++++- util/lar/lib.h | 38 +++++++++- util/lar/list.c | 33 +++++---- util/lar/list.h | 26 ------- 12 files changed, 484 insertions(+), 151 deletions(-) delete mode 100644 util/lar/create.h delete mode 100644 util/lar/extract.h delete mode 100644 util/lar/list.h diff --git a/arch/x86/Makefile b/arch/x86/Makefile index c2e9e8213d..547596bb50 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile @@ -37,7 +37,9 @@ LINUXBIOS_COMPONENTS := linuxbios.lar linuxbios.vpd stage0.init $(obj)/linuxbios.rom: $(patsubst %,$(obj)/%,$(LINUXBIOS_COMPONENTS)) $(Q)cat $^ > $@ - + $(Q)# qemu wants bios.bin: + $(Q)# run "qemu -L build/ -nographic -hda /dev/zero" + $(Q)cp $@ $(obj)/bios.bin # # Build the LAR archive. @@ -58,11 +60,7 @@ $(obj)/linuxbios.lar: $(obj)/util/lar/lar lzma $(obj)/linuxbios.initram $(obj)/l $(Q)cp $(obj)/linuxbios.stage2 $(obj)/lar.tmp/normal/stage2 $(Q)cp $(CONFIG_PAYLOAD) $(obj)/lar.tmp/normal/payload $(Q)printf " " - $(Q)cd $(obj)/lar.tmp && ../util/lar/lar c ../linuxbios.lar.pre normal/initram normal/stage2 normal/payload - $(Q)# Padding the LAR archive to image size - 16k (bootblock size) - $(Q)dd if=$(obj)/linuxbios.lar.pre of=$(obj)/linuxbios.lar \ - bs=$(LAR_SIZE) count=1 conv=sync $(SILENT) - + $(Q)cd $(obj)/lar.tmp && ../util/lar/lar -cv ../linuxbios.lar . -s $(LAR_SIZE) # # LinuxBIOS stage0. This is the LinuxBIOS "boot block code". diff --git a/util/lar/README b/util/lar/README index abc83839b6..0e459e9f4f 100644 --- a/util/lar/README +++ b/util/lar/README @@ -84,7 +84,7 @@ TODO Copyright and License --------------------- -Copyright (C) 2006 coresystems GmbH +Copyright (C) 2006-2007 coresystems GmbH Written by Stefan Reinauer for coresystems GmbH. This program is free software; you can redistribute it and/or modify diff --git a/util/lar/create.c b/util/lar/create.c index ea408956a8..078b4374f6 100644 --- a/util/lar/create.c +++ b/util/lar/create.c @@ -1,7 +1,7 @@ /* * lar - LinuxBIOS archiver * - * Copyright (C) 2006 coresystems GmbH + * Copyright (C) 2006-2007 coresystems GmbH * Written by Stefan Reinauer for coresystems GmbH. * * This program is free software; you can redistribute it and/or modify @@ -32,60 +32,70 @@ #include "lib.h" #include "lar.h" -int create_lar(int argc, char *argv[]) +int create_lar(const char *archivename, struct file *files) { int i, ret; + int diff = 0; FILE *archive, *source; - char *archivename; char *tempmem; char *filebuf; char *pathname; u32 *walk; u32 csum; int pathlen, entrylen, filelen; + long currentsize = 0; struct lar_header *header; struct stat statbuf; - archivename = argv[2]; - if (argc <= 3) { - printf("No files for archive %s\n", archivename); + if (!files) { + fprintf(stderr, "No files for archive %s\n", archivename); exit(1); } - printf("Opening %s\n", archivename); + if(verbose()) + printf("Opening %s\n", archivename); + archive = fopen(archivename, "w"); if (!archive) { - /* Error. */ + fprintf(stderr, "Could not open archive %s for writing\n", + archivename); exit(1); } - for (i = 3; i < argc; i++) { - printf(" Adding %s to archive\n", argv[i]); + while (files) { + char *name=files->name; - ret = stat(argv[i], &statbuf); + /* 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) { - printf("No such file %s\n", argv[i]); + 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) { - printf("No memory\n"); + 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 = sprintf(pathname, argv[i]) + 1; + pathlen = snprintf(pathname, MAX_PATHLEN-1, name) + 1; pathlen = (pathlen + 15) & 0xfffffff0; /* Align it to 16 bytes. */ /* Read file into memory. */ filebuf = pathname + pathlen; - source = fopen(argv[i], "r"); + source = fopen(name, "r"); if (!source) { - printf("No such file %s\n", argv[i]); + fprintf(stderr, "No such file %s\n", name); exit(1); } fread(filebuf, statbuf.st_size, 1, source); @@ -111,10 +121,47 @@ int create_lar(int argc, char *argv[]) fwrite(tempmem, entrylen, 1, archive); free(tempmem); + + /* size counter */ + currentsize += entrylen; + + files = files->next; + } + + /* Calculate difference, if a size has been specified. + * Otherwise diff stays 0 and no action is taken below. + */ + if (get_larsize()) + diff = get_larsize() - currentsize; + + 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; + } + + 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); } fclose(archive); - printf("done.\n"); + + if(verbose()) + printf("done.\n"); return 0; } diff --git a/util/lar/create.h b/util/lar/create.h deleted file mode 100644 index 962f293ff2..0000000000 --- a/util/lar/create.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * lar - LinuxBIOS archiver - * - * Copyright (C) 2006 coresystems GmbH - * Written by Stefan Reinauer for coresystems GmbH. - * - * 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 - */ - -#ifndef __LAR_CREATE_H -#define __LAR_CREATE_H - -int create_lar(int argc, char *argv[]); - -#endif diff --git a/util/lar/example.c b/util/lar/example.c index 14ddd86057..a63bb19032 100644 --- a/util/lar/example.c +++ b/util/lar/example.c @@ -1,7 +1,7 @@ /* * lar - LinuxBIOS archiver * - * Copyright (C) 2006 coresystems GmbH + * Copyright (C) 2006-2007 coresystems GmbH * Written by Stefan Reinauer for coresystems GmbH. * * This file is dual-licensed. You can choose between: @@ -88,8 +88,8 @@ int find_file(struct mem_file *archive, char *filename, struct mem_file *result) } /* Skip file. */ - walk += (ntohl(header->offset) + ntohl(header->len) - + 15) & 0xfffffff0; + walk += (ntohl(header->len) + ntohl(header->offset) - + 1) & 0xfffffff0; } return 1; diff --git a/util/lar/extract.c b/util/lar/extract.c index 1eebfbe993..16734bc1f8 100644 --- a/util/lar/extract.c +++ b/util/lar/extract.c @@ -1,7 +1,7 @@ /* * lar - LinuxBIOS archiver * - * Copyright (C) 2006 coresystems GmbH + * Copyright (C) 2006-2007 coresystems GmbH * Written by Stefan Reinauer for coresystems GmbH. * * This program is free software; you can redistribute it and/or modify @@ -32,10 +32,9 @@ #include "lib.h" #include "lar.h" -int extract_lar(int argc, char *argv[]) +int extract_lar(const char *archivename, struct file *files) { int archivefile; - char *archivename; char *inmap; char *walk; char *fullname, *pathname, *pos; @@ -45,13 +44,13 @@ int extract_lar(int argc, char *argv[]) int do_extract; int i; - archivename = argv[2]; - if (stat(archivename, &statbuf) != 0) { printf("Error opening %s: %s\n", archivename, strerror(errno)); exit(1); } - printf("Opening %s\n", archivename); + + if(verbose()) + printf("Opening %s\n", archivename); archivefile = open(archivename, O_RDONLY); if (archivefile == -1) { @@ -76,13 +75,15 @@ int extract_lar(int argc, char *argv[]) /* FIXME: check checksum. */ do_extract = 1; - if (argc > 3) { + if (files) { + struct file *fwalk=files; do_extract = 0; - for (i = 3; i < argc; i++) { - if (strcmp(fullname, argv[i]) == 0) { + while (fwalk) { + if (strcmp(fullname, fwalk->name) == 0) { do_extract = 1; break; } + fwalk=fwalk->next; } } @@ -90,11 +91,17 @@ int extract_lar(int argc, char *argv[]) if (!do_extract) continue; - printf(" Extracting file %s\n", - walk + sizeof(struct lar_header)); + 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; @@ -105,19 +112,24 @@ int extract_lar(int argc, char *argv[]) file_to_extract = fopen(fullname, "w"); if (!file_to_extract) { - printf("error creating file.\n"); + fprintf(stderr, "error creating file %s.\n", fullname); exit(1); } - /* printf("Starting offs=%d, len=%d\n", ntohl(header->offset), - ntohl(header->len)); */ + fwrite(walk + ntohl(header->offset), ntohl(header->len), 1, file_to_extract); fclose(file_to_extract); + + walk += (ntohl(header->offset) + ntohl(header->len) + -1 ) & 0xfffffff0; } munmap(inmap, statbuf.st_size); close(archivefile); - printf("done.\n"); + + + if(verbose()) + printf("done.\n"); return 0; } diff --git a/util/lar/extract.h b/util/lar/extract.h deleted file mode 100644 index 98c32630de..0000000000 --- a/util/lar/extract.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * lar - LinuxBIOS archiver - * - * Copyright (C) 2006 coresystems GmbH - * Written by Stefan Reinauer for coresystems GmbH. - * - * 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 - */ - -#ifndef __LAR_EXTRACT_H -#define __LAR_EXTRACT_H - -int extract_lar(int argc, char *argv[]); - -#endif diff --git a/util/lar/lar.c b/util/lar/lar.c index ce476d16ff..349f549727 100644 --- a/util/lar/lar.c +++ b/util/lar/lar.c @@ -1,7 +1,7 @@ /* * lar - LinuxBIOS archiver * - * Copyright (C) 2006 coresystems GmbH + * Copyright (C) 2006-2007 coresystems GmbH * Written by Stefan Reinauer for coresystems GmbH. * * This program is free software; you can redistribute it and/or modify @@ -24,33 +24,173 @@ #include #include #include +#include + #include #include #include #include "lib.h" #include "lar.h" -#include "create.h" -#include "extract.h" -#include "list.h" + +#define VERSION "v0.9" +#define COPYRIGHT "Copyright (C) 2006-2007 coresystems GmbH" + +static int isverbose = 0; +static long larsize = 0; +static char * bootblock = NULL; + + +static void usage(char *name) +{ + printf ("\nLAR - the LinuxBIOS Archiver " VERSION "\n" COPYRIGHT "\n\n" + "Usage: %s [-cxl] archive.lar [[[file1] file2] ...]\n\n", name); +} + +int verbose(void) +{ + return isverbose; +} + +long get_larsize(void) +{ + return larsize; +} + +char *get_bootblock(void) +{ + return bootblock; +} + int main(int argc, char *argv[]) { - if (argc < 2) { - printf("Usage: lar [cxl] archive.lar \n"); - exit(0); - } + int opt; + int option_index = 0; - if (strcmp(argv[1], "x") == 0) - extract_lar(argc, argv); - else if (strcmp(argv[1], "c") == 0) - create_lar(argc, argv); - else if (strcmp(argv[1], "l") == 0) - list_lar(argc, argv); - else { - printf("Mode must be c, x, or l.\n"); + int larmode = NONE; + + char * archivename = NULL; + + static struct option long_options[]= { + { "create", 0, 0, 'c' }, + { "extract", 0, 0, 'x' }, + { "list", 0, 0, 'l' }, + { "size", 1, 0, 's' }, + { "bootblock", 1, 0, 'b' }, + { "verbose", 0, 0, 'v' }, + { "version", 0, 0, 'V' }, + { "help", 0, 0, 'h' }, + { 0, 0, 0, 0 } + }; + + if (argc < 3) { + usage(argv[0]); exit(1); } + while ((opt = getopt_long(argc, argv, "cxls:b:vVh?", + long_options, &option_index)) != EOF) { + switch(opt) { + case 'c': + larmode = CREATE; + break; + case 'l': + larmode = LIST; + break; + case 'x': + larmode = EXTRACT; + break; + case 's': + larsize = strtol(optarg, (char **)NULL, 10); + break; + case 'b': + printf("Bootblock handling not yet supported. Ignoring\n"); + bootblock = strdup(optarg); + if (!bootblock) { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + break; + case 'v': + isverbose = 1; + break; + case 'V': + printf ("LAR - the LinuxBIOS Archiver " VERSION "\n"); + break; + default: + usage(argv[0]); + exit(1); + } + } + + // tar compatibility: Allow lar x as alternative to + // lar -x. This should be dropped or done correctly. + // Right now, you'd have to write lar x -v instead of + // lar xv... but the author of this software was too + // lazy to handle all option parameter twice. + if (larmode == NONE) + { + if (strncmp(argv[optind], "x", 2) == 0) + larmode=EXTRACT; + else if (strncmp(argv[optind], "c", 2) == 0) + larmode=CREATE; + else if (strncmp(argv[optind], "l", 2) == 0) + larmode=LIST; + + /* If larmode changed in this if branch, + * eat a parameter + */ + if (larmode != NONE) + optind++; + } + + if (larmode == NONE) + { + usage(argv[0]); + printf("Error: No mode specified.\n\n"); + exit(1); + } + + /* size only makes sense when creating a lar */ + if (larmode != CREATE && larsize) { + printf("Warning: size parameter ignored since " + "not creating an archive.\n"); + } + + if (optind < argc) { + archivename=argv[optind++]; + } else { + + usage(argv[0]); + printf("Error: No archive name.\n\n"); + exit(1); + } + + /* when a new archive is created, recurse over + * physical files when a directory is found. + * Otherwise just add the directory to the match list + */ + + while (optind < argc) { + if (larmode == CREATE) { + add_files(argv[optind++]); + } else + add_file_or_directory(argv[optind++]); + } + + switch (larmode) { + case EXTRACT: + extract_lar(archivename, get_files()); + break; + case CREATE: + create_lar(archivename, get_files()); + break; + case LIST: + list_lar(archivename, get_files()); + break; + } + + free_files(); return 0; } diff --git a/util/lar/lib.c b/util/lar/lib.c index e7318a5f5b..ba9ecbeaea 100644 --- a/util/lar/lib.c +++ b/util/lar/lib.c @@ -1,7 +1,7 @@ /* * lar - LinuxBIOS archiver * - * Copyright (C) 2006 coresystems GmbH + * Copyright (C) 2006-2007 coresystems GmbH * Written by Stefan Reinauer for coresystems GmbH. * * This program is free software; you can redistribute it and/or modify @@ -22,11 +22,16 @@ #include #include #include +#include #include #include +#include "lib.h" + #define MAX_PATH 1024 +static struct file * files = NULL; + int mkdirp(const char *dirpath) { char *pos, *currpath, *path; @@ -34,11 +39,16 @@ int mkdirp(const char *dirpath) int ret = 0; path = strdup(dirpath); + if (!path) { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + currpath = path; if (!getcwd(cwd, MAX_PATH)) { free(path); - printf("Error getting cwd.\n"); + fprintf(stderr, "Error getting cwd.\n"); return -1; } @@ -60,3 +70,162 @@ int mkdirp(const char *dirpath) return ret; } + +static int handle_directory(const char *name) +{ + int ret=-1, n; + struct dirent **namelist; + + n = scandir(name, &namelist, 0, alphasort); + + if(n < 0) { + fprintf(stderr, "Could not enter directory %s\n", name); + } else { + while (n--) { + char fullname[MAX_PATH]; + + fullname[0] = '\0'; + + if (strncmp("..", namelist[n]->d_name, 3) && + strncmp(".", namelist[n]->d_name, 2)) { + + strncpy(fullname, name, MAX_PATH); + + if(name[(strlen(name))-1] != '/') { + strncat(fullname, "/", MAX_PATH); + } + + strncat(fullname, namelist[n]->d_name, MAX_PATH); + + add_files(fullname); + } + free(namelist[n]); + + } + free(namelist); + ret=0; + } + + return ret; +} + +/* + * Add physically existing files to the file list. + * This function is used when an archive is created. + */ + +int add_files(const char *name) +{ + struct stat filestat; + int ret = -1; + + /* printf("... add_files %s\n", name); */ + if (stat(name, &filestat) == -1) { + fprintf(stderr, "Error getting file attributes of %s\n", name); + return -1; + } + + if (S_ISCHR(filestat.st_mode) || S_ISBLK(filestat.st_mode)) { + fprintf(stderr, "Device files are not supported: %s\n", name); + } + + if (S_ISFIFO(filestat.st_mode)) { + fprintf(stderr, "FIFOs are not supported: %s\n", name); + } + + if (S_ISSOCK(filestat.st_mode)) { + fprintf(stderr, "Sockets are not supported: %s\n", name); + } + + if (S_ISLNK(filestat.st_mode)) { + fprintf(stderr, "Symbolic links are not supported: %s\n", name); + } + + // Is it a directory? + if (S_ISDIR(filestat.st_mode)) { + ret=handle_directory(name); + } + + // Is it a regular file? + if (S_ISREG(filestat.st_mode)) { + struct file *tmpfile; + + /* printf("... adding %s\n", name); */ + tmpfile = malloc(sizeof(struct file)); + if (!tmpfile) { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + + tmpfile->name = strdup(name); + if(!tmpfile->name) { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + + tmpfile->next = files; + files = tmpfile; + ret = 0; + } + + return ret; +} + +/* + * Add files or directories as specified to the file list. + * This function is used when an archive is listed or extracted. + */ + +int add_file_or_directory(const char *name) +{ + struct file *tmpfile; + + tmpfile = malloc(sizeof(struct file)); + if (!tmpfile) { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + + tmpfile->name = strdup(name); + if (!tmpfile->name) { + fprintf(stderr, "Out of memory.\n"); + exit(1); + } + + tmpfile->next = files; + files=tmpfile; + + return 0; +} + +struct file *get_files(void) +{ + return files; +} + +void free_files(void) +{ + struct file * temp; + + while (files) { + temp=files; + files=files->next; + free(temp->name); + free(temp); + } +} + +#ifdef DEBUG +int list_files(void) +{ + struct file * walk = files; + + printf ("File list:\n"); + while (walk) { + printf("- %s\n", walk->name); + walk=walk->next; + } + printf ("-----\n"); + return 0; +} +#endif diff --git a/util/lar/lib.h b/util/lar/lib.h index fdd8c3c6cf..4a8bcc4b5f 100644 --- a/util/lar/lib.h +++ b/util/lar/lib.h @@ -1,7 +1,7 @@ /* * lar - LinuxBIOS archiver * - * Copyright (C) 2006 coresystems GmbH + * Copyright (C) 2006-2007 coresystems GmbH * Written by Stefan Reinauer for coresystems GmbH. * * This program is free software; you can redistribute it and/or modify @@ -21,6 +21,42 @@ #ifndef __LAR_LIB_H #define __LAR_LIB_H +/* data types */ + +struct file { + char * name; + struct file *next; +}; + +enum { + NONE, + CREATE, + LIST, + EXTRACT +} larmodes; + +/* prototypes for lar.c functions */ +int verbose(void); +long get_larsize(void); +char *get_bootblock(void); + + +/* prototypes for lib.c functions */ int mkdirp(const char *dirpath); +int add_files(const char *name); +int add_file_or_directory(const char *name); + +struct file *get_files(void); +void free_files(void); + +/* prototypes for extract.c functions */ +int extract_lar(const char *archivename, struct file *files); + +/* prototypes for list.c functions */ +int list_lar(const char *archivename, struct file *files); + +/* prototypes for create.c functions */ +int create_lar(const char *archivename, struct file *files); + #endif diff --git a/util/lar/list.c b/util/lar/list.c index ea9b2eb207..d477cf9303 100644 --- a/util/lar/list.c +++ b/util/lar/list.c @@ -1,7 +1,7 @@ /* * lar - LinuxBIOS archiver * - * Copyright (C) 2006 coresystems GmbH + * Copyright (C) 2006-2007 coresystems GmbH * Written by Stefan Reinauer for coresystems GmbH. * * This program is free software; you can redistribute it and/or modify @@ -32,10 +32,9 @@ #include "lib.h" #include "lar.h" -int list_lar(int argc, char *argv[]) +int list_lar(const char *archivename, struct file *files) { int archivefile; - char *archivename; char *inmap; char *walk; char *fullname; @@ -45,13 +44,14 @@ int list_lar(int argc, char *argv[]) int do_extract; int i; - archivename = argv[2]; - if (stat(archivename, &statbuf) != 0) { - printf("Error opening %s: %s\n", archivename, strerror(errno)); + fprintf(stderr, "Error opening %s: %s\n", + archivename, strerror(errno)); exit(1); } - printf("Opening %s\n", archivename); + + if(verbose()) + printf("Opening %s\n", archivename); archivefile = open(archivename, O_RDONLY); if (archivefile == -1) { @@ -72,29 +72,38 @@ int list_lar(int argc, char *argv[]) fullname = walk + sizeof(struct lar_header); do_extract = 1; - if (argc > 3) { + if (files) { + struct file *fwalk=files; do_extract = 0; - for (i = 3; i < argc; i++) { - if (strcmp(fullname, argv[i]) == 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) + if (!do_extract) { continue; + } printf(" %s ", walk + sizeof(struct lar_header)); printf("(%d bytes @0x%lx)\n", 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); - printf("done.\n"); + + if(verbose()) + printf("done.\n"); return 0; } diff --git a/util/lar/list.h b/util/lar/list.h deleted file mode 100644 index c62b1a0261..0000000000 --- a/util/lar/list.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * lar - LinuxBIOS archiver - * - * Copyright (C) 2006 coresystems GmbH - * Written by Stefan Reinauer for coresystems GmbH. - * - * 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 - */ - -#ifndef __LAR_LIST_H -#define __LAR_LIST_H - -int list_lar(int argc, char *argv[]); - -#endif