From 92efb61fa7cfa2fb90bc545d8b47c291f2c45009 Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Tue, 7 Nov 2006 17:32:43 +0000 Subject: [PATCH] Add initial version of lar to the archive. Signed-off-by: Stefan Reinauer Acked-By: Stefan Reinauer and others. git-svn-id: svn://coreboot.org/repository/LinuxBIOSv3@39 f3766cd6-281f-0410-b1cd-43a5c92072e9 --- util/lar/Makefile | 45 ++++++++++++++++ util/lar/README | 87 +++++++++++++++++++++++++++++++ util/lar/create.c | 126 ++++++++++++++++++++++++++++++++++++++++++++ util/lar/create.h | 28 ++++++++++ util/lar/example.c | 124 +++++++++++++++++++++++++++++++++++++++++++ util/lar/extract.c | 127 +++++++++++++++++++++++++++++++++++++++++++++ util/lar/extract.h | 28 ++++++++++ util/lar/lar.c | 58 +++++++++++++++++++++ util/lar/lar.h | 39 ++++++++++++++ util/lar/lib.c | 75 ++++++++++++++++++++++++++ util/lar/lib.h | 28 ++++++++++ util/lar/list.c | 105 +++++++++++++++++++++++++++++++++++++ util/lar/list.h | 28 ++++++++++ 13 files changed, 898 insertions(+) create mode 100644 util/lar/Makefile create mode 100644 util/lar/README create mode 100644 util/lar/create.c create mode 100644 util/lar/create.h create mode 100644 util/lar/example.c create mode 100644 util/lar/extract.c create mode 100644 util/lar/extract.h create mode 100644 util/lar/lar.c create mode 100644 util/lar/lar.h create mode 100644 util/lar/lib.c create mode 100644 util/lar/lib.h create mode 100644 util/lar/list.c create mode 100644 util/lar/list.h diff --git a/util/lar/Makefile b/util/lar/Makefile new file mode 100644 index 0000000000..511d55103a --- /dev/null +++ b/util/lar/Makefile @@ -0,0 +1,45 @@ +# +# lar makefile. This file is GPL. All rights reserved. +# +# (c) 2006 coresystems GmbH +# + +SOURCE = lar.c create.c extract.c list.c lib.c + +CC=gcc +CFLAGS=-O2 -Wall -W + +lar: $(SOURCE) + $(CC) $(CFLAGS) -o $@ $^ + strip -s $@ + +example: example.c + $(CC) $(CFLAGS) -o $@ $^ + +clean: + rm -rf lar tree.lar tree tree2 example + + +tree: + @printf "creating sample tree... " + @rm -rf tree + @mkdir tree + @mkdir -p tree/compression + @mkdir -p tree/normal + @mkdir -p tree/fallback + @dd if=/dev/urandom of=tree/compression/lzma bs=1k count=8 &>/dev/null + @dd if=/dev/urandom of=tree/normal/linuxbios.elf.lzma bs=1k count=32 &>/dev/null + @dd if=/dev/urandom of=tree/normal/initmem bs=1k count=16 &>/dev/null + @dd if=/dev/urandom of=tree/fallback/linuxbios.elf.lzma bs=1k count=32 &>/dev/null + @dd if=/dev/urandom of=tree/fallback/initmem bs=1k count=16 &>/dev/null + @printf "done.\n" + +tree.lar: lar tree + cd tree; ../lar c ../tree.lar `find . -type f|cut -c3-` + +test: lar example tree.lar + mkdir tree2; cd tree2; ../lar x ../tree.lar + @echo Comparing tree: + diff -urN tree tree2 + @rm -rf tree tree2 + ./example tree.lar diff --git a/util/lar/README b/util/lar/README new file mode 100644 index 0000000000..c84f3165c1 --- /dev/null +++ b/util/lar/README @@ -0,0 +1,87 @@ +LinuxBIOS Archiver: lar +----------------------- + +TOC +- Introduction +- Usage +- Archive format +- TODO +- ChangeLog + +Introduction +------------ + +This is a simple archiver, similar to cpio, ar or tar. + +Design goals were + - minimum overhead + - maximum fault tolerance + - simplicity + +For a usage example see example.c + +For questions contact Stefan Reinauer + +Usage +----- + +Create archive archive.lar containting files file1 ... fileN + + $ lar c archive.lar file1 ... fileN + + +Extract files from archive.lar + + $ lar x archive.lar [file1 .. fileN] + +List files in archive: + + $ lar l archive.lar + + +Archive format +-------------- + +The rough format is: + + |--------------| + | header | + |--------------| + | data | + |--------------| + | header | + |--------------| + | data | + |--------------| + ... + +Headers have to be 16 byte aligned. + + |--------------------| + | magic (8byte) | + |--------------------| + | length (4byte) | + |--------------------| + | checksum (4byte) | + |--------------------| + | offset to blob (4b)| + |--------------------| + | "path name" | <-- null terminated, aligned to 16b + |--------------------| + | blob (aligned 16b) | + |--------------------| + + +TODO +---- + +* reading flash layouts +* This does not enforce any alignment yet +* Alignment enforcing will be optional. + + +ChangeLog + +2006/10/9 + - inital version + diff --git a/util/lar/create.c b/util/lar/create.c new file mode 100644 index 0000000000..fda0e69f41 --- /dev/null +++ b/util/lar/create.c @@ -0,0 +1,126 @@ +/* + * lar - linuxbios archiver + * + * written by Stefan Reinauer + * + * (C) 2006 coresystems GmbH. All rights reserved. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lib.h" +#include "lar.h" + +int create_lar(int argc, char *argv[]) +{ + int i, ret; + FILE *archive, *source; + char *archivename; + char *tempmem; + char *filebuf; + char *pathname; + u32 *walk; + u32 csum; + int pathlen, entrylen, filelen; + struct lar_header *header; + struct stat statbuf; + + archivename=argv[2]; + if (argc<=3) { + printf("No files for archive %s\n", archivename); + exit(1); + } + + printf("Opening %s\n", archivename); + archive=fopen(archivename, "w"); + if(!archive) { + // error + exit(1); + } + + for (i=3; ilen=htonl(statbuf.st_size); + header->offset=htonl(sizeof(struct lar_header)+pathlen); + + /* calculate checksum */ + csum=0; + for (walk=(u32 *)tempmem; + walk<(u32 *)(tempmem+ statbuf.st_size+sizeof(struct lar_header)+pathlen); + walk++) { + csum+=ntohl(*walk); + } + header->checksum=htonl(csum); + + /* write out entry to archive */ + entrylen=(filelen+pathlen+sizeof(struct lar_header)+15) & 0xfffffff0; + + fwrite(tempmem, entrylen, 1, archive); + + free(tempmem); + + } + + fclose(archive); + printf("done.\n"); + + return 0; +} + + diff --git a/util/lar/create.h b/util/lar/create.h new file mode 100644 index 0000000000..a97ae9e3e3 --- /dev/null +++ b/util/lar/create.h @@ -0,0 +1,28 @@ +/* + * lar - linuxbios archiver + * + * written by Stefan Reinauer + * + * (C) 2006 coresystems GmbH. All rights reserved. + * + * 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 1 + +int create_lar(int argc, char *argv[]); + +#endif diff --git a/util/lar/example.c b/util/lar/example.c new file mode 100644 index 0000000000..2aac02e05a --- /dev/null +++ b/util/lar/example.c @@ -0,0 +1,124 @@ +/* + * lar - linuxbios archiver + * + * written by Stefan Reinauer + * + * (C) 2006 coresystems GmbH. All rights reserved. + * + * 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 + * + * This file may be dual licensed with the new BSD license. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lar.h" + +struct mem_file { + char *start; + int len; +}; + +int find_file(struct mem_file *archive, char *filename, struct mem_file *result) +{ + char * walk, *fullname; + struct lar_header * header; + + for (walk = archive->start; walk < archive->start + + archive->len; walk+=16) { + + if(strcmp(walk, MAGIC)!=0) + continue; + + header=(struct lar_header *)walk; + fullname=walk+sizeof(struct lar_header); + + // FIXME: check checksum + + if(strcmp(fullname, filename)!=0) { + result->start=walk + ntohl(header->offset); + result->len=ntohl(header->len); + return 0; + } + + // skip file + walk += ( ntohl(header->offset) + ntohl(header->len) + + 15 ) & 0xfffffff0; + } + + return 1; +} + + + +int main(int argc, char *argv[]) +{ + int fd, ret; + struct stat statbuf; + struct mem_file archive, result; + + if (argc!=2) { + printf("Usage: example archive.lar\n"); + exit(0); + } + + if (stat(argv[1], &statbuf)!=0) { + printf("Error opening %s: %s\n", + argv[1], strerror(errno)); + exit(1); + } + printf("Opening %s\n", argv[1]); + + fd=open(argv[1], O_RDONLY); + if (fd==-1) { + printf("Error while opening %s: %s\n", + argv[1], strerror(errno)); + exit(1); + } + archive.len=statbuf.st_size; + + archive.start=mmap(NULL, statbuf.st_size, PROT_READ, + MAP_SHARED, fd, 0); + /* OS stuff ends here */ + /* ------------------------------------------------- */ + + // find first compressor + ret=find_file(&archive, "compression/", &result); + if(!ret) printf("file found.\n"); + else printf("file not found.\n"); + + ret=find_file(&archive, "normal/initram", &result); + if(!ret) printf("file found.\n"); + else printf("file not found.\n"); + + + /* ------------------------------------------------- */ + /* OS stuff starts again here */ + munmap(archive.start, archive.len); + close(fd); + + return 0; +} + + diff --git a/util/lar/extract.c b/util/lar/extract.c new file mode 100644 index 0000000000..1fb3404301 --- /dev/null +++ b/util/lar/extract.c @@ -0,0 +1,127 @@ +/* + * lar - linuxbios archiver + * + * written by Stefan Reinauer + * + * (C) 2006 coresystems GmbH. All rights reserved. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lib.h" +#include "lar.h" + +int extract_lar(int argc, char *argv[]) +{ + int archivefile; + char * archivename; + char * inmap; + char * walk; + char *fullname, *pathname, *pos; + struct lar_header * header; + struct stat statbuf; + int archivelen; + 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); + + 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; walk3) { + do_extract=0; + for (i=3; ioffset), + // ntohl(header->len)); + fwrite(walk+ntohl(header->offset), ntohl(header->len), + 1, file_to_extract); + fclose(file_to_extract); + } + munmap(inmap, statbuf.st_size); + close(archivefile); + printf("done.\n"); + + return 0; +} + + diff --git a/util/lar/extract.h b/util/lar/extract.h new file mode 100644 index 0000000000..c465f32eca --- /dev/null +++ b/util/lar/extract.h @@ -0,0 +1,28 @@ +/* + * lar - linuxbios archiver + * + * written by Stefan Reinauer + * + * (C) 2006 coresystems GmbH. All rights reserved. + * + * 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 1 + +int extract_lar(int argc, char *argv[]); + +#endif diff --git a/util/lar/lar.c b/util/lar/lar.c new file mode 100644 index 0000000000..4e61ad30b0 --- /dev/null +++ b/util/lar/lar.c @@ -0,0 +1,58 @@ +/* + * lar - linuxbios archiver + * + * written by Stefan Reinauer + * + * (C) 2006 coresystems GmbH. All rights reserved. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lib.h" +#include "lar.h" +#include "create.h" +#include "extract.h" +#include "list.h" + +int main(int argc, char *argv[]) +{ + if (argc<2) { + printf("Usage: lar [cxl] archive.lar \n"); + exit(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 or x\n"); + exit(1); + } + + return 0; +} diff --git a/util/lar/lar.h b/util/lar/lar.h new file mode 100644 index 0000000000..f2a847bcb7 --- /dev/null +++ b/util/lar/lar.h @@ -0,0 +1,39 @@ +/* + * lar - linuxbios archiver + * + * written by Stefan Reinauer + * + * (C) 2006 coresystems GmbH. All rights reserved. + * + * 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 + * + * This file may be dual licensed with the new BSD license. + * + */ + +#include + +#define MAGIC "LARCHIVE" +#define MAX_PATHLEN 1024 + +typedef uint32_t u32; + +struct lar_header { + char magic[8]; + u32 len; + u32 checksum; + u32 offset; +}; + + diff --git a/util/lar/lib.c b/util/lar/lib.c new file mode 100644 index 0000000000..3b928b4c08 --- /dev/null +++ b/util/lar/lib.c @@ -0,0 +1,75 @@ +/* + * lar - linuxbios archiver + * + * written by Stefan Reinauer + * + * (C) 2006 coresystems GmbH. All rights reserved. + * + * 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 +#include +#include +#include +#include +#include + +int mkdirp(char *dirpath) +{ +#define MAX_PATH 1024 + char *pos, *currpath, *path; + char cwd[MAX_PATH]; + int ret=0; + + path = strdup(dirpath); + currpath = path; + + if(!getcwd(cwd, MAX_PATH)) { + free(path); + printf("error getting cwd\n"); + return -1; + } + + do { + pos=index(currpath,'/'); + if (pos)*pos=0; + + //printf("cp=%s\n",currpath); + mkdir(currpath,0755); + ret=chdir(currpath); + + if(pos) currpath=pos+1; + } while (pos && !ret && strlen(currpath)) ; + + chdir(cwd); + free(path); + + return ret; +} + +#if 0 +int main(void) { + int ret; + ret=mkdirp("a/b/c/d/"); + if (ret) printf("error! mkdir\n\n"); + else printf("jippie! mkdir\n\n"); + ret=mkdirp("a/b/c/d"); + if (ret) printf("error! mkdir\n"); + else printf("jippie! mkdir\n"); + + return 0; +} +#endif diff --git a/util/lar/lib.h b/util/lar/lib.h new file mode 100644 index 0000000000..bc32ea0896 --- /dev/null +++ b/util/lar/lib.h @@ -0,0 +1,28 @@ +/* + * lar - linuxbios archiver + * + * written by Stefan Reinauer + * + * (C) 2006 coresystems GmbH. All rights reserved. + * + * 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_LIB_H +#define __LAR_LIB_H 1 + +int mkdirp(char *dirpath); + +#endif diff --git a/util/lar/list.c b/util/lar/list.c new file mode 100644 index 0000000000..97915cae7a --- /dev/null +++ b/util/lar/list.c @@ -0,0 +1,105 @@ +/* + * lar - linuxbios archiver + * + * written by Stefan Reinauer + * + * (C) 2006 coresystems GmbH. All rights reserved. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "lib.h" +#include "lar.h" + +int list_lar(int argc, char *argv[]) +{ + int archivefile; + char * archivename; + char * inmap; + char * walk; + char *fullname; + struct lar_header * header; + struct stat statbuf; + int archivelen; + 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); + + 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; walk3) { + do_extract=0; + for (i=3; ilen), + (walk-inmap)+ntohl(header->offset)); + } + munmap(inmap, statbuf.st_size); + close(archivefile); + printf("done.\n"); + + return 0; +} + + diff --git a/util/lar/list.h b/util/lar/list.h new file mode 100644 index 0000000000..3c86892416 --- /dev/null +++ b/util/lar/list.h @@ -0,0 +1,28 @@ +/* + * lar - linuxbios archiver + * + * written by Stefan Reinauer + * + * (C) 2006 coresystems GmbH. All rights reserved. + * + * 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 1 + +int list_lar(int argc, char *argv[]); + +#endif