View of xos/fs/bin.c


XOS | Parent Directory | View | Download

/* 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 <http://www.gnu.org/licenses/>. */
 
#include "pfs.h"
 
#include <verify_area.h>
#include <segment.h>
#include <consts.h>
#include <enums.h>
#include <errno.h>
#include <string.h>
#include <bin.h>
 
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);
}