aboutsummaryrefslogtreecommitdiff
path: root/ubi-utils/src/libpfi.c
diff options
context:
space:
mode:
authorArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2008-01-23 19:34:52 +0200
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2008-01-23 19:34:52 +0200
commit3ad29ab55ad71d706152781b70a43d9f6be407b9 (patch)
tree4e5a41b23e771faef0f633c6570210a42bd9c037 /ubi-utils/src/libpfi.c
parent22f5fe49d60ea43524a902408b3112a78f2c5aae (diff)
ubi-utils: remove all old tools
Remove all old tools because I cannot maintain them and the original authors do not seem to have time for this. Some of the tools do not work properly, some are just vague and undocumented and seem to be oriented to the environment of the IBM guys. Nevertheless, I'll return the tool as is in the next commit, becouse they are still useful. This commit also adds a ubinize utility to generate UBI images. Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'ubi-utils/src/libpfi.c')
-rw-r--r--ubi-utils/src/libpfi.c628
1 files changed, 0 insertions, 628 deletions
diff --git a/ubi-utils/src/libpfi.c b/ubi-utils/src/libpfi.c
deleted file mode 100644
index 6de24ea..0000000
--- a/ubi-utils/src/libpfi.c
+++ /dev/null
@@ -1,628 +0,0 @@
-/*
- * Copyright (c) International Business Machines Corp., 2006
- * Copyright (C) 2008 Nokia Corporation
- *
- * 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 2 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, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*
- * A library to work with pfi files.
- *
- * Authors Oliver Lohmann
- * Andreas Arnez
- * Joern Engel
- * Frank Haverkamp
- * Artem Bityutskiy
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <errno.h>
-
-#include <mtd/ubi-header.h>
-#include <libpfi.h>
-#include "common.h"
-#include "bootenv.h"
-
-#define PROGRAM_NAME "libpfi"
-
-#define PFI_MAGIC "PFI!\n"
-#define PFI_MAGIC_LEN (sizeof(PFI_MAGIC) - 1)
-#define PFI_DATA "DATA\n"
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-#define PFI_MANDATORY 0x0001
-#define PFI_STRING 0x0002
-#define PFI_LISTVALUE 0x0004
-#define PFI_MANDATORY_UBI 0x0008
-
-enum key_id {
- /* version 1 */
- key_version, /* must be index position 0! */
- key_mode,
- key_size,
- key_crc,
- key_label,
- key_flags,
- key_ubi_ids,
- key_ubi_size,
- key_ubi_type,
- key_ubi_names,
- key_ubi_alignment,
- num_keys,
-};
-
-struct pfi_header {
- uint8_t defined[num_keys]; /* reserve all possible keys even if
- version does not require this. */
- int mode_no; /* current mode no. -> can only increase */
- union {
- char *str;
- uint32_t num;
- } value[num_keys];
-};
-
-struct key_descriptor {
- enum key_id id;
- const char *name;
- uint32_t flags;
-};
-
-static const struct key_descriptor key_desc_v1[] = {
- { key_version, "version", PFI_MANDATORY },
- { key_mode, "mode", PFI_MANDATORY | PFI_STRING },
- { key_size, "size", PFI_MANDATORY },
- { key_crc, "crc", PFI_MANDATORY },
- { key_label, "label", PFI_MANDATORY | PFI_STRING },
- { key_flags, "flags", PFI_MANDATORY },
- { key_ubi_ids, "ubi_ids", PFI_MANDATORY_UBI | PFI_STRING },
- { key_ubi_size, "ubi_size", PFI_MANDATORY_UBI },
- { key_ubi_type, "ubi_type", PFI_MANDATORY_UBI | PFI_STRING },
- { key_ubi_names, "ubi_names", PFI_MANDATORY_UBI | PFI_STRING },
- { key_ubi_alignment, "ubi_alignment", PFI_MANDATORY_UBI },
-};
-
-static const struct key_descriptor *key_descriptors[] = {
- NULL,
- key_desc_v1, /* version 1 */
-};
-
-static const int key_descriptors_max[] = {
- 0, /* version 0 */
- sizeof(key_desc_v1)/sizeof(struct key_descriptor), /* version 1 */
-};
-
-#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-
-static const char* modes[] = {"ubi"};
-
-/* latest version contains all possible keys */
-static const struct key_descriptor *key_desc = key_desc_v1;
-
-#define PFI_IS_UBI(mode) \
- (((mode) != NULL) && (strcmp("ubi", (mode)) == 0))
-
-static int get_mode_no(const char *mode)
-{
- int i;
-
- for (i = 0; i < (int)ARRAY_SIZE(modes); i++)
- if (strcmp(mode, modes[i]) == 0)
- return i;
- return -1;
-}
-
-static int
-find_key_by_name (const char *name)
-{
- int i;
-
- for (i = 0; i < num_keys; i++) {
- if (strcmp(name, key_desc[i].name) == 0)
- return i;
- }
- return -1;
-}
-
-static int
-check_valid (struct pfi_header *head)
-{
- int i;
- int max_keys;
- uint32_t version;
- const char *mode;
- const struct key_descriptor *desc;
- uint32_t to_check = PFI_MANDATORY;
-
- /*
- * For the validity check the list of possible keys depends on
- * the version of the PFI file used.
- */
- version = head->value[key_version].num;
- if (version > PFI_HDRVERSION)
- return PFI_ENOHEADER;
-
- max_keys = key_descriptors_max[version];
- desc = key_descriptors[version];
-
- if (!desc)
- return PFI_ENOVERSION;
-
- mode = head->value[key_mode].str;
- if (PFI_IS_UBI(mode)) {
- to_check |= PFI_MANDATORY_UBI;
- }
- else { /* neither UBI nor RAW == ERR */
- return PFI_EINSUFF;
- }
-
- for (i = 0; i < max_keys; i++) {
- if ((desc[i].flags & to_check) && !head->defined[i]) {
- fprintf(stderr, "libpfi: %s missing\n", desc[i].name);
- return PFI_EINSUFF;
- }
- }
-
- return 0;
-}
-
-int pfi_header_init (struct pfi_header **head)
-{
- int i;
- struct pfi_header *self = malloc(sizeof(*self));
-
- *head = self;
- if (self == NULL)
- return PFI_ENOMEM;
-
- /* initialize maximum number of possible keys */
- for (i = 0; i < num_keys; i++) {
- memset(self, 0, sizeof(*self));
- self->defined[i] = 0;
- }
-
- return 0;
-}
-
-int pfi_header_destroy (struct pfi_header **head)
-{
- int i;
- struct pfi_header *self = *head;
-
- for (i = 0; i < num_keys; i++) {
- if (self->defined[i] && (key_desc[i].flags & PFI_STRING) &&
- self->value[i].str) {
- free(self->value[i].str);
- }
- }
- free(*head);
- *head = NULL;
- return 0;
-}
-
-int pfi_header_setnumber (struct pfi_header *head,
- const char *key, uint32_t value)
-{
- int key_id = find_key_by_name(key);
-
- if (key_id < 0)
- return PFI_EUNDEF;
-
- if (key_desc[key_id].flags & PFI_STRING)
- return PFI_EBADTYPE;
-
- head->value[key_id].num = value;
- head->defined[key_id] = 1;
- return 0;
-}
-
-int pfi_header_setvalue (struct pfi_header *head,
- const char *key, const char *value)
-{
- int key_id = find_key_by_name(key);
-
- if (value == NULL)
- return PFI_EINSUFF;
-
- if ((key_id < 0) || (key_id >= num_keys))
- return PFI_EUNDEF;
-
- if (key_desc[key_id].flags & PFI_STRING) {
- /*
- * The value is a string. Copy to a newly allocated
- * buffer. Delete the old value, if already set.
- */
- size_t len = strlen(value) + 1;
- char *old_str = NULL;
- char *str;
-
- old_str = head->value[key_id].str;
- if (old_str != NULL)
- free(old_str);
-
- str = head->value[key_id].str = (char *) malloc(len);
- if (str == NULL)
- return PFI_ENOMEM;
-
- strcpy(str, value);
- } else {
- int len;
- int ret;
- /* FIXME: here we assume that the value is always
- given in hex and starts with '0x'. */
- ret = sscanf(value, "0x%x%n", &head->value[key_id].num, &len);
- if (ret < 1 || value[len] != '\0')
- return PFI_EBADTYPE;
- }
- head->defined[key_id] = 1;
- return 0;
-}
-
-int pfi_header_getnumber (struct pfi_header *head,
- const char *key, uint32_t *value)
-{
- int key_id = find_key_by_name(key);
-
- if (key_id < 0)
- return PFI_EUNDEF;
-
- if (key_desc[key_id].flags & PFI_STRING)
- return PFI_EBADTYPE;
-
- if (!head->defined[key_id])
- return PFI_EUNDEF;
-
- *value = head->value[key_id].num;
- return 0;
-}
-
-int pfi_header_getstring (struct pfi_header *head,
- const char *key, char *value, size_t size)
-{
- int key_id = find_key_by_name(key);
-
- if (key_id < 0)
- return PFI_EUNDEF;
-
- if (!(key_desc[key_id].flags & PFI_STRING))
- return PFI_EBADTYPE;
-
- if (!head->defined[key_id])
- return PFI_EUNDEF;
-
- strncpy(value, head->value[key_id].str, size-1);
- value[size-1] = '\0';
- return 0;
-}
-
-int pfi_header_read(FILE *in, struct pfi_header *head)
-{
- char mode[PFI_KEYWORD_LEN];
- char buf[256];
-
- if (fread(buf, 1, PFI_MAGIC_LEN, in) != PFI_MAGIC_LEN) {
- errmsg("cannot read %d bytes", PFI_MAGIC_LEN);
- perror("fread");
- return -1;
- }
-
- if (memcmp(buf, PFI_MAGIC, PFI_MAGIC_LEN) != 0) {
- if (memcmp(buf, PFI_DATA, PFI_MAGIC_LEN) == 0)
- return 1;
-
- errmsg("PFI magic \"%s\" not found", PFI_MAGIC);
- return -1;
- }
-
- while (fgets(buf, sizeof(buf), in) != NULL && buf[0] != '\n') {
- char *value;
- char *end;
- value = strchr(buf, '=');
- if (value == NULL)
- return PFI_ENOHEADER;
-
- *value = '\0';
- value++;
- end = strchr(value, '\n');
- if (end)
- *end = '\0';
-
- if (pfi_header_setvalue(head, buf, value))
- return PFI_ENOHEADER;
- }
-
- if (check_valid(head) != 0)
- return PFI_ENOHEADER;
-
- /* set current mode no. in head */
- pfi_header_getstring(head, "mode", mode, PFI_KEYWORD_LEN);
- if (head->mode_no > get_mode_no(mode)) {
- return PFI_EMODE;
- }
- head->mode_no = get_mode_no(mode);
- return 0;
-}
-int
-read_pfi_ubi(struct pfi_header *pfi_hd, struct pfi_ubi **pfi_ubi,
- const char *label)
-{
- int err = 0;
- const char** tmp_names = NULL;
- char tmp_str[PFI_KEYWORD_LEN];
- bootenv_list_t ubi_id_list = NULL;
- bootenv_list_t ubi_name_list = NULL;
- struct pfi_ubi *res;
- uint32_t i;
- size_t size;
-
- res = (struct pfi_ubi *) calloc(1, sizeof(struct pfi_ubi));
- if (!res)
- return -ENOMEM;
-
- err = pfi_header_getnumber(pfi_hd, "size", &(res->data_size));
- if (err != 0) {
- errmsg("cannot read 'size' from PFI.");
- goto err;
- }
-
- err = pfi_header_getnumber(pfi_hd, "crc", &(res->crc));
- if (err != 0) {
- errmsg("cannot read 'crc' from PFI.");
- goto err;
- }
-
- err = pfi_header_getstring(pfi_hd, "ubi_ids", tmp_str, PFI_KEYWORD_LEN);
- if (err != 0) {
- errmsg("cannot read 'ubi_ids' from PFI.");
- goto err;
- }
-
- err = bootenv_list_create(&ubi_id_list);
- if (err != 0) {
- goto err;
- }
- err = bootenv_list_create(&ubi_name_list);
- if (err != 0) {
- goto err;
- }
-
- err = bootenv_list_import(ubi_id_list, tmp_str);
- if (err != 0) {
- errmsg("cannot translate PFI value: %s", tmp_str);
- goto err;
- }
-
- err = bootenv_list_to_num_vector(ubi_id_list, &size,
- &(res->ids));
- res->ids_size = size;
- if (err != 0) {
- errmsg("cannot create numeric value array: %s", tmp_str);
- goto err;
- }
-
- if (res->ids_size == 0) {
- err = -1;
- errmsg("sanity check failed: No ubi_ids specified.");
- goto err;
- }
-
- err = pfi_header_getstring(pfi_hd, "ubi_type",
- tmp_str, PFI_KEYWORD_LEN);
- if (err != 0) {
- errmsg("cannot read 'ubi_type' from PFI.");
- goto err;
- }
- if (strcmp(tmp_str, "static") == 0)
- res->vol_type = UBI_VID_STATIC;
- else if (strcmp(tmp_str, "dynamic") == 0)
- res->vol_type = UBI_VID_DYNAMIC;
- else {
- errmsg("unknown ubi_type in PFI.");
- goto err;
- }
-
- err = pfi_header_getnumber(pfi_hd, "ubi_alignment", &(res->alignment));
- if (err != 0) {
- errmsg("cannot read 'ubi_alignment' from PFI.");
- goto err;
- }
-
- err = pfi_header_getnumber(pfi_hd, "ubi_size", &(res->size));
- if (err != 0) {
- errmsg("cannot read 'ubi_size' from PFI.");
- goto err;
- }
-
- err = pfi_header_getstring(pfi_hd, "ubi_names",
- tmp_str, PFI_KEYWORD_LEN);
- if (err != 0) {
- errmsg("cannot read 'ubi_names' from PFI.");
- goto err;
- }
-
- err = bootenv_list_import(ubi_name_list, tmp_str);
- if (err != 0) {
- errmsg("cannot translate PFI value: %s", tmp_str);
- goto err;
- }
- err = bootenv_list_to_vector(ubi_name_list, &size,
- &(tmp_names));
- res->names_size = size;
- if (err != 0) {
- errmsg("cannot create string array: %s", tmp_str);
- goto err;
- }
-
- if (res->names_size != res->ids_size) {
- errmsg("sanity check failed: ubi_ids list does not match "
- "sizeof ubi_names list.");
- err = -1;
- }
-
- /* copy tmp_names to own structure */
- res->names = calloc(1, res->names_size * sizeof (char*));
- if (res->names == NULL)
- goto err;
-
- for (i = 0; i < res->names_size; i++) {
- res->names[i] = calloc(PFI_UBI_VOL_NAME_LEN + 1, sizeof(char));
- if (res->names[i] == NULL)
- goto err;
- strncpy(res->names[i], tmp_names[i], PFI_UBI_VOL_NAME_LEN + 1);
- }
-
- goto out;
-
- err:
- if (res) {
- if (res->names) {
- for (i = 0; i < res->names_size; i++) {
- if (res->names[i]) {
- free(res->names[i]);
- }
- }
- free(res->names);
- }
- if (res->ids) {
- free(res->ids);
- }
- free(res);
- res = NULL;
- }
-
- out:
- bootenv_list_destroy(&ubi_id_list);
- bootenv_list_destroy(&ubi_name_list);
- if (tmp_names != NULL)
- free(tmp_names);
- *pfi_ubi = res;
- return err;
-}
-
-int
-free_pfi_ubi(struct pfi_ubi **pfi_ubi)
-{
- size_t i;
- struct pfi_ubi *tmp = *pfi_ubi;
- if (tmp) {
- if (tmp->ids)
- free(tmp->ids);
- if (tmp->names) {
- for (i = 0; i < tmp->names_size; i++) {
- if (tmp->names[i]) {
- free(tmp->names[i]);
- }
- }
- free(tmp->names);
- }
- free(tmp);
- }
- *pfi_ubi = NULL;
-
- return 0;
-}
-
-int read_pfi_headers(struct list_entry **ubi_list, FILE *fp_pfi)
-{
- int err = 0;
- long long data_offs = 0;
- long fpos;
- char mode[PFI_KEYWORD_LEN];
- char label[PFI_LABEL_LEN];
- struct list_entry *tmp;
-
- *ubi_list = list_empty(); struct pfi_ubi *ubi = NULL;
- struct pfi_header *pfi_header = NULL;
-
- /* read all headers from PFI and store them in lists */
- err = pfi_header_init(&pfi_header);
- if (err != 0) {
- errmsg("cannot initialize pfi header.");
- goto err;
- }
- while ((err == 0) && !feof(fp_pfi)) {
- err = pfi_header_read(fp_pfi, pfi_header);
- if (err != 0) {
- if (err == 1) {
- err = 0;
- break; /* data section starts,
- all headers read */
- }
- else {
- goto err;
- }
- }
- err = pfi_header_getstring(pfi_header, "label", label,
- PFI_LABEL_LEN);
- if (err != 0) {
- errmsg("cannot read 'label' from PFI.");
- goto err;
- }
- err = pfi_header_getstring(pfi_header, "mode", mode,
- PFI_KEYWORD_LEN);
- if (err != 0) {
- errmsg("cannot read 'mode' from PFI.");
- goto err;
- }
- if (strcmp(mode, "ubi") == 0) {
- err = read_pfi_ubi(pfi_header, &ubi, label);
- if (err != 0) {
- goto err;
- }
- *ubi_list = append_elem(ubi, *ubi_list);
- }
- else {
- errmsg("recvieved unknown mode from PFI: %s", mode);
- goto err;
- }
- ubi->data_offs = data_offs;
- data_offs += ubi->data_size;
- }
-
- fpos = ftell(fp_pfi);
- if (fpos == -1) {
- errmsg("ftell returned error");
- perror("ftell");
- goto err;
- }
-
- list_for_each(ubi, tmp, *ubi_list)
- ubi->data_offs += fpos;
-
- goto out;
-
- err:
- *ubi_list = remove_all((free_func_t)&free_pfi_ubi, *ubi_list);
- out:
- pfi_header_destroy(&pfi_header);
- return err;
-
-}