libpayload: retire LAR support
Who knows it still? Change-Id: If6e36569cd9a1ba3da8b3fe84264cd2a6dfd634b Signed-off-by: Patrick Georgi <patrick@georgi-clan.de> Reviewed-on: http://review.coreboot.org/10443 Tested-by: build bot (Jenkins) Reviewed-by: Edward O'Callaghan <edward.ocallaghan@koparo.com>
This commit is contained in:
parent
52648623e0
commit
cacf7234af
|
@ -48,13 +48,6 @@ config EXPERIMENTAL
|
||||||
Prompt for experimental functionality. Attention: This is not likely
|
Prompt for experimental functionality. Attention: This is not likely
|
||||||
to work without problems
|
to work without problems
|
||||||
|
|
||||||
config OBSOLETE
|
|
||||||
bool "Obsolete Options"
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
Prompt for obsolete options. These options are for old, unsupported
|
|
||||||
features and are likely to go away in the future.
|
|
||||||
|
|
||||||
config DEVELOPER
|
config DEVELOPER
|
||||||
bool "Developer Options"
|
bool "Developer Options"
|
||||||
default n
|
default n
|
||||||
|
@ -149,13 +142,6 @@ config PDCURSES
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
config LAR
|
|
||||||
bool "LAR support"
|
|
||||||
default n
|
|
||||||
depends on OBSOLETE
|
|
||||||
help
|
|
||||||
LAR is the archive format of (obsolete) coreboot v3
|
|
||||||
|
|
||||||
config CBFS
|
config CBFS
|
||||||
bool "CBFS support"
|
bool "CBFS support"
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -1,94 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of the coreboot project.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2006 coresystems GmbH
|
|
||||||
* (Written by Stefan Reinauer <stepan@coresystems.de> for coresystems GmbH)
|
|
||||||
*
|
|
||||||
* This file is dual-licensed. You can choose between:
|
|
||||||
* - The GNU GPL, version 2, as published by the Free Software Foundation
|
|
||||||
* - The revised BSD license (without advertising clause)
|
|
||||||
*
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
* 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.
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
* ---------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef LAR_H
|
|
||||||
#define LAR_H
|
|
||||||
|
|
||||||
#include <arch/types.h>
|
|
||||||
|
|
||||||
#define LAR_MAGIC "LARCHIVE"
|
|
||||||
#define LAR_MAX_PATHLEN 1024
|
|
||||||
|
|
||||||
struct lar_header {
|
|
||||||
char magic[8];
|
|
||||||
u32 len;
|
|
||||||
u32 reallen;
|
|
||||||
u32 checksum;
|
|
||||||
u32 compchecksum;
|
|
||||||
u32 offset;
|
|
||||||
/* Compression:
|
|
||||||
* 0 = no compression
|
|
||||||
* 1 = lzma
|
|
||||||
* 2 = nrv2b
|
|
||||||
* 3 = zeroes
|
|
||||||
*/
|
|
||||||
u32 compression;
|
|
||||||
u64 entry;
|
|
||||||
u64 loadaddress;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum compalgo {
|
|
||||||
ALGO_NONE = 0,
|
|
||||||
ALGO_LZMA = 1,
|
|
||||||
ALGO_NRV2B = 2,
|
|
||||||
ALGO_ZEROES = 3,
|
|
||||||
/* invalid should always be the last entry. */
|
|
||||||
ALGO_INVALID
|
|
||||||
};
|
|
||||||
|
|
||||||
struct mem_file {
|
|
||||||
void *start;
|
|
||||||
int len;
|
|
||||||
u32 reallen;
|
|
||||||
u32 compression;
|
|
||||||
void *entry;
|
|
||||||
void *loadaddress;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* LAR_H */
|
|
|
@ -58,9 +58,6 @@
|
||||||
#include <arch/virtual.h>
|
#include <arch/virtual.h>
|
||||||
#include <sysinfo.h>
|
#include <sysinfo.h>
|
||||||
#include <pci.h>
|
#include <pci.h>
|
||||||
#ifdef CONFIG_LP_LAR
|
|
||||||
#include <lar.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||||
|
@ -354,63 +351,6 @@ struct timeval {
|
||||||
int gettimeofday(struct timeval *tv, void *tz);
|
int gettimeofday(struct timeval *tv, void *tz);
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifdef CONFIG_LP_LAR
|
|
||||||
/**
|
|
||||||
* @defgroup lar LAR functions
|
|
||||||
* @{
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** LAR file header */
|
|
||||||
struct LAR {
|
|
||||||
void *start; /**< Location of the LAR in memory */
|
|
||||||
int cindex; /**< Next file to return in readlar() */
|
|
||||||
int count; /**< Number of entries in the header cache */
|
|
||||||
int alloc; /**< Number of slots in the header cache */
|
|
||||||
int eof; /**< Last entry in the header cache */
|
|
||||||
void **headers; /**< Pointer to the header cache */
|
|
||||||
};
|
|
||||||
|
|
||||||
/** A structure representing the next LAR entry */
|
|
||||||
struct larent {
|
|
||||||
u8 name[LAR_MAX_PATHLEN]; /**< The name of the next LAR entry */
|
|
||||||
};
|
|
||||||
|
|
||||||
/** A structure containing information about a LAR file */
|
|
||||||
struct larstat {
|
|
||||||
u32 len; /**< Length of the file in the LAR */
|
|
||||||
u32 reallen; /**< Length of the uncompressed file */
|
|
||||||
u32 checksum; /**< Checksum of the uncompressed file */
|
|
||||||
u32 compchecksum; /**< Checksum of the compressed file in the LAR */
|
|
||||||
u32 offset; /**< Offset of the file in the LAR */
|
|
||||||
u32 compression; /**< Compression type of the file */
|
|
||||||
u64 entry; /**< Entry point of the file for executables */
|
|
||||||
u64 loadaddress; /**< Address in memory to put the uncompressed file */
|
|
||||||
};
|
|
||||||
|
|
||||||
/** A structure representing a LAR file */
|
|
||||||
struct LFILE {
|
|
||||||
struct LAR *lar; /**< Pointer to the LAR struct */
|
|
||||||
struct lar_header *header; /**< Pointer to the header struct */
|
|
||||||
u32 size; /**< Size of the file */
|
|
||||||
void *start; /**< Start of the file in memory */
|
|
||||||
u32 offset; /**< Offset of the file in the LAR */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct LAR *openlar(void *addr);
|
|
||||||
int closelar(struct LAR *lar);
|
|
||||||
struct larent *readlar(struct LAR *lar);
|
|
||||||
void rewindlar(struct LAR *lar);
|
|
||||||
int larstat(struct LAR *lar, const char *path, struct larstat *buf);
|
|
||||||
void *larfptr(struct LAR *lar, const char *filename);
|
|
||||||
int lfverify(struct LAR *lar, const char *filename);
|
|
||||||
struct LFILE *lfopen(struct LAR *lar, const char *filename);
|
|
||||||
int lfread(void *ptr, size_t size, size_t nmemb, struct LFILE *stream);
|
|
||||||
|
|
||||||
int lfseek(struct LFILE *stream, long offset, int whence);
|
|
||||||
int lfclose(struct LFILE *file);
|
|
||||||
/** @} */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup info System information functions
|
* @defgroup info System information functions
|
||||||
* This module contains functions that return information about the system
|
* This module contains functions that return information about the system
|
||||||
|
|
|
@ -39,9 +39,6 @@ libc-$(CONFIG_LP_LIBC) += hexdump.c
|
||||||
libc-$(CONFIG_LP_LIBC) += die.c
|
libc-$(CONFIG_LP_LIBC) += die.c
|
||||||
libc-$(CONFIG_LP_LIBC) += coreboot.c
|
libc-$(CONFIG_LP_LIBC) += coreboot.c
|
||||||
|
|
||||||
# should be moved to coreboot directory
|
|
||||||
libc-$(CONFIG_LP_LAR) += lar.c
|
|
||||||
|
|
||||||
ifeq ($(CONFIG_LP_ARCH_MIPS),y)
|
ifeq ($(CONFIG_LP_ARCH_MIPS),y)
|
||||||
libc-$(CONFIG_LP_LIBC) += 64bit_div.c
|
libc-$(CONFIG_LP_LIBC) += 64bit_div.c
|
||||||
endif
|
endif
|
||||||
|
|
|
@ -1,350 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of the libpayload project.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2008 Advanced Micro Devices, Inc.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
||||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
||||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
||||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
||||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
||||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
||||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
||||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
||||||
* SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <endian.h>
|
|
||||||
#include <libpayload.h>
|
|
||||||
|
|
||||||
#define ROM_RESET_VECTOR 0xFFFFFFF0
|
|
||||||
|
|
||||||
static void * next_header(void * cur)
|
|
||||||
{
|
|
||||||
struct lar_header *header = (struct lar_header *) cur;
|
|
||||||
int offset = ((ntohl(header->offset) + ntohl(header->len)) + 15) &
|
|
||||||
0xFFFFFFF0;
|
|
||||||
|
|
||||||
return (void *) (cur + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct lar_header *lar_get_header(struct LAR *lar, int index)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (index < lar->count)
|
|
||||||
return (struct lar_header *) lar->headers[index];
|
|
||||||
|
|
||||||
if (lar->eof && index >= lar->eof)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for(i = lar->count; i <= index; i++) {
|
|
||||||
void *next = (i == 0) ?
|
|
||||||
lar->start : next_header(lar->headers[i - 1]);
|
|
||||||
|
|
||||||
if (strncmp((const char *) next, LAR_MAGIC, 8)) {
|
|
||||||
lar->eof = lar->count;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lar->count == lar->alloc) {
|
|
||||||
void *tmp = realloc(lar->headers,
|
|
||||||
(lar->alloc + 16) * sizeof(void *));
|
|
||||||
|
|
||||||
if (tmp == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
lar->headers = tmp;
|
|
||||||
lar->alloc += 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
lar->headers[lar->count++] = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (struct lar_header *) lar->headers[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open a LAR stream
|
|
||||||
*
|
|
||||||
* @param addr The address in memory where the LAR is located.
|
|
||||||
* Use NULL to specify the boot LAR
|
|
||||||
* @return a pointer to the LAR stream
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct LAR *openlar(void *addr)
|
|
||||||
{
|
|
||||||
struct LAR *lar;
|
|
||||||
|
|
||||||
/* If the address is null, then figure out the start of the
|
|
||||||
boot LAR */
|
|
||||||
|
|
||||||
if (addr == NULL) {
|
|
||||||
u32 size = *((u32 *) (ROM_RESET_VECTOR + 4));
|
|
||||||
addr = (void *) ((ROM_RESET_VECTOR + 16) - size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check the magic to make sure this is a LAR */
|
|
||||||
if (strncmp((const char *) addr, LAR_MAGIC, strlen(LAR_MAGIC)))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
lar = calloc(sizeof(struct LAR), 1);
|
|
||||||
|
|
||||||
if (!lar)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
lar->start = addr;
|
|
||||||
|
|
||||||
/* Preallocate 16 slots in the cache - this saves wear and
|
|
||||||
* tear on the heap */
|
|
||||||
|
|
||||||
lar->headers = malloc(16 * sizeof(void *));
|
|
||||||
|
|
||||||
if (!lar->headers)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
lar->alloc = 16;
|
|
||||||
lar->count = lar->eof = 0;
|
|
||||||
lar->cindex = 0;
|
|
||||||
|
|
||||||
return lar;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Close a LAR stream
|
|
||||||
*
|
|
||||||
* @param lar A pointer to the LAR stream
|
|
||||||
* @return Return 0 on success, -1 on error
|
|
||||||
*/
|
|
||||||
|
|
||||||
int closelar(struct LAR *lar)
|
|
||||||
{
|
|
||||||
if (!lar)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (lar->headers)
|
|
||||||
free(lar->headers);
|
|
||||||
|
|
||||||
free(lar);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read an entry from the LAR
|
|
||||||
*
|
|
||||||
* @param lar A pointer to the LAR stream
|
|
||||||
* @return A pointer to a larent structure
|
|
||||||
representing the next file in the LAR
|
|
||||||
*/
|
|
||||||
|
|
||||||
struct larent *readlar(struct LAR *lar)
|
|
||||||
{
|
|
||||||
static struct larent _larent;
|
|
||||||
struct lar_header *header;
|
|
||||||
int nlen;
|
|
||||||
|
|
||||||
if (!lar)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
header = lar_get_header(lar, lar->cindex);
|
|
||||||
|
|
||||||
if (header == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
nlen = ntohl(header->offset) - sizeof(*header);
|
|
||||||
|
|
||||||
if (nlen > LAR_MAX_PATHLEN - 1)
|
|
||||||
nlen = LAR_MAX_PATHLEN - 1;
|
|
||||||
|
|
||||||
memcpy((void *) _larent.name, ((char *) header + sizeof(*header)),
|
|
||||||
nlen);
|
|
||||||
|
|
||||||
_larent.name[nlen] = 0;
|
|
||||||
|
|
||||||
lar->cindex++;
|
|
||||||
|
|
||||||
return (struct larent *) &_larent;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rewindlar(struct LAR *lar)
|
|
||||||
{
|
|
||||||
if (lar != NULL)
|
|
||||||
lar->cindex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct lar_header *get_header_by_name(struct LAR *lar, const char *name)
|
|
||||||
{
|
|
||||||
struct lar_header *header;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i = 0; ; i++) {
|
|
||||||
header = lar_get_header(lar, i);
|
|
||||||
|
|
||||||
if (header == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
if (!strcmp(name, ((char *) header + sizeof(*header))))
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int larstat(struct LAR *lar, const char *path, struct larstat *buf)
|
|
||||||
{
|
|
||||||
struct lar_header *header = get_header_by_name(lar, path);
|
|
||||||
|
|
||||||
if (header == NULL || buf == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
buf->len = ntohl(header->len);
|
|
||||||
buf->reallen = ntohl(header->reallen);
|
|
||||||
buf->checksum = ntohl(header->checksum);
|
|
||||||
buf->compchecksum = ntohl(header->compchecksum);
|
|
||||||
buf->compression = ntohl(header->compression);
|
|
||||||
buf->entry = ntohll(header->entry);
|
|
||||||
buf->loadaddress = ntohll(header->loadaddress);
|
|
||||||
buf->offset = ((u32) header - (u32) lar->start) + ntohl(header->offset);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void * larfptr(struct LAR *lar, const char *filename)
|
|
||||||
{
|
|
||||||
struct lar_header *header = get_header_by_name(lar, filename);
|
|
||||||
|
|
||||||
if (header == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
return (void *) ((u8 *) header + ntohl(header->offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify the checksum on a particular LAR entry
|
|
||||||
*
|
|
||||||
* @param lar A pointer to the LAR stream
|
|
||||||
* @param filename The lar entry to verify
|
|
||||||
* @return Return 1 if the entry is valid, 0 if it is not, or -1
|
|
||||||
* on error
|
|
||||||
*/
|
|
||||||
|
|
||||||
int lfverify(struct LAR *lar, const char *filename)
|
|
||||||
{
|
|
||||||
struct lar_header *header = get_header_by_name(lar, filename);
|
|
||||||
|
|
||||||
u8 *ptr = (u8 *) header;
|
|
||||||
int len = ntohl(header->len) + ntohl(header->offset);
|
|
||||||
int offset;
|
|
||||||
u32 csum = 0;
|
|
||||||
|
|
||||||
if (header == NULL)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/* The checksum needs to be calulated on entire data section,
|
|
||||||
* including any padding for the 16 byte alignment (which should
|
|
||||||
* be zeros
|
|
||||||
*/
|
|
||||||
|
|
||||||
len = (len + 15) & 0xFFFFFFF0;
|
|
||||||
|
|
||||||
for(offset = 0; offset < len; offset += 4) {
|
|
||||||
csum += *((u32 *) (ptr + offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
return (csum == 0xFFFFFFFF) ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LFILE * lfopen(struct LAR *lar, const char *filename)
|
|
||||||
{
|
|
||||||
struct LFILE *file;
|
|
||||||
struct lar_header *header = get_header_by_name(lar, filename);
|
|
||||||
|
|
||||||
if (header == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* FIXME: What other validations do we want to do on the file here? */
|
|
||||||
|
|
||||||
file = malloc(sizeof(struct LFILE));
|
|
||||||
|
|
||||||
if (file == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
file->lar = lar;
|
|
||||||
file->header = header;
|
|
||||||
file->size = ntohl(header->len);
|
|
||||||
file->start = ((u8 *) header + ntohl(header->offset));
|
|
||||||
file->offset = 0;
|
|
||||||
|
|
||||||
return file;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *lfmap(struct LFILE *file, int offset)
|
|
||||||
{
|
|
||||||
if (file == NULL)
|
|
||||||
return (void *) -1;
|
|
||||||
|
|
||||||
if (offset > file->size)
|
|
||||||
return (void *) -1;
|
|
||||||
|
|
||||||
return (void *) (file->start + offset);
|
|
||||||
};
|
|
||||||
|
|
||||||
int lfread(void *ptr, size_t size, size_t nmemb, struct LFILE *stream)
|
|
||||||
{
|
|
||||||
size_t tsize, actual;
|
|
||||||
size_t remain = stream->size - stream->offset;
|
|
||||||
|
|
||||||
if (!stream || !remain)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
tsize = (size * nmemb);
|
|
||||||
actual = (tsize > remain) ? remain : tsize;
|
|
||||||
|
|
||||||
memcpy(ptr, (void *) (stream->start + stream->offset), actual);
|
|
||||||
stream->offset += actual;
|
|
||||||
|
|
||||||
return actual;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lfseek(struct LFILE *file, long offset, int whence)
|
|
||||||
{
|
|
||||||
int o = file->offset;
|
|
||||||
|
|
||||||
switch(whence) {
|
|
||||||
case SEEK_SET:
|
|
||||||
o = offset;
|
|
||||||
break;
|
|
||||||
case SEEK_CUR:
|
|
||||||
o += offset;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SEEK_END:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (o < 0 || o > file->size)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
file->offset = o;
|
|
||||||
return file->offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
int lfclose(struct LFILE *file)
|
|
||||||
{
|
|
||||||
if (file)
|
|
||||||
free(file);
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue