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 <stepan@coresystems.de> Acked-by: Uwe Hermann <uwe@hermann-uwe.de> git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@234 f3766cd6-281f-0410-b1cd-43a5c92072e9
This commit is contained in:
parent
6869f4a129
commit
88f2f6402a
12 changed files with 485 additions and 152 deletions
|
|
@ -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".
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ TODO
|
|||
Copyright and License
|
||||
---------------------
|
||||
|
||||
Copyright (C) 2006 coresystems GmbH
|
||||
Copyright (C) 2006-2007 coresystems GmbH
|
||||
Written by Stefan Reinauer <stepan@coresystems.de> for coresystems GmbH.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* lar - LinuxBIOS archiver
|
||||
*
|
||||
* Copyright (C) 2006 coresystems GmbH
|
||||
* Copyright (C) 2006-2007 coresystems GmbH
|
||||
* Written by Stefan Reinauer <stepan@coresystems.de> 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* lar - LinuxBIOS archiver
|
||||
*
|
||||
* Copyright (C) 2006 coresystems GmbH
|
||||
* Written by Stefan Reinauer <stepan@coresystems.de> 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
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* lar - LinuxBIOS archiver
|
||||
*
|
||||
* Copyright (C) 2006 coresystems GmbH
|
||||
* Copyright (C) 2006-2007 coresystems GmbH
|
||||
* Written by Stefan Reinauer <stepan@coresystems.de> 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;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* lar - LinuxBIOS archiver
|
||||
*
|
||||
* Copyright (C) 2006 coresystems GmbH
|
||||
* Copyright (C) 2006-2007 coresystems GmbH
|
||||
* Written by Stefan Reinauer <stepan@coresystems.de> 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* lar - LinuxBIOS archiver
|
||||
*
|
||||
* Copyright (C) 2006 coresystems GmbH
|
||||
* Written by Stefan Reinauer <stepan@coresystems.de> 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
|
||||
172
util/lar/lar.c
172
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 <stepan@coresystems.de> for coresystems GmbH.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
@ -24,33 +24,173 @@
|
|||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#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 <files>\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;
|
||||
}
|
||||
|
|
|
|||
173
util/lar/lib.c
173
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 <stepan@coresystems.de> for coresystems GmbH.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
|
@ -22,11 +22,16 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#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
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* lar - LinuxBIOS archiver
|
||||
*
|
||||
* Copyright (C) 2006 coresystems GmbH
|
||||
* Copyright (C) 2006-2007 coresystems GmbH
|
||||
* Written by Stefan Reinauer <stepan@coresystems.de> 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
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* lar - LinuxBIOS archiver
|
||||
*
|
||||
* Copyright (C) 2006 coresystems GmbH
|
||||
* Copyright (C) 2006-2007 coresystems GmbH
|
||||
* Written by Stefan Reinauer <stepan@coresystems.de> 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* lar - LinuxBIOS archiver
|
||||
*
|
||||
* Copyright (C) 2006 coresystems GmbH
|
||||
* Written by Stefan Reinauer <stepan@coresystems.de> 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue