summaryrefslogtreecommitdiff
path: root/ubi-utils/src/pfi.c
diff options
context:
space:
mode:
Diffstat (limited to 'ubi-utils/src/pfi.c')
-rw-r--r--ubi-utils/src/pfi.c458
1 files changed, 0 insertions, 458 deletions
diff --git a/ubi-utils/src/pfi.c b/ubi-utils/src/pfi.c
deleted file mode 100644
index fa835e2..0000000
--- a/ubi-utils/src/pfi.c
+++ /dev/null
@@ -1,458 +0,0 @@
-/*
- * Copyright (c) International Business Machines Corp., 2006
- *
- * 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.
- */
-
-/*
- * @file pfi.c
- *
- * @author Oliver Lohmann
- * Andreas Arnez
- * Joern Engel
- * Frank Haverkamp
- *
- * @brief libpfi holds all code to create and process pfi files.
- *
- * <oliloh@de.ibm.com> Wed Feb 8 11:38:22 CET 2006: Initial creation.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <syslog.h>
-#include <stdarg.h>
-#include <errno.h>
-
-#include "pfi.h"
-
-#define PFI_MAGIC "PFI!\n"
-#define PFI_DATA "DATA\n" /* The same size as PFI_MAGIC */
-#define PFI_MAGIC_LEN 5
-
-static const char copyright [] __attribute__((unused)) =
- "Copyright (c) International Business Machines Corp., 2006";
-
-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,
- key_raw_starts,
- key_raw_total_size,
- num_keys,
-};
-
-struct pfi_header {
- char 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];
-};
-
-
-#define PFI_MANDATORY 0x0001
-#define PFI_STRING 0x0002
-#define PFI_LISTVALUE 0x0004 /* comma seperated list of nums */
-#define PFI_MANDATORY_UBI 0x0008
-#define PFI_MANDATORY_RAW 0x0010
-
-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 },
- { key_raw_starts, "raw_starts", PFI_MANDATORY_RAW | PFI_STRING },
- { key_raw_total_size, "raw_total_size", PFI_MANDATORY_RAW },
-};
-
-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[] = {"raw", "ubi"}; /* order isn't arbitrary! */
-
-/* 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))
-
-#define PFI_IS_RAW(mode) \
- (((mode) != NULL) && (strcmp("raw", (mode)) == 0))
-
-/**
- * @return <0 On Error.
- * >=0 Mode no.
- */
-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 (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 if (PFI_IS_RAW(mode)) {
- to_check |= PFI_MANDATORY_RAW;
- }
- 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 (pfi_header *head)
-{
- int i;
- pfi_header self = (pfi_header) 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 (pfi_header *head)
-{
- int i;
- 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 (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 (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 (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 (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_write (FILE *out, pfi_header head)
-{
- int i;
- int ret;
-
- pfi_header_setnumber(head, "version", PFI_HDRVERSION);
-
- if ((ret = check_valid(head)) != 0)
- return ret;
-
- /* OK. Now write the header. */
-
- ret = fwrite(PFI_MAGIC, 1, PFI_MAGIC_LEN, out);
- if (ret < PFI_MAGIC_LEN)
- return ret;
-
-
- for (i = 0; i < num_keys; i++) {
- if (!head->defined[i])
- continue;
-
- ret = fprintf(out, "%s=", key_desc[i].name);
- if (ret < 0)
- return PFI_EFILE;
-
- if (key_desc[i].flags & PFI_STRING) {
- ret = fprintf(out, "%s", head->value[i].str);
- if (ret < 0)
- return PFI_EFILE;
- } else {
- ret = fprintf(out, "0x%8x", head->value[i].num);
- if (ret < 0)
- return PFI_EFILE;
-
- }
- ret = fprintf(out, "\n");
- if (ret < 0)
- return PFI_EFILE;
- }
- ret = fprintf(out, "\n");
- if (ret < 0)
- return PFI_EFILE;
-
- ret = fflush(out);
- if (ret != 0)
- return PFI_EFILE;
-
- return 0;
-}
-
-int pfi_header_read (FILE *in, pfi_header head)
-{
- char magic[PFI_MAGIC_LEN];
- char mode[PFI_KEYWORD_LEN];
- char buf[256];
-
- if (PFI_MAGIC_LEN != fread(magic, 1, PFI_MAGIC_LEN, in))
- return PFI_EFILE;
- if (memcmp(magic, PFI_MAGIC, PFI_MAGIC_LEN) != 0) {
- if (memcmp(magic, PFI_DATA, PFI_MAGIC_LEN) == 0) {
- return PFI_DATA_START;
- }
- return PFI_ENOHEADER;
- }
-
- 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 pfi_header_dump (FILE *out, pfi_header head __attribute__((__unused__)))
-{
- fprintf(out, "Sorry not implemented yet. Write mail to "
- "Andreas Arnez and complain!\n");
- return 0;
-}
-
-int pfi_read (FILE *in, pfi_read_func func, void *priv_data)
-{
- int rc;
- pfi_header header;
-
- rc = pfi_header_init (&header);
- if (0 != rc)
- return rc;
- if (!func)
- return PFI_EINVAL;
-
- while ((0 == rc) && !feof(in)) {
- /*
- * Read header and check consistency of the fields.
- */
- rc = pfi_header_read( in, header );
- if (0 != rc)
- break;
- if (func) {
- rc = func(in, header, priv_data);
- if (rc != 0)
- break;
- }
- }
-
- pfi_header_destroy(&header);
- return rc;
-}