/* 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); }