/* Copyright (C) 2008 Emmanuel Varoquaux
This file is part of XOS.
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, either version 3 of the License, or
(at your option) any later version.
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, see . */
#include "pfs.h"
#include
#include
#include
#include
#include
#include
#include
static inline int check_checksum(const bin_hdr_t *hdr)
{
unsigned long sum;
const unsigned char *p;
sum = 0;
for (p = (const void *)hdr; p != (const void *)&hdr->checksum; p++)
sum += *p;
return sum == hdr->checksum;
}
int bin_check(const void *bin_start)
{
const void *p;
for (p = bin_start; ((const bin_hdr_t *)p)->magic == BIN_MAGIC; p += bin_align(sizeof (bin_hdr_t) + ((const bin_hdr_t *)p)->size))
if (!check_checksum(p))
return 0;
return 1;
}
int bin_find(const void *bin_start, const char *fs_basename, unsigned long *id, int *type)
{
const void *p;
for (p = bin_start; ((const bin_hdr_t *)p)->magic == BIN_MAGIC; p += bin_align(sizeof (bin_hdr_t) + ((const bin_hdr_t *)p)->size))
if (pfs_name_match(fs_basename, ((const bin_hdr_t *)p)->name)) {
*id = (unsigned long)p;
*type = FT_REG;
return 1;
}
return 0;
}
int bin_get_name(const void *bin_file, char name[])
{
strcpy(name, ((const bin_hdr_t *)bin_file)->name);
return 0;
}
int bin_get_size(const void *bin_file, unsigned long *size)
{
*size = ((const bin_hdr_t *)bin_file)->size;
return 0;
}
int bin_read_dir(const void *bin_start, unsigned long pos, char *fs_buf, unsigned int count)
{
const void *p;
unsigned int len;
if (!count)
return 0;
if (!verify_area(fs_buf, count, PF_WRITE))
return -EFAULT;
/* on passe les entrees inferieures a pos */
p = bin_start;
while (1) {
if (((const bin_hdr_t *)p)->magic != BIN_MAGIC)
return 0; /* plus d'entree a lire */
len = strlen(((const bin_hdr_t *)p)->name);
if (pos < len + 1)
break; /* une entree a lire */
pos -= len + 1;
p += bin_align(sizeof (bin_hdr_t) + ((const bin_hdr_t *)p)->size);
}
/* lecture de l'entree ou se trouve pos */
return pfs_read_name(((const bin_hdr_t *)p)->name, pos, fs_buf, count);
}
int bin_read(const void *bin_file, unsigned long pos, char *fs_buf, unsigned int count)
{
return pfs_read_buf(bin_file + sizeof (bin_hdr_t), ((const bin_hdr_t *)bin_file)->size, pos, fs_buf, count);
}