diff options
Diffstat (limited to 'ubi-utils')
-rw-r--r-- | ubi-utils/LICENSE.libiniparser | 20 | ||||
-rw-r--r-- | ubi-utils/Makemodule.am | 37 | ||||
-rw-r--r-- | ubi-utils/dictionary.c | 405 | ||||
-rw-r--r-- | ubi-utils/include/dictionary.h | 174 | ||||
-rw-r--r-- | ubi-utils/include/libiniparser.h | 280 | ||||
-rw-r--r-- | ubi-utils/include/libscan.h | 113 | ||||
-rw-r--r-- | ubi-utils/include/libubi.h | 485 | ||||
-rw-r--r-- | ubi-utils/include/libubigen.h | 195 | ||||
-rw-r--r-- | ubi-utils/libiniparser.c | 646 | ||||
-rw-r--r-- | ubi-utils/libscan.c | 225 | ||||
-rw-r--r-- | ubi-utils/libubi.c | 1391 | ||||
-rw-r--r-- | ubi-utils/libubi_int.h | 134 | ||||
-rw-r--r-- | ubi-utils/libubigen.c | 315 |
13 files changed, 4 insertions, 4416 deletions
diff --git a/ubi-utils/LICENSE.libiniparser b/ubi-utils/LICENSE.libiniparser deleted file mode 100644 index 74c125c..0000000 --- a/ubi-utils/LICENSE.libiniparser +++ /dev/null @@ -1,20 +0,0 @@ -Copyright (c) 2000-2007 by Nicolas Devillard. -MIT License - -Permission is hereby granted, free of charge, to any person obtaining a -copy of this software and associated documentation files (the "Software"), -to deal in the Software without restriction, including without limitation -the rights to use, copy, modify, merge, publish, distribute, sublicense, -and/or sell copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/ubi-utils/Makemodule.am b/ubi-utils/Makemodule.am index f1c50df..215eac2 100644 --- a/ubi-utils/Makemodule.am +++ b/ubi-utils/Makemodule.am @@ -1,78 +1,49 @@ -libubi_a_SOURCES = ubi-utils/libubi.c ubi-utils/libubi_int.h -libubi_a_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include - -libubigen_a_SOURCES = ubi-utils/libubigen.c -libubigen_a_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include - ubiupdatevol_SOURCES = ubi-utils/ubiupdatevol.c ubiupdatevol_LDADD = libmtd.a libubi.a -ubiupdatevol_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include ubimkvol_SOURCES = ubi-utils/ubimkvol.c ubimkvol_LDADD = libmtd.a libubi.a -ubimkvol_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include ubirmvol_SOURCES = ubi-utils/ubirmvol.c ubirmvol_LDADD = libmtd.a libubi.a -ubirmvol_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include ubicrc32_SOURCES = ubi-utils/ubicrc32.c ubicrc32_LDADD = libmtd.a libubi.a -ubicrc32_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include ubinfo_SOURCES = ubi-utils/ubinfo.c ubinfo_LDADD = libmtd.a libubi.a -ubinfo_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include ubiattach_SOURCES = ubi-utils/ubiattach.c ubiattach_LDADD = libmtd.a libubi.a -ubiattach_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include ubidetach_SOURCES = ubi-utils/ubidetach.c ubidetach_LDADD = libmtd.a libubi.a -ubidetach_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include -ubinize_SOURCES = ubi-utils/ubinize.c ubi-utils/libiniparser.c ubi-utils/dictionary.c -ubinize_LDADD = libubi.a libubigen.a libmtd.a -ubinize_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include +ubinize_SOURCES = ubi-utils/ubinize.c +ubinize_LDADD = libubi.a libubigen.a libmtd.a libiniparser.a -ubiformat_SOURCES = ubi-utils/ubiformat.c ubi-utils/libscan.c -ubiformat_LDADD = libubi.a libubigen.a libmtd.a -ubiformat_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include +ubiformat_SOURCES = ubi-utils/ubiformat.c +ubiformat_LDADD = libubi.a libubigen.a libmtd.a libscan.a ubirename_SOURCES = ubi-utils/ubirename.c ubirename_LDADD = libmtd.a libubi.a -ubirename_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include mtdinfo_SOURCES = ubi-utils/mtdinfo.c mtdinfo_LDADD = libubi.a libubigen.a libmtd.a -mtdinfo_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include ubirsvol_SOURCES = ubi-utils/ubirsvol.c ubirsvol_LDADD = libmtd.a libubi.a -ubirsvol_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include ubiblock_SOURCES = ubi-utils/ubiblock.c ubiblock_LDADD = libmtd.a libubi.a -ubiblock_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/ubi-utils/include UBI_BINS = \ ubiupdatevol ubimkvol ubirmvol ubicrc32 ubinfo ubiattach \ ubidetach ubinize ubiformat ubirename mtdinfo ubirsvol ubiblock -UBI_EXTRA = \ - ubi-utils/LICENSE.libiniparser - -UBI_HEADER = \ - ubi-utils/include ubi-utils/libubi_int.h - UBI_MAN = \ ubi-utils/ubinize.8 -EXTRA_DIST += $(UBI_HEADER) $(UBI_EXTRA) - dist_man8_MANS += $(UBI_MAN) sbin_PROGRAMS += $(UBI_BINS) - -noinst_LIBRARIES += libubi.a libubigen.a diff --git a/ubi-utils/dictionary.c b/ubi-utils/dictionary.c deleted file mode 100644 index f4b7468..0000000 --- a/ubi-utils/dictionary.c +++ /dev/null @@ -1,405 +0,0 @@ -/*-------------------------------------------------------------------------*/ -/** - @file dictionary.c - @author N. Devillard - @date Sep 2007 - @version $Revision: 1.27 $ - @brief Implements a dictionary for string variables. - - This module implements a simple dictionary object, i.e. a list - of string/string associations. This object is useful to store e.g. - informations retrieved from a configuration file (ini files). -*/ -/*--------------------------------------------------------------------------*/ - -/* - $Id: dictionary.c,v 1.27 2007-11-23 21:39:18 ndevilla Exp $ - $Revision: 1.27 $ -*/ -/*--------------------------------------------------------------------------- - Includes - ---------------------------------------------------------------------------*/ -#include "dictionary.h" - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -/** Maximum value size for integers and doubles. */ -#define MAXVALSZ 1024 - -/** Minimal allocated number of entries in a dictionary */ -#define DICTMINSZ 128 - -/** Invalid key token */ -#define DICT_INVALID_KEY ((char*)-1) - -/*--------------------------------------------------------------------------- - Private functions - ---------------------------------------------------------------------------*/ - -/* Doubles the allocated size associated to a pointer */ -/* 'size' is the current allocated size. */ -static void * mem_double(void * ptr, int size) -{ - void * newptr ; - - newptr = calloc(2*size, 1); - if (newptr==NULL) { - return NULL ; - } - memcpy(newptr, ptr, size); - free(ptr); - return newptr ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Duplicate a string - @param s String to duplicate - @return Pointer to a newly allocated string, to be freed with free() - - This is a replacement for strdup(). This implementation is provided - for systems that do not have it. - */ -/*--------------------------------------------------------------------------*/ -static char * xstrdup(char * s) -{ - char * t ; - if (!s) - return NULL ; - t = malloc(strlen(s)+1) ; - if (t) { - strcpy(t,s); - } - return t ; -} - -/*--------------------------------------------------------------------------- - Function codes - ---------------------------------------------------------------------------*/ -/*-------------------------------------------------------------------------*/ -/** - @brief Compute the hash key for a string. - @param key Character string to use for key. - @return 1 unsigned int on at least 32 bits. - - This hash function has been taken from an Article in Dr Dobbs Journal. - This is normally a collision-free function, distributing keys evenly. - The key is stored anyway in the struct so that collision can be avoided - by comparing the key itself in last resort. - */ -/*--------------------------------------------------------------------------*/ -unsigned dictionary_hash(char * key) -{ - int len ; - unsigned hash ; - int i ; - - len = strlen(key); - for (hash=0, i=0 ; i<len ; i++) { - hash += (unsigned)key[i] ; - hash += (hash<<10); - hash ^= (hash>>6) ; - } - hash += (hash <<3); - hash ^= (hash >>11); - hash += (hash <<15); - return hash ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Create a new dictionary object. - @param size Optional initial size of the dictionary. - @return 1 newly allocated dictionary objet. - - This function allocates a new dictionary object of given size and returns - it. If you do not know in advance (roughly) the number of entries in the - dictionary, give size=0. - */ -/*--------------------------------------------------------------------------*/ -dictionary * dictionary_new(int size) -{ - dictionary * d ; - - /* If no size was specified, allocate space for DICTMINSZ */ - if (size<DICTMINSZ) size=DICTMINSZ ; - - if (!(d = (dictionary *)calloc(1, sizeof(dictionary)))) { - return NULL; - } - d->size = size ; - d->val = (char **)calloc(size, sizeof(char*)); - d->key = (char **)calloc(size, sizeof(char*)); - d->hash = (unsigned int *)calloc(size, sizeof(unsigned)); - return d ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Delete a dictionary object - @param d dictionary object to deallocate. - @return void - - Deallocate a dictionary object and all memory associated to it. - */ -/*--------------------------------------------------------------------------*/ -void dictionary_del(dictionary * d) -{ - int i ; - - if (d==NULL) return ; - for (i=0 ; i<d->size ; i++) { - if (d->key[i]!=NULL) - free(d->key[i]); - if (d->val[i]!=NULL) - free(d->val[i]); - } - free(d->val); - free(d->key); - free(d->hash); - free(d); - return ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Get a value from a dictionary. - @param d dictionary object to search. - @param key Key to look for in the dictionary. - @param def Default value to return if key not found. - @return 1 pointer to internally allocated character string. - - This function locates a key in a dictionary and returns a pointer to its - value, or the passed 'def' pointer if no such key can be found in - dictionary. The returned character pointer points to data internal to the - dictionary object, you should not try to free it or modify it. - */ -/*--------------------------------------------------------------------------*/ -char * dictionary_get(dictionary * d, char * key, char * def) -{ - unsigned hash ; - int i ; - - hash = dictionary_hash(key); - for (i=0 ; i<d->size ; i++) { - if (d->key[i]==NULL) - continue ; - /* Compare hash */ - if (hash==d->hash[i]) { - /* Compare string, to avoid hash collisions */ - if (!strcmp(key, d->key[i])) { - return d->val[i] ; - } - } - } - return def ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Set a value in a dictionary. - @param d dictionary object to modify. - @param key Key to modify or add. - @param val Value to add. - @return int 0 if Ok, anything else otherwise - - If the given key is found in the dictionary, the associated value is - replaced by the provided one. If the key cannot be found in the - dictionary, it is added to it. - - It is Ok to provide a NULL value for val, but NULL values for the dictionary - or the key are considered as errors: the function will return immediately - in such a case. - - Notice that if you dictionary_set a variable to NULL, a call to - dictionary_get will return a NULL value: the variable will be found, and - its value (NULL) is returned. In other words, setting the variable - content to NULL is equivalent to deleting the variable from the - dictionary. It is not possible (in this implementation) to have a key in - the dictionary without value. - - This function returns non-zero in case of failure. - */ -/*--------------------------------------------------------------------------*/ -int dictionary_set(dictionary * d, char * key, char * val) -{ - int i ; - unsigned hash ; - - if (d==NULL || key==NULL) return -1 ; - - /* Compute hash for this key */ - hash = dictionary_hash(key) ; - /* Find if value is already in dictionary */ - if (d->n>0) { - for (i=0 ; i<d->size ; i++) { - if (d->key[i]==NULL) - continue ; - if (hash==d->hash[i]) { /* Same hash value */ - if (!strcmp(key, d->key[i])) { /* Same key */ - /* Found a value: modify and return */ - if (d->val[i]!=NULL) - free(d->val[i]); - d->val[i] = val ? xstrdup(val) : NULL ; - /* Value has been modified: return */ - return 0 ; - } - } - } - } - /* Add a new value */ - /* See if dictionary needs to grow */ - if (d->n==d->size) { - - /* Reached maximum size: reallocate dictionary */ - d->val = (char **)mem_double(d->val, d->size * sizeof(char*)) ; - d->key = (char **)mem_double(d->key, d->size * sizeof(char*)) ; - d->hash = (unsigned int *)mem_double(d->hash, d->size * sizeof(unsigned)) ; - if ((d->val==NULL) || (d->key==NULL) || (d->hash==NULL)) { - /* Cannot grow dictionary */ - return -1 ; - } - /* Double size */ - d->size *= 2 ; - } - - /* Insert key in the first empty slot */ - for (i=0 ; i<d->size ; i++) { - if (d->key[i]==NULL) { - /* Add key here */ - break ; - } - } - /* Copy key */ - d->key[i] = xstrdup(key); - d->val[i] = val ? xstrdup(val) : NULL ; - d->hash[i] = hash; - d->n ++ ; - return 0 ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Delete a key in a dictionary - @param d dictionary object to modify. - @param key Key to remove. - @return void - - This function deletes a key in a dictionary. Nothing is done if the - key cannot be found. - */ -/*--------------------------------------------------------------------------*/ -void dictionary_unset(dictionary * d, char * key) -{ - unsigned hash ; - int i ; - - if (key == NULL) { - return; - } - - hash = dictionary_hash(key); - for (i=0 ; i<d->size ; i++) { - if (d->key[i]==NULL) - continue ; - /* Compare hash */ - if (hash==d->hash[i]) { - /* Compare string, to avoid hash collisions */ - if (!strcmp(key, d->key[i])) { - /* Found key */ - break ; - } - } - } - if (i>=d->size) - /* Key not found */ - return ; - - free(d->key[i]); - d->key[i] = NULL ; - if (d->val[i]!=NULL) { - free(d->val[i]); - d->val[i] = NULL ; - } - d->hash[i] = 0 ; - d->n -- ; - return ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Dump a dictionary to an opened file pointer. - @param d Dictionary to dump - @param f Opened file pointer. - @return void - - Dumps a dictionary onto an opened file pointer. Key pairs are printed out - as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as - output file pointers. - */ -/*--------------------------------------------------------------------------*/ -void dictionary_dump(dictionary * d, FILE * out) -{ - int i ; - - if (d==NULL || out==NULL) return ; - if (d->n<1) { - fprintf(out, "empty dictionary\n"); - return ; - } - for (i=0 ; i<d->size ; i++) { - if (d->key[i]) { - fprintf(out, "%20s\t[%s]\n", - d->key[i], - d->val[i] ? d->val[i] : "UNDEF"); - } - } - return ; -} - - -/* Test code */ -#ifdef TESTDIC -#define NVALS 20000 -int main(int argc, char *argv[]) -{ - dictionary * d ; - char * val ; - int i ; - char cval[90] ; - - /* Allocate dictionary */ - printf("allocating...\n"); - d = dictionary_new(0); - - /* Set values in dictionary */ - printf("setting %d values...\n", NVALS); - for (i=0 ; i<NVALS ; i++) { - sprintf(cval, "%04d", i); - dictionary_set(d, cval, "salut"); - } - printf("getting %d values...\n", NVALS); - for (i=0 ; i<NVALS ; i++) { - sprintf(cval, "%04d", i); - val = dictionary_get(d, cval, DICT_INVALID_KEY); - if (val==DICT_INVALID_KEY) { - printf("cannot get value for key [%s]\n", cval); - } - } - printf("unsetting %d values...\n", NVALS); - for (i=0 ; i<NVALS ; i++) { - sprintf(cval, "%04d", i); - dictionary_unset(d, cval); - } - if (d->n != 0) { - printf("error deleting values\n"); - } - printf("deallocating...\n"); - dictionary_del(d); - return 0 ; -} -#endif -/* vim: set ts=4 et sw=4 tw=75 */ diff --git a/ubi-utils/include/dictionary.h b/ubi-utils/include/dictionary.h deleted file mode 100644 index c7d1790..0000000 --- a/ubi-utils/include/dictionary.h +++ /dev/null @@ -1,174 +0,0 @@ - -/*-------------------------------------------------------------------------*/ -/** - @file dictionary.h - @author N. Devillard - @date Sep 2007 - @version $Revision: 1.12 $ - @brief Implements a dictionary for string variables. - - This module implements a simple dictionary object, i.e. a list - of string/string associations. This object is useful to store e.g. - informations retrieved from a configuration file (ini files). -*/ -/*--------------------------------------------------------------------------*/ - -/* - $Id: dictionary.h,v 1.12 2007-11-23 21:37:00 ndevilla Exp $ - $Author: ndevilla $ - $Date: 2007-11-23 21:37:00 $ - $Revision: 1.12 $ -*/ - -#ifndef _DICTIONARY_H_ -#define _DICTIONARY_H_ - -/*--------------------------------------------------------------------------- - Includes - ---------------------------------------------------------------------------*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -/*--------------------------------------------------------------------------- - New types - ---------------------------------------------------------------------------*/ - - -/*-------------------------------------------------------------------------*/ -/** - @brief Dictionary object - - This object contains a list of string/string associations. Each - association is identified by a unique string key. Looking up values - in the dictionary is speeded up by the use of a (hopefully collision-free) - hash function. - */ -/*-------------------------------------------------------------------------*/ -typedef struct _dictionary_ { - int n ; /** Number of entries in dictionary */ - int size ; /** Storage size */ - char ** val ; /** List of string values */ - char ** key ; /** List of string keys */ - unsigned * hash ; /** List of hash values for keys */ -} dictionary ; - - -/*--------------------------------------------------------------------------- - Function prototypes - ---------------------------------------------------------------------------*/ - -/*-------------------------------------------------------------------------*/ -/** - @brief Compute the hash key for a string. - @param key Character string to use for key. - @return 1 unsigned int on at least 32 bits. - - This hash function has been taken from an Article in Dr Dobbs Journal. - This is normally a collision-free function, distributing keys evenly. - The key is stored anyway in the struct so that collision can be avoided - by comparing the key itself in last resort. - */ -/*--------------------------------------------------------------------------*/ -unsigned dictionary_hash(char * key); - -/*-------------------------------------------------------------------------*/ -/** - @brief Create a new dictionary object. - @param size Optional initial size of the dictionary. - @return 1 newly allocated dictionary objet. - - This function allocates a new dictionary object of given size and returns - it. If you do not know in advance (roughly) the number of entries in the - dictionary, give size=0. - */ -/*--------------------------------------------------------------------------*/ -dictionary * dictionary_new(int size); - -/*-------------------------------------------------------------------------*/ -/** - @brief Delete a dictionary object - @param d dictionary object to deallocate. - @return void - - Deallocate a dictionary object and all memory associated to it. - */ -/*--------------------------------------------------------------------------*/ -void dictionary_del(dictionary * vd); - -/*-------------------------------------------------------------------------*/ -/** - @brief Get a value from a dictionary. - @param d dictionary object to search. - @param key Key to look for in the dictionary. - @param def Default value to return if key not found. - @return 1 pointer to internally allocated character string. - - This function locates a key in a dictionary and returns a pointer to its - value, or the passed 'def' pointer if no such key can be found in - dictionary. The returned character pointer points to data internal to the - dictionary object, you should not try to free it or modify it. - */ -/*--------------------------------------------------------------------------*/ -char * dictionary_get(dictionary * d, char * key, char * def); - - -/*-------------------------------------------------------------------------*/ -/** - @brief Set a value in a dictionary. - @param d dictionary object to modify. - @param key Key to modify or add. - @param val Value to add. - @return int 0 if Ok, anything else otherwise - - If the given key is found in the dictionary, the associated value is - replaced by the provided one. If the key cannot be found in the - dictionary, it is added to it. - - It is Ok to provide a NULL value for val, but NULL values for the dictionary - or the key are considered as errors: the function will return immediately - in such a case. - - Notice that if you dictionary_set a variable to NULL, a call to - dictionary_get will return a NULL value: the variable will be found, and - its value (NULL) is returned. In other words, setting the variable - content to NULL is equivalent to deleting the variable from the - dictionary. It is not possible (in this implementation) to have a key in - the dictionary without value. - - This function returns non-zero in case of failure. - */ -/*--------------------------------------------------------------------------*/ -int dictionary_set(dictionary * vd, char * key, char * val); - -/*-------------------------------------------------------------------------*/ -/** - @brief Delete a key in a dictionary - @param d dictionary object to modify. - @param key Key to remove. - @return void - - This function deletes a key in a dictionary. Nothing is done if the - key cannot be found. - */ -/*--------------------------------------------------------------------------*/ -void dictionary_unset(dictionary * d, char * key); - - -/*-------------------------------------------------------------------------*/ -/** - @brief Dump a dictionary to an opened file pointer. - @param d Dictionary to dump - @param f Opened file pointer. - @return void - - Dumps a dictionary onto an opened file pointer. Key pairs are printed out - as @c [Key]=[Value], one per line. It is Ok to provide stdout or stderr as - output file pointers. - */ -/*--------------------------------------------------------------------------*/ -void dictionary_dump(dictionary * d, FILE * out); - -#endif diff --git a/ubi-utils/include/libiniparser.h b/ubi-utils/include/libiniparser.h deleted file mode 100644 index be3c667..0000000 --- a/ubi-utils/include/libiniparser.h +++ /dev/null @@ -1,280 +0,0 @@ - -/*-------------------------------------------------------------------------*/ -/** - @file iniparser.h - @author N. Devillard - @date Sep 2007 - @version 3.0 - @brief Parser for ini files. -*/ -/*--------------------------------------------------------------------------*/ - -/* - $Id: iniparser.h,v 1.24 2007-11-23 21:38:19 ndevilla Exp $ - $Revision: 1.24 $ -*/ - -#ifndef _INIPARSER_H_ -#define _INIPARSER_H_ - -/*--------------------------------------------------------------------------- - Includes - ---------------------------------------------------------------------------*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -/* - * The following #include is necessary on many Unixes but not Linux. - * It is not needed for Windows platforms. - * Uncomment it if needed. - */ -/* #include <unistd.h> */ - -#include "dictionary.h" - -/*--------------------------------------------------------------------------- - Macros - ---------------------------------------------------------------------------*/ -/** For backwards compatibility only */ -#define iniparser_getstr(d, k) iniparser_getstring(d, k, NULL) -#define iniparser_setstr iniparser_setstring - -/*-------------------------------------------------------------------------*/ -/** - @brief Get number of sections in a dictionary - @param d Dictionary to examine - @return int Number of sections found in dictionary - - This function returns the number of sections found in a dictionary. - The test to recognize sections is done on the string stored in the - dictionary: a section name is given as "section" whereas a key is - stored as "section:key", thus the test looks for entries that do not - contain a colon. - - This clearly fails in the case a section name contains a colon, but - this should simply be avoided. - - This function returns -1 in case of error. - */ -/*--------------------------------------------------------------------------*/ - -int iniparser_getnsec(dictionary * d); - - -/*-------------------------------------------------------------------------*/ -/** - @brief Get name for section n in a dictionary. - @param d Dictionary to examine - @param n Section number (from 0 to nsec-1). - @return Pointer to char string - - This function locates the n-th section in a dictionary and returns - its name as a pointer to a string statically allocated inside the - dictionary. Do not free or modify the returned string! - - This function returns NULL in case of error. - */ -/*--------------------------------------------------------------------------*/ - -char * iniparser_getsecname(dictionary * d, int n); - - -/*-------------------------------------------------------------------------*/ -/** - @brief Save a dictionary to a loadable ini file - @param d Dictionary to dump - @param f Opened file pointer to dump to - @return void - - This function dumps a given dictionary into a loadable ini file. - It is Ok to specify @c stderr or @c stdout as output files. - */ -/*--------------------------------------------------------------------------*/ - -void iniparser_dump_ini(dictionary * d, FILE * f); - -/*-------------------------------------------------------------------------*/ -/** - @brief Dump a dictionary to an opened file pointer. - @param d Dictionary to dump. - @param f Opened file pointer to dump to. - @return void - - This function prints out the contents of a dictionary, one element by - line, onto the provided file pointer. It is OK to specify @c stderr - or @c stdout as output files. This function is meant for debugging - purposes mostly. - */ -/*--------------------------------------------------------------------------*/ -void iniparser_dump(dictionary * d, FILE * f); - -/*-------------------------------------------------------------------------*/ -/** - @brief Get the string associated to a key - @param d Dictionary to search - @param key Key string to look for - @param def Default value to return if key not found. - @return pointer to statically allocated character string - - This function queries a dictionary for a key. A key as read from an - ini file is given as "section:key". If the key cannot be found, - the pointer passed as 'def' is returned. - The returned char pointer is pointing to a string allocated in - the dictionary, do not free or modify it. - */ -/*--------------------------------------------------------------------------*/ -char * iniparser_getstring(dictionary * d, const char * key, char * def); - -/*-------------------------------------------------------------------------*/ -/** - @brief Get the string associated to a key, convert to an int - @param d Dictionary to search - @param key Key string to look for - @param notfound Value to return in case of error - @return integer - - This function queries a dictionary for a key. A key as read from an - ini file is given as "section:key". If the key cannot be found, - the notfound value is returned. - - Supported values for integers include the usual C notation - so decimal, octal (starting with 0) and hexadecimal (starting with 0x) - are supported. Examples: - - - "42" -> 42 - - "042" -> 34 (octal -> decimal) - - "0x42" -> 66 (hexa -> decimal) - - Warning: the conversion may overflow in various ways. Conversion is - totally outsourced to strtol(), see the associated man page for overflow - handling. - - Credits: Thanks to A. Becker for suggesting strtol() - */ -/*--------------------------------------------------------------------------*/ -int iniparser_getint(dictionary * d, const char * key, int notfound); - -/*-------------------------------------------------------------------------*/ -/** - @brief Get the string associated to a key, convert to a double - @param d Dictionary to search - @param key Key string to look for - @param notfound Value to return in case of error - @return double - - This function queries a dictionary for a key. A key as read from an - ini file is given as "section:key". If the key cannot be found, - the notfound value is returned. - */ -/*--------------------------------------------------------------------------*/ -double iniparser_getdouble(dictionary * d, char * key, double notfound); - -/*-------------------------------------------------------------------------*/ -/** - @brief Get the string associated to a key, convert to a boolean - @param d Dictionary to search - @param key Key string to look for - @param notfound Value to return in case of error - @return integer - - This function queries a dictionary for a key. A key as read from an - ini file is given as "section:key". If the key cannot be found, - the notfound value is returned. - - A true boolean is found if one of the following is matched: - - - A string starting with 'y' - - A string starting with 'Y' - - A string starting with 't' - - A string starting with 'T' - - A string starting with '1' - - A false boolean is found if one of the following is matched: - - - A string starting with 'n' - - A string starting with 'N' - - A string starting with 'f' - - A string starting with 'F' - - A string starting with '0' - - The notfound value returned if no boolean is identified, does not - necessarily have to be 0 or 1. - */ -/*--------------------------------------------------------------------------*/ -int iniparser_getboolean(dictionary * d, const char * key, int notfound); - - -/*-------------------------------------------------------------------------*/ -/** - @brief Set an entry in a dictionary. - @param ini Dictionary to modify. - @param entry Entry to modify (entry name) - @param val New value to associate to the entry. - @return int 0 if Ok, -1 otherwise. - - If the given entry can be found in the dictionary, it is modified to - contain the provided value. If it cannot be found, -1 is returned. - It is Ok to set val to NULL. - */ -/*--------------------------------------------------------------------------*/ -int iniparser_setstring(dictionary * ini, char * entry, char * val); - - -/*-------------------------------------------------------------------------*/ -/** - @brief Delete an entry in a dictionary - @param ini Dictionary to modify - @param entry Entry to delete (entry name) - @return void - - If the given entry can be found, it is deleted from the dictionary. - */ -/*--------------------------------------------------------------------------*/ -void iniparser_unset(dictionary * ini, char * entry); - -/*-------------------------------------------------------------------------*/ -/** - @brief Finds out if a given entry exists in a dictionary - @param ini Dictionary to search - @param entry Name of the entry to look for - @return integer 1 if entry exists, 0 otherwise - - Finds out if a given entry exists in the dictionary. Since sections - are stored as keys with NULL associated values, this is the only way - of querying for the presence of sections in a dictionary. - */ -/*--------------------------------------------------------------------------*/ -int iniparser_find_entry(dictionary * ini, char * entry) ; - -/*-------------------------------------------------------------------------*/ -/** - @brief Parse an ini file and return an allocated dictionary object - @param ininame Name of the ini file to read. - @return Pointer to newly allocated dictionary - - This is the parser for ini files. This function is called, providing - the name of the file to be read. It returns a dictionary object that - should not be accessed directly, but through accessor functions - instead. - - The returned dictionary must be freed using iniparser_freedict(). - */ -/*--------------------------------------------------------------------------*/ -dictionary * iniparser_load(const char * ininame); - -/*-------------------------------------------------------------------------*/ -/** - @brief Free all memory associated to an ini dictionary - @param d Dictionary to free - @return void - - Free all memory associated to an ini dictionary. - It is mandatory to call this function before the dictionary object - gets out of the current context. - */ -/*--------------------------------------------------------------------------*/ -void iniparser_freedict(dictionary * d); - -#endif diff --git a/ubi-utils/include/libscan.h b/ubi-utils/include/libscan.h deleted file mode 100644 index a2b8657..0000000 --- a/ubi-utils/include/libscan.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * 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. - * - * Author: Artem Bityutskiy - * - * UBI scanning library. - */ - -#ifndef __LIBSCAN_H__ -#define __LIBSCAN_H__ - -#include <stdint.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * If an eraseblock does not contain an erase counter, this value is used - * instead of the erase counter. - */ -#define NO_EC 0xFFFFFFFF - -/* - * If an eraseblock contains a corrupted erase counter, this value is used - * instead of the erase counter. - */ -#define CORRUPT_EC 0xFFFFFFFE - -/* - * If an eraseblock does not contain an erase counter, one of these values is - * used. - * - * @EB_EMPTY: the eraseblock appeared to be empty - * @EB_CORRUPTED: the eraseblock contains corrupted erase counter header - * @EB_ALIEN: the eraseblock contains some non-UBI data - * @EC_MAX: maximum allowed erase counter value - */ -enum -{ - EB_EMPTY = 0xFFFFFFFF, - EB_CORRUPTED = 0xFFFFFFFE, - EB_ALIEN = 0xFFFFFFFD, - EB_BAD = 0xFFFFFFFC, - EC_MAX = UBI_MAX_ERASECOUNTER, -}; - -/** - * struct ubi_scan_info - UBI scanning information. - * @ec: erase counters or eraseblock status for all eraseblocks - * @mean_ec: mean erase counter - * @ok_cnt: count of eraseblock with correct erase counter header - * @empty_cnt: count of supposedly eraseblocks - * @corrupted_cnt: count of eraseblocks with corrupted erase counter header - * @alien_cnt: count of eraseblock containing non-ubi data - * @bad_cnt: count of bad eraseblocks - * @bad_cnt: count of non-bad eraseblocks - * @vid_hdr_offs: volume ID header offset from the found EC headers (%-1 means - * undefined) - * @data_offs: data offset from the found EC headers (%-1 means undefined) - */ -struct ubi_scan_info -{ - uint32_t *ec; - long long mean_ec; - int ok_cnt; - int empty_cnt; - int corrupted_cnt; - int alien_cnt; - int bad_cnt; - int good_cnt; - int vid_hdr_offs; - int data_offs; -}; - -struct mtd_dev_info; - -/** - * ubi_scan - scan an MTD device. - * @mtd: information about the MTD device to scan - * @fd: MTD device node file descriptor - * @info: the result of the scanning is returned here - * @verbose: verbose mode: %0 - be silent, %1 - output progress information, - * 2 - debugging output mode - */ -int ubi_scan(struct mtd_dev_info *mtd, int fd, struct ubi_scan_info **info, - int verbose); - -/** - * ubi_scan_free - free scanning information. - * @si: scanning information to free - */ -void ubi_scan_free(struct ubi_scan_info *si); - -#ifdef __cplusplus -} -#endif - -#endif /* __LIBSCAN_H__ */ diff --git a/ubi-utils/include/libubi.h b/ubi-utils/include/libubi.h deleted file mode 100644 index 4d6a7ee..0000000 --- a/ubi-utils/include/libubi.h +++ /dev/null @@ -1,485 +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. - * - * Author: Artem Bityutskiy - * - * UBI (Unsorted Block Images) library. - */ - -#ifndef __LIBUBI_H__ -#define __LIBUBI_H__ - -#include <ctype.h> -#include <stdint.h> -#include <mtd/ubi-user.h> -#include <mtd/ubi-media.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* UBI version libubi is made for */ -#define LIBUBI_UBI_VERSION 1 - -/* Maximum physical eraseblock size in bytes */ -#define UBI_MAX_PEB_SZ (2*1024*1024) - -/* UBI library descriptor */ -typedef void * libubi_t; - -/** - * struct ubi_attach_request - MTD device attachment request. - * @dev_num: number to assign to the newly created UBI device - * (%UBI_DEV_NUM_AUTO should be used to automatically assign the - * number) - * @mtd_num: MTD device number to attach (used if @mtd_dev_node is %NULL) - * @mtd_dev_node: path to MTD device node to attach - * @vid_hdr_offset: VID header offset (%0 means default offset and this is what - * most of the users want) - * @max_beb_per1024: Maximum expected bad eraseblocks per 1024 eraseblocks - */ -struct ubi_attach_request -{ - int dev_num; - int mtd_num; - const char *mtd_dev_node; - int vid_hdr_offset; - int max_beb_per1024; -}; - -/** - * struct ubi_mkvol_request - volume creation request. - * @vol_id: ID to assign to the new volume (%UBI_VOL_NUM_AUTO should be used to - * automatically assign ID) - * @alignment: volume alignment - * @bytes: volume size in bytes - * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) - * @name: volume name - */ -struct ubi_mkvol_request -{ - int vol_id; - int alignment; - long long bytes; - int vol_type; - const char *name; -}; - -/** - * struct ubi_info - general UBI information. - * @dev_count: count of UBI devices in system - * @lowest_dev_num: lowest UBI device number - * @highest_dev_num: highest UBI device number - * @version: UBI version - * @ctrl_major: major number of the UBI control device - * @ctrl_minor: minor number of the UBI control device - */ -struct ubi_info -{ - int dev_count; - int lowest_dev_num; - int highest_dev_num; - int version; - int ctrl_major; - int ctrl_minor; -}; - -/** - * struct ubi_dev_info - UBI device information. - * @dev_num: UBI device number - * @mtd_num: MTD device number on top of which this UBI device is working - * @vol_count: count of volumes on this UBI device - * @lowest_vol_id: lowest volume ID - * @highest_vol_id: highest volume ID - * @major: major number of corresponding character device - * @minor: minor number of corresponding character device - * @total_lebs: total number of logical eraseblocks on this UBI device - * @avail_lebs: how many logical eraseblocks are not used and available for new - * volumes - * @total_bytes: @total_lebs * @leb_size - * @avail_bytes: @avail_lebs * @leb_size - * @bad_count: count of bad physical eraseblocks - * @leb_size: logical eraseblock size - * @max_ec: current highest erase counter value - * @bad_rsvd: how many physical eraseblocks of the underlying flash device are - * reserved for bad eraseblocks handling - * @max_vol_count: maximum possible number of volumes on this UBI device - * @min_io_size: minimum input/output unit size of the UBI device - */ -struct ubi_dev_info -{ - int dev_num; - int mtd_num; - int vol_count; - int lowest_vol_id; - int highest_vol_id; - int major; - int minor; - int total_lebs; - int avail_lebs; - long long total_bytes; - long long avail_bytes; - int bad_count; - int leb_size; - long long max_ec; - int bad_rsvd; - int max_vol_count; - int min_io_size; -}; - -/** - * struct ubi_vol_info - UBI volume information. - * @dev_num: UBI device number the volume resides on - * @vol_id: ID of this volume - * @major: major number of corresponding volume character device - * @minor: minor number of corresponding volume character device - * @type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) - * @alignment: alignment of this volume - * @data_bytes: how many data bytes are stored on this volume (equivalent to - * @rsvd_bytes for dynamic volumes) - * @rsvd_bytes: how many bytes are reserved for this volume - * @rsvd_lebs: how many logical eraseblocks are reserved for this volume - * @leb_size: logical eraseblock size of this volume (may be less then - * device's logical eraseblock size due to alignment) - * @corrupted: non-zero if the volume is corrupted - * @name: volume name (null-terminated) - */ -struct ubi_vol_info -{ - int dev_num; - int vol_id; - int major; - int minor; - int type; - int alignment; - long long data_bytes; - long long rsvd_bytes; - int rsvd_lebs; - int leb_size; - int corrupted; - char name[UBI_VOL_NAME_MAX + 1]; -}; - -/** - * libubi_open - open UBI library. - * - * This function initializes and opens the UBI library and returns UBI library - * descriptor in case of success and %NULL in case of failure. In case of - * failure, errno contains the error code or zero if UBI is not present in the - * system. - */ -libubi_t libubi_open(void); - -/** - * libubi_close - close UBI library. - * @desc: UBI library descriptor - */ -void libubi_close(libubi_t desc); - -/** - * ubi_get_info - get general UBI information. - * @desc: UBI library descriptor - * @info: pointer to the &struct ubi_info object to fill - * - * This function fills the passed @info object with general UBI information and - * returns %0 in case of success and %-1 in case of failure. - */ -int ubi_get_info(libubi_t desc, struct ubi_info *info); - -/** - * mtd_num2ubi_dev - find UBI device by attached MTD device. - * @@desc: UBI library descriptor - * @mtd_num: MTD device number - * @dev_num: UBI device number is returned here - * - * This function finds UBI device to which MTD device @mtd_num is attached. - * Returns %0 if the UBI device was found and %-1 if not. - */ -int mtd_num2ubi_dev(libubi_t desc, int mtd_num, int *dev_num); - -/** - * ubi_attach - attach an MTD device by its node path or bt MTD device number - * @desc: UBI library descriptor - * @node: name of the UBI control character device node - * @req: MTD attach request - * - * This function creates new UBI device by attaching an MTD device described by - * @req. If @req->mtd_dev_node is given it should contain path to the MTD - * device node. Otherwise @req->mtd_num will be used. - * - * Returns %0 in case of success, %-1 in case of failure (errno is set) and %1 - * if parameter @req->max_beb_per1024 was ignored by kernel (because the kernel - * is old and does not support this feature, which was added in 3.7). The newly - * created UBI device number is returned in @req->dev_num. In the MTD device - * was specified by its device node path, the MTD device number is returned in - * @req->mtd_num. - */ -int ubi_attach(libubi_t desc, const char *node, struct ubi_attach_request *req); - -/** - * ubi_detach_mtd - detach an MTD device. - * @desc: UBI library descriptor - * @node: name of the UBI control character device node - * @mtd_num: MTD device number to detach - * - * This function detaches MTD device number @mtd_num from UBI, which means the - * corresponding UBI device is removed. Returns zero in case of success and %-1 - * in case of failure. - */ -int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num); - -/** - * ubi_detach - detach an MTD device by its node path. - * @desc: UBI library descriptor - * @node: name of the UBI control character device node - * @mtd_dev_node: path to an MTD device node - * - * This function detaches an MTD device @mtd_dev_node from UBI. Returns zero in - * case of success and %-1 in case of failure. - */ -int ubi_detach(libubi_t desc, const char *node, const char *mtd_dev_node); - -/** - * ubi_remove_dev - remove an UBI device. - * @desc: UBI library descriptor - * @node: name of the UBI control character device node - * @ubi_dev: UBI device number to remove - * - * This function removes UBI device number @ubi_dev and returns zero in case of - * success and %-1 in case of failure. - */ -int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev); - -/** - * ubi_mkvol - create an UBI volume. - * @desc: UBI library descriptor - * @node: name of the UBI character device to create a volume at - * @req: UBI volume creation request - * - * This function creates a UBI volume as described at @req and returns %0 in - * case of success and %-1 in case of failure. The assigned volume ID is - * returned in @req->vol_id. - */ -int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req); - -/** - * ubi_rmvol - remove a UBI volume. - * @desc: UBI library descriptor - * @node: name of the UBI character device to remove a volume from - * @vol_id: ID of the volume to remove - * - * This function removes volume @vol_id from UBI device @node and returns %0 in - * case of success and %-1 in case of failure. - */ -int ubi_rmvol(libubi_t desc, const char *node, int vol_id); - - -/** - * ubi_rnvols - rename UBI volumes. - * @desc: UBI library descriptor - * @node: name of the UBI character device to remove a volume from - * @rnvol: description of volumes to rename - * - * This function removes volume @vol_id from UBI device @node and returns %0 in - * case of success and %-1 in case of failure. - */ -int ubi_rnvols(libubi_t desc, const char *node, struct ubi_rnvol_req *rnvol); - -/** - * ubi_rsvol - re-size UBI volume. - * @desc: UBI library descriptor - * @node: name of the UBI character device owning the volume which should be - * re-sized - * @vol_id: volume ID to re-size - * @bytes: new volume size in bytes - * - * This function returns %0 in case of success and %-1 in case of error. - */ -int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes); - -/** - * ubi_probe_node - test UBI node. - * @desc: UBI library descriptor - * @node: the node to test - * - * This function tests whether @node is a UBI device or volume node and returns - * %1 if this is an UBI device node, %2 if this is a volume node, and %-1 if - * this is not an UBI device or volume node (errno is ENODEV in this case) or - * if an error occurred. - */ -int ubi_probe_node(libubi_t desc, const char *node); - -/** - * ubi_get_dev_info - get UBI device information. - * @desc: UBI library descriptor - * @node: name of the UBI character device to fetch information about - * @info: pointer to the &struct ubi_dev_info object to fill - * - * This function fills the passed @info object with UBI device information and - * returns %0 in case of success and %-1 in case of failure. If the UBI device - * corresponding to @node does not exist, errno is set to @ENODEV. - */ -int ubi_get_dev_info(libubi_t desc, const char *node, - struct ubi_dev_info *info); - -/** - * ubi_dev_present - check whether an UBI device is present. - * @desc: UBI library descriptor - * @dev_num: UBI device number to check - * - * This function returns %1 if UBI device is present and %0 if not. - */ -int ubi_dev_present(libubi_t desc, int dev_num); - -/** - * ubi_get_dev_info1 - get UBI device information. - * @desc: UBI library descriptor - * @dev_num: UBI device number to fetch information about - * @info: pointer to the &struct ubi_dev_info object to fill - * - * This function is identical to 'ubi_get_dev_info()' except that it accepts UBI - * device number, not UBI character device. If the UBI device @dev_num does not - * exist, errno is set to @ENODEV. - */ -int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info); - -/** - * ubi_get_vol_info - get UBI volume information. - * @desc: UBI library descriptor - * @node: name of the UBI volume character device to fetch information about - * @info: pointer to the &struct ubi_vol_info object to fill - * - * This function fills the passed @info object with UBI volume information and - * returns %0 in case of success and %-1 in case of failure. If the UBI volume - * corresponding to @node does not exist, errno is set to @ENODEV. - */ -int ubi_get_vol_info(libubi_t desc, const char *node, - struct ubi_vol_info *info); - -/** - * ubi_get_vol_info1 - get UBI volume information. - * @desc: UBI library descriptor - * @dev_num: UBI device number - * @vol_id: ID of the UBI volume to fetch information about - * @info: pointer to the &struct ubi_vol_info object to fill - * - * This function is identical to 'ubi_get_vol_info()' except that it accepts UBI - * volume ID, not UBI volume character device. If the UBI device @dev_num does - * not exist, or if the UBI volume @vol_id does not exist, errno is set to - * @ENODEV. - */ -int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id, - struct ubi_vol_info *info); - -/** - * ubi_get_vol_info1_nm - get UBI volume information by volume name. - * @desc: UBI library descriptor - * @dev_num: UBI device number - * @name: name of the UBI volume to fetch information about - * @info: pointer to the &struct ubi_vol_info object to fill - * - * This function is identical to 'ubi_get_vol_info()' except that it accepts UBI - * volume name, not UBI volume ID. If the UBI device @dev_num does not exist, - * or if the UBI volume @name does not exist, errno is set to @ENODEV. - */ -int ubi_get_vol_info1_nm(libubi_t desc, int dev_num, const char *name, - struct ubi_vol_info *info); - -/** - * ubi_vol_block_create - create a block device on top of an UBI volume. - * @fd: volume character device file descriptor - * - * Returns %0 in case of success and %-1 in case of failure. - */ -int ubi_vol_block_create(int fd); - -/** - * ubi_vol_block_remove - remove a block device from an UBI volume. - * @fd: volume character device file descriptor - * - * Returns %0 in case of success and %-1 in case of failure. - */ -int ubi_vol_block_remove(int fd); - -/** - * ubi_update_start - start UBI volume update. - * @desc: UBI library descriptor - * @fd: volume character device file descriptor - * @bytes: how many bytes will be written to the volume - * - * This function initiates UBI volume update and returns %0 in case of success - * and %-1 in case of error. The caller is assumed to write @bytes data to the - * volume @fd afterward. - */ -int ubi_update_start(libubi_t desc, int fd, long long bytes); - -/** - * ubi_leb_change_start - start atomic LEB change. - * @desc: UBI library descriptor - * @fd: volume character device file descriptor - * @lnum: LEB number to change - * @bytes: how many bytes of new data will be written to the LEB - * - * This function initiates atomic LEB change operation and returns %0 in case - * of success and %-1 in case of error. he caller is assumed to write @bytes - * data to the volume @fd afterward. - */ -int ubi_leb_change_start(libubi_t desc, int fd, int lnum, int bytes); - -/** - * ubi_set_property - set volume propety. - * @fd: volume character device file descriptor - * @property: the property to change (%UBI_VOL_PROP_DIRECT_WRITE, etc) - * @value: new value of the changed property - * - * This function changes a property of a volume. Returns zero in case of - * success and a negative error code in case of error. - */ -int ubi_set_property(int fd, uint8_t property, uint64_t value); - -/** - * ubi_leb_unmap - unmap a logical eraseblock. - * @fd: volume character device file descriptor - * @lnum: logical eraseblock to unmap - * - * This function unmaps LEB @lnum and returns zero in case of success and a - * negative error code in case of error. - */ -int ubi_leb_unmap(int fd, int lnum); - -/** - * ubi_is_mapped - check if logical eraseblock is mapped. - * @fd: volume character device file descriptor - * @lnum: logical eraseblock number - * - * This function checks if logical eraseblock @lnum is mapped to a physical - * eraseblock. If a logical eraseblock is un-mapped, this does not necessarily - * mean it will still be un-mapped after the UBI device is re-attached. The - * logical eraseblock may become mapped to the physical eraseblock it was last - * mapped to. - * - * This function returns %1 if the LEB is mapped, %0 if not, and %-1 in case of - * failure. If the volume is damaged because of an interrupted update errno - * set with %EBADF error code. - */ -int ubi_is_mapped(int fd, int lnum); - -#ifdef __cplusplus -} -#endif - -#endif /* !__LIBUBI_H__ */ diff --git a/ubi-utils/include/libubigen.h b/ubi-utils/include/libubigen.h deleted file mode 100644 index c25ac20..0000000 --- a/ubi-utils/include/libubigen.h +++ /dev/null @@ -1,195 +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. - */ - -/* - * Authors: Frank Haverkamp - * Artem Bityutskiy - */ - -#ifndef __LIBUBIGEN_H__ -#define __LIBUBIGEN_H__ - -#include <stdint.h> -#include <mtd/ubi-media.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * struct ubigen_info - libubigen information. - * @leb_size: logical eraseblock size - * @peb_size: size of the physical eraseblock - * @min_io_size: minimum input/output unit size - * @vid_hdr_offs: offset of the VID header - * @data_offs: data offset - * @ubi_ver: UBI version - * @vtbl_size: volume table size - * @max_volumes: maximum amount of volumes - * @image_seq: UBI image sequence number - */ -struct ubigen_info -{ - int leb_size; - int peb_size; - int min_io_size; - int vid_hdr_offs; - int data_offs; - int ubi_ver; - int vtbl_size; - int max_volumes; - uint32_t image_seq; -}; - -/** - * struct ubigen_vol_info - information about a volume. - * @id: volume id - * @type: volume type (%UBI_VID_DYNAMIC or %UBI_VID_STATIC) - * @alignment: volume alignment - * @data_pad: how many bytes are unused at the end of the each physical - * eraseblock to satisfy the requested alignment - * @usable_leb_size: LEB size accessible for volume users - * @name: volume name - * @name_len: volume name length - * @compat: compatibility of this volume (%0, %UBI_COMPAT_DELETE, - * %UBI_COMPAT_IGNORE, %UBI_COMPAT_PRESERVE, or %UBI_COMPAT_REJECT) - * @used_ebs: total number of used logical eraseblocks in this volume (relevant - * for static volumes only) - * @bytes: size of the volume contents in bytes (relevant for static volumes - * only) - * @flags: volume flags (%UBI_VTBL_AUTORESIZE_FLG) - */ -struct ubigen_vol_info -{ - int id; - int type; - int alignment; - int data_pad; - int usable_leb_size; - const char *name; - int name_len; - int compat; - int used_ebs; - long long bytes; - uint8_t flags; -}; - -/** - * ubigen_info_init - initialize libubigen. - * @ui: libubigen information - * @peb_size: flash physical eraseblock size - * @min_io_size: flash minimum input/output unit size - * @subpage_size: flash sub-page, if present (has to be equivalent to - * @min_io_size if does not exist) - * @vid_hdr_offs: offset of the VID header - * @ubi_ver: UBI version - * @image_seq: UBI image sequence number - */ -void ubigen_info_init(struct ubigen_info *ui, int peb_size, int min_io_size, - int subpage_size, int vid_hdr_offs, int ubi_ver, - uint32_t image_seq); - -/** - * ubigen_create_empty_vtbl - creates empty volume table. - * @ui: libubigen information - * - * This function creates an empty volume table and returns a pointer to it in - * case of success and %NULL in case of failure. The returned object has to be - * freed with 'free()' call. - */ -struct ubi_vtbl_record *ubigen_create_empty_vtbl(const struct ubigen_info *ui); - -/** - * ubigen_init_ec_hdr - initialize EC header. - * @ui: libubigen information - * @hdr: the EC header to initialize - * @ec: erase counter value - */ -void ubigen_init_ec_hdr(const struct ubigen_info *ui, - struct ubi_ec_hdr *hdr, long long ec); - -/** - * ubigen_init_vid_hdr - initialize VID header. - * @ui: libubigen information - * @vi: volume information - * @hdr: the VID header to initialize - * @lnum: logical eraseblock number - * @data: the contents of the LEB (static volumes only) - * @data_size: amount of data in this LEB (static volumes only) - * - * Note, @used_ebs, @data and @data_size are ignored in case of dynamic - * volumes. - */ -void ubigen_init_vid_hdr(const struct ubigen_info *ui, - const struct ubigen_vol_info *vi, - struct ubi_vid_hdr *hdr, int lnum, - const void *data, int data_size); - -/** - * ubigen_add_volume - add a volume to the volume table. - * @ui: libubigen information - * @vi: volume information - * @vtbl: volume table to add to - * - * This function adds volume described by input parameters to the volume table - * @vtbl. - */ -int ubigen_add_volume(const struct ubigen_info *ui, - const struct ubigen_vol_info *vi, - struct ubi_vtbl_record *vtbl); - -/** - * ubigen_write_volume - write UBI volume. - * @ui: libubigen information - * @vi: volume information - * @ec: erase counter value to put to EC headers - * @bytes: volume size in bytes - * @in: input file descriptor (has to be properly seeked) - * @out: output file descriptor - * - * This function reads the contents of the volume from the input file @in and - * writes the UBI volume to the output file @out. Returns zero on success and - * %-1 on failure. - */ -int ubigen_write_volume(const struct ubigen_info *ui, - const struct ubigen_vol_info *vi, long long ec, - long long bytes, int in, int out); - -/** - * ubigen_write_layout_vol - write UBI layout volume - * @ui: libubigen information - * @peb1: physical eraseblock number to write the first volume table copy - * @peb2: physical eraseblock number to write the second volume table copy - * @ec1: erase counter value for @peb1 - * @ec2: erase counter value for @peb1 - * @vtbl: volume table - * @fd: output file descriptor seeked to the proper position - * - * This function creates the UBI layout volume which contains 2 copies of the - * volume table. Returns zero in case of success and %-1 in case of failure. - */ -int ubigen_write_layout_vol(const struct ubigen_info *ui, int peb1, int peb2, - long long ec1, long long ec2, - struct ubi_vtbl_record *vtbl, int fd); - -#ifdef __cplusplus -} -#endif - -#endif /* !__LIBUBIGEN_H__ */ diff --git a/ubi-utils/libiniparser.c b/ubi-utils/libiniparser.c deleted file mode 100644 index 898f57f..0000000 --- a/ubi-utils/libiniparser.c +++ /dev/null @@ -1,646 +0,0 @@ - -/*-------------------------------------------------------------------------*/ -/** - @file iniparser.c - @author N. Devillard - @date Sep 2007 - @version 3.0 - @brief Parser for ini files. -*/ -/*--------------------------------------------------------------------------*/ -/* - $Id: iniparser.c,v 2.18 2008-01-03 18:35:39 ndevilla Exp $ - $Revision: 2.18 $ - $Date: 2008-01-03 18:35:39 $ -*/ -/*---------------------------- Includes ------------------------------------*/ -#include <ctype.h> -#include <libiniparser.h> - -/*---------------------------- Defines -------------------------------------*/ -#define ASCIILINESZ (1024) -#define INI_INVALID_KEY ((char*)-1) - -/*--------------------------------------------------------------------------- - Private to this module - ---------------------------------------------------------------------------*/ -/** - * This enum stores the status for each parsed line (internal use only). - */ -typedef enum _line_status_ { - LINE_UNPROCESSED, - LINE_ERROR, - LINE_EMPTY, - LINE_COMMENT, - LINE_SECTION, - LINE_VALUE -} line_status ; - -/*-------------------------------------------------------------------------*/ -/** - @brief Convert a string to lowercase. - @param s String to convert. - @return ptr to statically allocated string. - - This function returns a pointer to a statically allocated string - containing a lowercased version of the input string. Do not free - or modify the returned string! Since the returned string is statically - allocated, it will be modified at each function call (not re-entrant). - */ -/*--------------------------------------------------------------------------*/ -static char * strlwc(const char * s) -{ - static char l[ASCIILINESZ+1]; - int i ; - - if (s==NULL) return NULL ; - memset(l, 0, ASCIILINESZ+1); - i=0 ; - while (s[i] && i<ASCIILINESZ) { - l[i] = (char)tolower((int)s[i]); - i++ ; - } - l[ASCIILINESZ]=(char)0; - return l ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Remove blanks at the beginning and the end of a string. - @param s String to parse. - @return ptr to statically allocated string. - - This function returns a pointer to a statically allocated string, - which is identical to the input string, except that all blank - characters at the end and the beg. of the string have been removed. - Do not free or modify the returned string! Since the returned string - is statically allocated, it will be modified at each function call - (not re-entrant). - */ -/*--------------------------------------------------------------------------*/ -static char * strstrip(char * s) -{ - static char l[ASCIILINESZ+1]; - char * last ; - - if (s==NULL) return NULL ; - - while (isspace((int)*s) && *s) s++; - memset(l, 0, ASCIILINESZ+1); - strcpy(l, s); - last = l + strlen(l); - while (last > l) { - if (!isspace((int)*(last-1))) - break ; - last -- ; - } - *last = (char)0; - return (char*)l ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Get number of sections in a dictionary - @param d Dictionary to examine - @return int Number of sections found in dictionary - - This function returns the number of sections found in a dictionary. - The test to recognize sections is done on the string stored in the - dictionary: a section name is given as "section" whereas a key is - stored as "section:key", thus the test looks for entries that do not - contain a colon. - - This clearly fails in the case a section name contains a colon, but - this should simply be avoided. - - This function returns -1 in case of error. - */ -/*--------------------------------------------------------------------------*/ -int iniparser_getnsec(dictionary * d) -{ - int i ; - int nsec ; - - if (d==NULL) return -1 ; - nsec=0 ; - for (i=0 ; i<d->size ; i++) { - if (d->key[i]==NULL) - continue ; - if (strchr(d->key[i], ':')==NULL) { - nsec ++ ; - } - } - return nsec ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Get name for section n in a dictionary. - @param d Dictionary to examine - @param n Section number (from 0 to nsec-1). - @return Pointer to char string - - This function locates the n-th section in a dictionary and returns - its name as a pointer to a string statically allocated inside the - dictionary. Do not free or modify the returned string! - - This function returns NULL in case of error. - */ -/*--------------------------------------------------------------------------*/ -char * iniparser_getsecname(dictionary * d, int n) -{ - int i ; - int foundsec ; - - if (d==NULL || n<0) return NULL ; - foundsec=0 ; - for (i=0 ; i<d->size ; i++) { - if (d->key[i]==NULL) - continue ; - if (strchr(d->key[i], ':')==NULL) { - foundsec++ ; - if (foundsec>n) - break ; - } - } - if (foundsec<=n) { - return NULL ; - } - return d->key[i] ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Dump a dictionary to an opened file pointer. - @param d Dictionary to dump. - @param f Opened file pointer to dump to. - @return void - - This function prints out the contents of a dictionary, one element by - line, onto the provided file pointer. It is OK to specify @c stderr - or @c stdout as output files. This function is meant for debugging - purposes mostly. - */ -/*--------------------------------------------------------------------------*/ -void iniparser_dump(dictionary * d, FILE * f) -{ - int i ; - - if (d==NULL || f==NULL) return ; - for (i=0 ; i<d->size ; i++) { - if (d->key[i]==NULL) - continue ; - if (d->val[i]!=NULL) { - fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]); - } else { - fprintf(f, "[%s]=UNDEF\n", d->key[i]); - } - } - return ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Save a dictionary to a loadable ini file - @param d Dictionary to dump - @param f Opened file pointer to dump to - @return void - - This function dumps a given dictionary into a loadable ini file. - It is Ok to specify @c stderr or @c stdout as output files. - */ -/*--------------------------------------------------------------------------*/ -void iniparser_dump_ini(dictionary * d, FILE * f) -{ - int i, j ; - char keym[ASCIILINESZ+1]; - int nsec ; - char * secname ; - int seclen ; - - if (d==NULL || f==NULL) return ; - - nsec = iniparser_getnsec(d); - if (nsec<1) { - /* No section in file: dump all keys as they are */ - for (i=0 ; i<d->size ; i++) { - if (d->key[i]==NULL) - continue ; - fprintf(f, "%s = %s\n", d->key[i], d->val[i]); - } - return ; - } - for (i=0 ; i<nsec ; i++) { - secname = iniparser_getsecname(d, i) ; - seclen = (int)strlen(secname); - fprintf(f, "\n[%s]\n", secname); - sprintf(keym, "%s:", secname); - for (j=0 ; j<d->size ; j++) { - if (d->key[j]==NULL) - continue ; - if (!strncmp(d->key[j], keym, seclen+1)) { - fprintf(f, - "%-30s = %s\n", - d->key[j]+seclen+1, - d->val[j] ? d->val[j] : ""); - } - } - } - fprintf(f, "\n"); - return ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Get the string associated to a key - @param d Dictionary to search - @param key Key string to look for - @param def Default value to return if key not found. - @return pointer to statically allocated character string - - This function queries a dictionary for a key. A key as read from an - ini file is given as "section:key". If the key cannot be found, - the pointer passed as 'def' is returned. - The returned char pointer is pointing to a string allocated in - the dictionary, do not free or modify it. - */ -/*--------------------------------------------------------------------------*/ -char * iniparser_getstring(dictionary * d, const char * key, char * def) -{ - char * lc_key ; - char * sval ; - - if (d==NULL || key==NULL) - return def ; - - lc_key = strlwc(key); - sval = dictionary_get(d, lc_key, def); - return sval ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Get the string associated to a key, convert to an int - @param d Dictionary to search - @param key Key string to look for - @param notfound Value to return in case of error - @return integer - - This function queries a dictionary for a key. A key as read from an - ini file is given as "section:key". If the key cannot be found, - the notfound value is returned. - - Supported values for integers include the usual C notation - so decimal, octal (starting with 0) and hexadecimal (starting with 0x) - are supported. Examples: - - "42" -> 42 - "042" -> 34 (octal -> decimal) - "0x42" -> 66 (hexa -> decimal) - - Warning: the conversion may overflow in various ways. Conversion is - totally outsourced to strtol(), see the associated man page for overflow - handling. - - Credits: Thanks to A. Becker for suggesting strtol() - */ -/*--------------------------------------------------------------------------*/ -int iniparser_getint(dictionary * d, const char * key, int notfound) -{ - char * str ; - - str = iniparser_getstring(d, key, INI_INVALID_KEY); - if (str==INI_INVALID_KEY) return notfound ; - return (int)strtol(str, NULL, 0); -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Get the string associated to a key, convert to a double - @param d Dictionary to search - @param key Key string to look for - @param notfound Value to return in case of error - @return double - - This function queries a dictionary for a key. A key as read from an - ini file is given as "section:key". If the key cannot be found, - the notfound value is returned. - */ -/*--------------------------------------------------------------------------*/ -double iniparser_getdouble(dictionary * d, char * key, double notfound) -{ - char * str ; - - str = iniparser_getstring(d, key, INI_INVALID_KEY); - if (str==INI_INVALID_KEY) return notfound ; - return atof(str); -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Get the string associated to a key, convert to a boolean - @param d Dictionary to search - @param key Key string to look for - @param notfound Value to return in case of error - @return integer - - This function queries a dictionary for a key. A key as read from an - ini file is given as "section:key". If the key cannot be found, - the notfound value is returned. - - A true boolean is found if one of the following is matched: - - - A string starting with 'y' - - A string starting with 'Y' - - A string starting with 't' - - A string starting with 'T' - - A string starting with '1' - - A false boolean is found if one of the following is matched: - - - A string starting with 'n' - - A string starting with 'N' - - A string starting with 'f' - - A string starting with 'F' - - A string starting with '0' - - The notfound value returned if no boolean is identified, does not - necessarily have to be 0 or 1. - */ -/*--------------------------------------------------------------------------*/ -int iniparser_getboolean(dictionary * d, const char * key, int notfound) -{ - char * c ; - int ret ; - - c = iniparser_getstring(d, key, INI_INVALID_KEY); - if (c==INI_INVALID_KEY) return notfound ; - if (c[0]=='y' || c[0]=='Y' || c[0]=='1' || c[0]=='t' || c[0]=='T') { - ret = 1 ; - } else if (c[0]=='n' || c[0]=='N' || c[0]=='0' || c[0]=='f' || c[0]=='F') { - ret = 0 ; - } else { - ret = notfound ; - } - return ret; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Finds out if a given entry exists in a dictionary - @param ini Dictionary to search - @param entry Name of the entry to look for - @return integer 1 if entry exists, 0 otherwise - - Finds out if a given entry exists in the dictionary. Since sections - are stored as keys with NULL associated values, this is the only way - of querying for the presence of sections in a dictionary. - */ -/*--------------------------------------------------------------------------*/ -int iniparser_find_entry( - dictionary * ini, - char * entry -) -{ - int found=0 ; - if (iniparser_getstring(ini, entry, INI_INVALID_KEY)!=INI_INVALID_KEY) { - found = 1 ; - } - return found ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Set an entry in a dictionary. - @param ini Dictionary to modify. - @param entry Entry to modify (entry name) - @param val New value to associate to the entry. - @return int 0 if Ok, -1 otherwise. - - If the given entry can be found in the dictionary, it is modified to - contain the provided value. If it cannot be found, -1 is returned. - It is Ok to set val to NULL. - */ -/*--------------------------------------------------------------------------*/ -int iniparser_set(dictionary * ini, char * entry, char * val) -{ - return dictionary_set(ini, strlwc(entry), val) ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Delete an entry in a dictionary - @param ini Dictionary to modify - @param entry Entry to delete (entry name) - @return void - - If the given entry can be found, it is deleted from the dictionary. - */ -/*--------------------------------------------------------------------------*/ -void iniparser_unset(dictionary * ini, char * entry) -{ - dictionary_unset(ini, strlwc(entry)); -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Load a single line from an INI file - @param input_line Input line, may be concatenated multi-line input - @param section Output space to store section - @param key Output space to store key - @param value Output space to store value - @return line_status value - */ -/*--------------------------------------------------------------------------*/ -static line_status iniparser_line( - char * input_line, - char * section, - char * key, - char * value) -{ - line_status sta ; - char line[ASCIILINESZ+1]; - int len ; - - strcpy(line, strstrip(input_line)); - len = (int)strlen(line); - - sta = LINE_UNPROCESSED ; - if (len<1) { - /* Empty line */ - sta = LINE_EMPTY ; - } else if (line[0]=='#') { - /* Comment line */ - sta = LINE_COMMENT ; - } else if (line[0]=='[' && line[len-1]==']') { - /* Section name */ - sscanf(line, "[%[^]]", section); - strcpy(section, strstrip(section)); - strcpy(section, strlwc(section)); - sta = LINE_SECTION ; - } else if (sscanf (line, "%[^=] = \"%[^\"]\"", key, value) == 2 - || sscanf (line, "%[^=] = '%[^\']'", key, value) == 2 - || sscanf (line, "%[^=] = %[^;#]", key, value) == 2) { - /* Usual key=value, with or without comments */ - strcpy(key, strstrip(key)); - strcpy(key, strlwc(key)); - strcpy(value, strstrip(value)); - /* - * sscanf cannot handle '' or "" as empty values - * this is done here - */ - if (!strcmp(value, "\"\"") || (!strcmp(value, "''"))) { - value[0]=0 ; - } - sta = LINE_VALUE ; - } else if (sscanf(line, "%[^=] = %[;#]", key, value)==2 - || sscanf(line, "%[^=] %[=]", key, value) == 2) { - /* - * Special cases: - * key= - * key=; - * key=# - */ - strcpy(key, strstrip(key)); - strcpy(key, strlwc(key)); - value[0]=0 ; - sta = LINE_VALUE ; - } else { - /* Generate syntax error */ - sta = LINE_ERROR ; - } - return sta ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Parse an ini file and return an allocated dictionary object - @param ininame Name of the ini file to read. - @return Pointer to newly allocated dictionary - - This is the parser for ini files. This function is called, providing - the name of the file to be read. It returns a dictionary object that - should not be accessed directly, but through accessor functions - instead. - - The returned dictionary must be freed using iniparser_freedict(). - */ -/*--------------------------------------------------------------------------*/ -dictionary * iniparser_load(const char * ininame) -{ - FILE * in ; - - char line [ASCIILINESZ+1] ; - char section [ASCIILINESZ+1] ; - char key [ASCIILINESZ+1] ; - char tmp [ASCIILINESZ+1] ; - char val [ASCIILINESZ+1] ; - - int last=0 ; - int len ; - int lineno=0 ; - int errs=0; - - dictionary * dict ; - - if ((in=fopen(ininame, "r"))==NULL) { - fprintf(stderr, "iniparser: cannot open %s\n", ininame); - return NULL ; - } - - dict = dictionary_new(0) ; - if (!dict) { - fclose(in); - return NULL ; - } - - memset(line, 0, ASCIILINESZ); - memset(section, 0, ASCIILINESZ); - memset(key, 0, ASCIILINESZ); - memset(val, 0, ASCIILINESZ); - last=0 ; - - while (fgets(line+last, ASCIILINESZ-last, in)!=NULL) { - lineno++ ; - len = (int)strlen(line)-1; - /* Safety check against buffer overflows */ - if (line[len]!='\n') { - fprintf(stderr, - "iniparser: input line too long in %s (%d)\n", - ininame, - lineno); - dictionary_del(dict); - fclose(in); - return NULL ; - } - /* Get rid of \n and spaces at end of line */ - while ((len>=0) && - ((line[len]=='\n') || (isspace(line[len])))) { - line[len]=0 ; - len-- ; - } - /* Detect multi-line */ - if (line[len]=='\\') { - /* Multi-line value */ - last=len ; - continue ; - } else { - last=0 ; - } - switch (iniparser_line(line, section, key, val)) { - case LINE_EMPTY: - case LINE_COMMENT: - break ; - - case LINE_SECTION: - errs = dictionary_set(dict, section, NULL); - break ; - - case LINE_VALUE: - sprintf(tmp, "%s:%s", section, key); - errs = dictionary_set(dict, tmp, val) ; - break ; - - case LINE_ERROR: - fprintf(stderr, "iniparser: syntax error in %s (%d):\n", - ininame, - lineno); - fprintf(stderr, "-> %s\n", line); - errs++ ; - break; - - default: - break ; - } - memset(line, 0, ASCIILINESZ); - last=0; - if (errs<0) { - fprintf(stderr, "iniparser: memory allocation failure\n"); - break ; - } - } - if (errs) { - dictionary_del(dict); - dict = NULL ; - } - fclose(in); - return dict ; -} - -/*-------------------------------------------------------------------------*/ -/** - @brief Free all memory associated to an ini dictionary - @param d Dictionary to free - @return void - - Free all memory associated to an ini dictionary. - It is mandatory to call this function before the dictionary object - gets out of the current context. - */ -/*--------------------------------------------------------------------------*/ -void iniparser_freedict(dictionary * d) -{ - dictionary_del(d); -} - -/* vim: set ts=4 et sw=4 tw=75 */ diff --git a/ubi-utils/libscan.c b/ubi-utils/libscan.c deleted file mode 100644 index dc47a89..0000000 --- a/ubi-utils/libscan.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * 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. - * - * Author: Artem Bityutskiy - * - * UBI scanning library. - */ - -#define PROGRAM_NAME "libscan" - -#include <sys/types.h> -#include <sys/stat.h> -#include <stdint.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdlib.h> - -#include <mtd_swab.h> -#include <mtd/ubi-media.h> -#include <mtd/mtd-user.h> -#include <libmtd.h> -#include <libscan.h> -#include <crc32.h> -#include "common.h" - -static int all_ff(const void *buf, int len) -{ - int i; - const uint8_t *p = buf; - - for (i = 0; i < len; i++) - if (p[i] != 0xFF) - return 0; - return 1; -} - -int ubi_scan(struct mtd_dev_info *mtd, int fd, struct ubi_scan_info **info, - int verbose) -{ - int eb, v = (verbose == 2), pr = (verbose == 1); - struct ubi_scan_info *si; - unsigned long long sum = 0; - - si = calloc(1, sizeof(struct ubi_scan_info)); - if (!si) - return sys_errmsg("cannot allocate %zd bytes of memory", - sizeof(struct ubi_scan_info)); - - si->ec = calloc(mtd->eb_cnt, sizeof(uint32_t)); - if (!si->ec) { - sys_errmsg("cannot allocate %zd bytes of memory", - sizeof(struct ubi_scan_info)); - goto out_si; - } - - si->vid_hdr_offs = si->data_offs = -1; - - verbose(v, "start scanning eraseblocks 0-%d", mtd->eb_cnt); - for (eb = 0; eb < mtd->eb_cnt; eb++) { - int ret; - uint32_t crc; - struct ubi_ec_hdr ech; - unsigned long long ec; - - if (v) { - normsg_cont("scanning eraseblock %d", eb); - fflush(stdout); - } - if (pr) { - printf("\r" PROGRAM_NAME ": scanning eraseblock %d -- %2lld %% complete ", - eb, (long long)(eb + 1) * 100 / mtd->eb_cnt); - fflush(stdout); - } - - ret = mtd_is_bad(mtd, fd, eb); - if (ret == -1) - goto out_ec; - if (ret) { - si->bad_cnt += 1; - si->ec[eb] = EB_BAD; - if (v) - printf(": bad\n"); - continue; - } - - ret = mtd_read(mtd, fd, eb, 0, &ech, sizeof(struct ubi_ec_hdr)); - if (ret < 0) - goto out_ec; - - if (be32_to_cpu(ech.magic) != UBI_EC_HDR_MAGIC) { - if (all_ff(&ech, sizeof(struct ubi_ec_hdr))) { - si->empty_cnt += 1; - si->ec[eb] = EB_EMPTY; - if (v) - printf(": empty\n"); - } else { - si->alien_cnt += 1; - si->ec[eb] = EB_ALIEN; - if (v) - printf(": alien\n"); - } - continue; - } - - crc = mtd_crc32(UBI_CRC32_INIT, &ech, UBI_EC_HDR_SIZE_CRC); - if (be32_to_cpu(ech.hdr_crc) != crc) { - si->corrupted_cnt += 1; - si->ec[eb] = EB_CORRUPTED; - if (v) - printf(": bad CRC %#08x, should be %#08x\n", - crc, be32_to_cpu(ech.hdr_crc)); - continue; - } - - ec = be64_to_cpu(ech.ec); - if (ec > EC_MAX) { - if (pr) - printf("\n"); - errmsg("erase counter in EB %d is %llu, while this " - "program expects them to be less than %u", - eb, ec, EC_MAX); - goto out_ec; - } - - if (si->vid_hdr_offs == -1) { - si->vid_hdr_offs = be32_to_cpu(ech.vid_hdr_offset); - si->data_offs = be32_to_cpu(ech.data_offset); - if (si->data_offs % mtd->min_io_size) { - if (pr) - printf("\n"); - if (v) - printf(": corrupted because of the below\n"); - warnmsg("bad data offset %d at eraseblock %d (n" - "of multiple of min. I/O unit size %d)", - si->data_offs, eb, mtd->min_io_size); - warnmsg("treat eraseblock %d as corrupted", eb); - si->corrupted_cnt += 1; - si->ec[eb] = EB_CORRUPTED; - continue; - - } - } else { - if ((int)be32_to_cpu(ech.vid_hdr_offset) != si->vid_hdr_offs) { - if (pr) - printf("\n"); - if (v) - printf(": corrupted because of the below\n"); - warnmsg("inconsistent VID header offset: was " - "%d, but is %d in eraseblock %d", - si->vid_hdr_offs, - be32_to_cpu(ech.vid_hdr_offset), eb); - warnmsg("treat eraseblock %d as corrupted", eb); - si->corrupted_cnt += 1; - si->ec[eb] = EB_CORRUPTED; - continue; - } - if ((int)be32_to_cpu(ech.data_offset) != si->data_offs) { - if (pr) - printf("\n"); - if (v) - printf(": corrupted because of the below\n"); - warnmsg("inconsistent data offset: was %d, but" - " is %d in eraseblock %d", - si->data_offs, - be32_to_cpu(ech.data_offset), eb); - warnmsg("treat eraseblock %d as corrupted", eb); - si->corrupted_cnt += 1; - si->ec[eb] = EB_CORRUPTED; - continue; - } - } - - si->ok_cnt += 1; - si->ec[eb] = ec; - if (v) - printf(": OK, erase counter %u\n", si->ec[eb]); - } - - if (si->ok_cnt != 0) { - /* Calculate mean erase counter */ - for (eb = 0; eb < mtd->eb_cnt; eb++) { - if (si->ec[eb] > EC_MAX) - continue; - sum += si->ec[eb]; - } - si->mean_ec = sum / si->ok_cnt; - } - - si->good_cnt = mtd->eb_cnt - si->bad_cnt; - verbose(v, "finished, mean EC %lld, %d OK, %d corrupted, %d empty, %d " - "alien, bad %d", si->mean_ec, si->ok_cnt, si->corrupted_cnt, - si->empty_cnt, si->alien_cnt, si->bad_cnt); - - *info = si; - if (pr) - printf("\n"); - return 0; - -out_ec: - free(si->ec); -out_si: - free(si); - *info = NULL; - return -1; -} - -void ubi_scan_free(struct ubi_scan_info *si) -{ - free(si->ec); - free(si); -} diff --git a/ubi-utils/libubi.c b/ubi-utils/libubi.c deleted file mode 100644 index 758d351..0000000 --- a/ubi-utils/libubi.c +++ /dev/null @@ -1,1391 +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. - * - * Author: Artem Bityutskiy - * - * UBI (Unsorted Block Images) library. - */ - -#define PROGRAM_NAME "libubi" - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <dirent.h> -#include <unistd.h> -#include <limits.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <libubi.h> -#include "libubi_int.h" -#include "common.h" - -/** - * mkpath - compose full path from 2 given components. - * @path: the first component - * @name: the second component - * - * This function returns the resulting path in case of success and %NULL in - * case of failure. - */ -static char *mkpath(const char *path, const char *name) -{ - char *n; - int len1 = strlen(path); - int len2 = strlen(name); - - n = malloc(len1 + len2 + 2); - if (!n) { - sys_errmsg("cannot allocate %d bytes", len1 + len2 + 2); - return NULL; - } - - memcpy(n, path, len1); - if (n[len1 - 1] != '/') - n[len1++] = '/'; - - memcpy(n + len1, name, len2 + 1); - return n; -} - -/** - * read_positive_ll - read a positive 'long long' value from a file. - * @file: the file to read from - * @value: the result is stored here - * - * This function reads file @file and interprets its contents as a positive - * 'long long' integer. If this is not true, it fails with %EINVAL error code. - * Returns %0 in case of success and %-1 in case of failure. - */ -static int read_positive_ll(const char *file, long long *value) -{ - int fd, rd; - char buf[50]; - - fd = open(file, O_RDONLY); - if (fd == -1) - return -1; - - rd = read(fd, buf, sizeof(buf)); - if (rd == -1) { - sys_errmsg("cannot read \"%s\"", file); - goto out_error; - } - if (rd == sizeof(buf)) { - errmsg("contents of \"%s\" is too long", file); - errno = EINVAL; - goto out_error; - } - buf[rd] = '\0'; - - if (sscanf(buf, "%lld\n", value) != 1) { - errmsg("cannot read integer from \"%s\"\n", file); - errno = EINVAL; - goto out_error; - } - - if (*value < 0) { - errmsg("negative value %lld in \"%s\"", *value, file); - errno = EINVAL; - goto out_error; - } - - if (close(fd)) - return sys_errmsg("close failed on \"%s\"", file); - - return 0; - -out_error: - close(fd); - return -1; -} - -/** - * read_positive_int - read a positive 'int' value from a file. - * @file: the file to read from - * @value: the result is stored here - * - * This function is the same as 'read_positive_ll()', but it reads an 'int' - * value, not 'long long'. - */ -static int read_positive_int(const char *file, int *value) -{ - long long res; - - if (read_positive_ll(file, &res)) - return -1; - - /* Make sure the value is not too big */ - if (res > INT_MAX) { - errmsg("value %lld read from file \"%s\" is out of range", - res, file); - errno = EINVAL; - return -1; - } - - *value = res; - return 0; -} - -/** - * read_data - read data from a file. - * @file: the file to read from - * @buf: the buffer to read to - * @buf_len: buffer length - * - * This function returns number of read bytes in case of success and %-1 in - * case of failure. Note, if the file contains more then @buf_len bytes of - * date, this function fails with %EINVAL error code. - */ -static int read_data(const char *file, void *buf, int buf_len) -{ - int fd, rd, tmp, tmp1; - - fd = open(file, O_RDONLY); - if (fd == -1) - return -1; - - rd = read(fd, buf, buf_len); - if (rd == -1) { - sys_errmsg("cannot read \"%s\"", file); - goto out_error; - } - - if (rd == buf_len) { - errmsg("contents of \"%s\" is too long", file); - errno = EINVAL; - goto out_error; - } - - ((char *)buf)[rd] = '\0'; - - /* Make sure all data is read */ - tmp1 = read(fd, &tmp, 1); - if (tmp1 == 1) { - sys_errmsg("cannot read \"%s\"", file); - goto out_error; - } - if (tmp1) { - errmsg("file \"%s\" contains too much data (> %d bytes)", - file, buf_len); - errno = EINVAL; - goto out_error; - } - - if (close(fd)) - return sys_errmsg("close failed on \"%s\"", file); - - return rd; - -out_error: - close(fd); - return -1; -} - -/** - * read_major - read major and minor numbers from a file. - * @file: name of the file to read from - * @major: major number is returned here - * @minor: minor number is returned here - * - * This function returns % in case of succes, and %-1 in case of failure. - */ -static int read_major(const char *file, int *major, int *minor) -{ - int ret; - char buf[50]; - - ret = read_data(file, buf, 50); - if (ret < 0) - return ret; - - ret = sscanf(buf, "%d:%d\n", major, minor); - if (ret != 2) { - errno = EINVAL; - return errmsg("\"%s\" does not have major:minor format", file); - } - - if (*major < 0 || *minor < 0) { - errno = EINVAL; - return errmsg("bad major:minor %d:%d in \"%s\"", - *major, *minor, file); - } - - return 0; -} - -/** - * dev_read_int - read a positive 'int' value from an UBI device sysfs file. - * @patt: file pattern to read from - * @dev_num: UBI device number - * @value: the result is stored here - * - * This function returns %0 in case of success and %-1 in case of failure. - */ -static int dev_read_int(const char *patt, int dev_num, int *value) -{ - char file[strlen(patt) + 50]; - - sprintf(file, patt, dev_num); - return read_positive_int(file, value); -} - -/** - * vol_read_int - read a positive 'int' value from an UBI volume sysfs file. - * @patt: file pattern to read from - * @dev_num: UBI device number - * @vol_id: volume ID - * @value: the result is stored here - * - * This function returns %0 in case of success and %-1 in case of failure. - */ -static int vol_read_int(const char *patt, int dev_num, int vol_id, int *value) -{ - char file[strlen(patt) + 100]; - - sprintf(file, patt, dev_num, vol_id); - return read_positive_int(file, value); -} - -/** - * dev_read_ll - read a positive 'long long' value from an UBI device sysfs file. - * @patt: file pattern to read from - * @dev_num: UBI device number - * @value: the result is stored here - * - * This function returns %0 in case of success and %-1 in case of failure. - */ -static int dev_read_ll(const char *patt, int dev_num, long long *value) -{ - char file[strlen(patt) + 50]; - - sprintf(file, patt, dev_num); - return read_positive_ll(file, value); -} - -/** - * vol_read_ll - read a positive 'long long' value from an UBI volume sysfs file. - * @patt: file pattern to read from - * @dev_num: UBI device number - * @vol_id: volume ID - * @value: the result is stored here - * - * This function returns %0 in case of success and %-1 in case of failure. - */ -static int vol_read_ll(const char *patt, int dev_num, int vol_id, - long long *value) -{ - char file[strlen(patt) + 100]; - - sprintf(file, patt, dev_num, vol_id); - return read_positive_ll(file, value); -} - -/** - * vol_read_data - read data from an UBI volume's sysfs file. - * @patt: file pattern to read from - * @dev_num: UBI device number - * @vol_id: volume ID - * @buf: buffer to read to - * @buf_len: buffer length - * - * This function returns number of read bytes in case of success and %-1 in - * case of failure. - */ -static int vol_read_data(const char *patt, int dev_num, int vol_id, void *buf, - int buf_len) -{ - char file[strlen(patt) + 100]; - - sprintf(file, patt, dev_num, vol_id); - return read_data(file, buf, buf_len); -} - -/** - * dev_get_major - get major and minor numbers of an UBI device. - * @lib: libubi descriptor - * @dev_num: UBI device number - * @major: major number is returned here - * @minor: minor number is returned here - * - * This function returns zero in case of succes and %-1 in case of failure. - */ -static int dev_get_major(struct libubi *lib, int dev_num, int *major, int *minor) -{ - char file[strlen(lib->dev_dev) + 50]; - - sprintf(file, lib->dev_dev, dev_num); - return read_major(file, major, minor); -} - -/** - * vol_get_major - get major and minor numbers of an UBI volume. - * @lib: libubi descriptor - * @dev_num: UBI device number - * @vol_id: volume ID - * @major: major number is returned here - * @minor: minor number is returned here - * - * This function returns zero in case of succes and %-1 in case of failure. - */ -static int vol_get_major(struct libubi *lib, int dev_num, int vol_id, - int *major, int *minor) -{ - char file[strlen(lib->vol_dev) + 100]; - - sprintf(file, lib->vol_dev, dev_num, vol_id); - return read_major(file, major, minor); -} - -/** - * vol_node2nums - find UBI device number and volume ID by volume device node - * file. - * @lib: UBI library descriptor - * @node: UBI character device node name - * @dev_num: UBI device number is returned here - * @vol_id: volume ID is returned hers - * - * This function returns zero in case of succes and %-1 in case of failure. - */ -static int vol_node2nums(struct libubi *lib, const char *node, int *dev_num, - int *vol_id) -{ - struct stat st; - struct ubi_info info; - int i, fd, major, minor; - char file[strlen(lib->ubi_vol) + 100]; - - if (stat(node, &st)) - return sys_errmsg("cannot get information about \"%s\"", - node); - - if (!S_ISCHR(st.st_mode)) { - errno = EINVAL; - return errmsg("\"%s\" is not a character device", node); - } - - major = major(st.st_rdev); - minor = minor(st.st_rdev); - - if (minor == 0) { - errno = EINVAL; - return errmsg("\"%s\" is not a volume character device", node); - } - - if (ubi_get_info((libubi_t *)lib, &info)) - return -1; - - for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { - int major1, minor1, ret; - - ret = dev_get_major(lib, i, &major1, &minor1); - if (ret) { - if (errno == ENOENT) - continue; - return -1; - } - - if (major1 == major) - break; - } - - if (i > info.highest_dev_num) { - errno = ENODEV; - return -1; - } - - /* Make sure this UBI volume exists */ - sprintf(file, lib->ubi_vol, i, minor - 1); - fd = open(file, O_RDONLY); - if (fd == -1) { - errno = ENODEV; - return -1; - } - - if (close(fd)) - return sys_errmsg("close failed on \"%s\"", file); - - *dev_num = i; - *vol_id = minor - 1; - errno = 0; - return 0; -} - -/** - * dev_node2num - find UBI device number by its character device node. - * @lib: UBI library descriptor - * @node: UBI character device node name - * @dev_num: UBI device number is returned here - * - * This function returns %0 in case of success and %-1 in case of failure. - */ -static int dev_node2num(struct libubi *lib, const char *node, int *dev_num) -{ - struct stat st; - struct ubi_info info; - int i, major, minor; - - if (stat(node, &st)) - return sys_errmsg("cannot get information about \"%s\"", node); - - if (!S_ISCHR(st.st_mode)) { - errno = EINVAL; - return errmsg("\"%s\" is not a character device", node); - } - - major = major(st.st_rdev); - minor = minor(st.st_rdev); - - if (minor != 0) { - errno = EINVAL; - return errmsg("\"%s\" is not an UBI character device", node); - } - - if (ubi_get_info((libubi_t *)lib, &info)) - return -1; - - for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { - int major1, minor1, ret; - - ret = dev_get_major(lib, i, &major1, &minor1); - if (ret) { - if (errno == ENOENT) - continue; - return -1; - } - - if (major1 == major) { - if (minor1 != 0) { - errmsg("UBI character device minor number is " - "%d, but must be 0", minor1); - errno = EINVAL; - return -1; - } - errno = 0; - *dev_num = i; - return 0; - } - } - - errno = ENODEV; - return -1; -} - -int mtd_num2ubi_dev(libubi_t desc, int mtd_num, int *dev_num) -{ - struct ubi_info info; - int i, ret, mtd_num1; - struct libubi *lib = desc; - - if (ubi_get_info(desc, &info)) - return -1; - - for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { - ret = dev_read_int(lib->dev_mtd_num, i, &mtd_num1); - if (ret) { - if (errno == ENOENT) - continue; - return -1; - } - - if (mtd_num1 == mtd_num) { - errno = 0; - *dev_num = i; - return 0; - } - } - - errno = 0; - return -1; -} - -libubi_t libubi_open(void) -{ - int fd, version; - struct libubi *lib; - - lib = calloc(1, sizeof(struct libubi)); - if (!lib) - return NULL; - - lib->sysfs_ctrl = mkpath(SYSFS_ROOT, SYSFS_CTRL); - if (!lib->sysfs_ctrl) - goto out_error; - - lib->ctrl_dev = mkpath(lib->sysfs_ctrl, CTRL_DEV); - if (!lib->ctrl_dev) - goto out_error; - - lib->sysfs_ubi = mkpath(SYSFS_ROOT, SYSFS_UBI); - if (!lib->sysfs_ubi) - goto out_error; - - /* Make sure UBI is present */ - fd = open(lib->sysfs_ubi, O_RDONLY); - if (fd == -1) { - errno = 0; - goto out_error; - } - - if (close(fd)) { - sys_errmsg("close failed on \"%s\"", lib->sysfs_ubi); - goto out_error; - } - - lib->ubi_dev = mkpath(lib->sysfs_ubi, UBI_DEV_NAME_PATT); - if (!lib->ubi_dev) - goto out_error; - - lib->ubi_version = mkpath(lib->sysfs_ubi, UBI_VER); - if (!lib->ubi_version) - goto out_error; - - lib->dev_dev = mkpath(lib->ubi_dev, DEV_DEV); - if (!lib->dev_dev) - goto out_error; - - lib->dev_avail_ebs = mkpath(lib->ubi_dev, DEV_AVAIL_EBS); - if (!lib->dev_avail_ebs) - goto out_error; - - lib->dev_total_ebs = mkpath(lib->ubi_dev, DEV_TOTAL_EBS); - if (!lib->dev_total_ebs) - goto out_error; - - lib->dev_bad_count = mkpath(lib->ubi_dev, DEV_BAD_COUNT); - if (!lib->dev_bad_count) - goto out_error; - - lib->dev_eb_size = mkpath(lib->ubi_dev, DEV_EB_SIZE); - if (!lib->dev_eb_size) - goto out_error; - - lib->dev_max_ec = mkpath(lib->ubi_dev, DEV_MAX_EC); - if (!lib->dev_max_ec) - goto out_error; - - lib->dev_bad_rsvd = mkpath(lib->ubi_dev, DEV_MAX_RSVD); - if (!lib->dev_bad_rsvd) - goto out_error; - - lib->dev_max_vols = mkpath(lib->ubi_dev, DEV_MAX_VOLS); - if (!lib->dev_max_vols) - goto out_error; - - lib->dev_min_io_size = mkpath(lib->ubi_dev, DEV_MIN_IO_SIZE); - if (!lib->dev_min_io_size) - goto out_error; - - lib->dev_mtd_num = mkpath(lib->ubi_dev, DEV_MTD_NUM); - if (!lib->dev_mtd_num) - goto out_error; - - lib->ubi_vol = mkpath(lib->sysfs_ubi, UBI_VOL_NAME_PATT); - if (!lib->ubi_vol) - goto out_error; - - lib->vol_type = mkpath(lib->ubi_vol, VOL_TYPE); - if (!lib->vol_type) - goto out_error; - - lib->vol_dev = mkpath(lib->ubi_vol, VOL_DEV); - if (!lib->vol_dev) - goto out_error; - - lib->vol_alignment = mkpath(lib->ubi_vol, VOL_ALIGNMENT); - if (!lib->vol_alignment) - goto out_error; - - lib->vol_data_bytes = mkpath(lib->ubi_vol, VOL_DATA_BYTES); - if (!lib->vol_data_bytes) - goto out_error; - - lib->vol_rsvd_ebs = mkpath(lib->ubi_vol, VOL_RSVD_EBS); - if (!lib->vol_rsvd_ebs) - goto out_error; - - lib->vol_eb_size = mkpath(lib->ubi_vol, VOL_EB_SIZE); - if (!lib->vol_eb_size) - goto out_error; - - lib->vol_corrupted = mkpath(lib->ubi_vol, VOL_CORRUPTED); - if (!lib->vol_corrupted) - goto out_error; - - lib->vol_name = mkpath(lib->ubi_vol, VOL_NAME); - if (!lib->vol_name) - goto out_error; - - if (read_positive_int(lib->ubi_version, &version)) - goto out_error; - if (version != LIBUBI_UBI_VERSION) { - errmsg("this library was made for UBI version %d, but UBI " - "version %d is detected\n", LIBUBI_UBI_VERSION, version); - goto out_error; - } - - return lib; - -out_error: - libubi_close((libubi_t)lib); - return NULL; -} - -void libubi_close(libubi_t desc) -{ - struct libubi *lib = (struct libubi *)desc; - - free(lib->vol_name); - free(lib->vol_corrupted); - free(lib->vol_eb_size); - free(lib->vol_rsvd_ebs); - free(lib->vol_data_bytes); - free(lib->vol_alignment); - free(lib->vol_dev); - free(lib->vol_type); - free(lib->ubi_vol); - free(lib->dev_mtd_num); - free(lib->dev_min_io_size); - free(lib->dev_max_vols); - free(lib->dev_bad_rsvd); - free(lib->dev_max_ec); - free(lib->dev_eb_size); - free(lib->dev_bad_count); - free(lib->dev_total_ebs); - free(lib->dev_avail_ebs); - free(lib->dev_dev); - free(lib->ubi_version); - free(lib->ubi_dev); - free(lib->sysfs_ubi); - free(lib->ctrl_dev); - free(lib->sysfs_ctrl); - free(lib); -} - -/** - * do_attach - perform the actual attach operation. - * @node: name of the UBI control character device node - * @r: attach request - * - * This function performs the actual UBI attach operation. Returns %0 in case of - * success and %-1 in case of failure. @r->ubi_num contains newly created UBI - * device number. - */ -static int do_attach(const char *node, const struct ubi_attach_req *r) -{ - int fd, ret; - - fd = open(node, O_RDONLY); - if (fd == -1) - return sys_errmsg("cannot open \"%s\"", node); - - ret = ioctl(fd, UBI_IOCATT, r); - close(fd); - if (ret == -1) - return -1; - -#ifdef UDEV_SETTLE_HACK -// if (system("udevsettle") == -1) -// return -1; - usleep(100000); -#endif - return ret; -} - -#ifndef MTD_CHAR_MAJOR -/* - * This is taken from kernel <linux/mtd/mtd.h> and is unlikely to change anytime - * soon. - */ -#define MTD_CHAR_MAJOR 90 -#endif - -/** - * mtd_node_to_num - converts device node to MTD number. - * @mtd_dev_node: path to device node to convert - * - * This function converts given @mtd_dev_node to MTD device number. - * @mtd_dev_node should contain path to the MTD device node. Returns MTD device - * number in case of success and %-1 in case of failure (errno is set). - */ -static int mtd_node_to_num(const char *mtd_dev_node) -{ - int major, minor; - struct stat sb; - - if (stat(mtd_dev_node, &sb) < 0) - return sys_errmsg("cannot stat \"%s\"", mtd_dev_node); - - if (!S_ISCHR(sb.st_mode)) { - errno = EINVAL; - return sys_errmsg("\"%s\" is not a character device", - mtd_dev_node); - } - - major = major(sb.st_rdev); - minor = minor(sb.st_rdev); - - if (major != MTD_CHAR_MAJOR) { - errno = EINVAL; - return sys_errmsg("\"%s\" is not an MTD device", mtd_dev_node); - } - - return minor / 2; -} - -int ubi_attach(libubi_t desc, const char *node, struct ubi_attach_request *req) -{ - struct ubi_attach_req r; - int ret; - - (void)desc; - - if (req->mtd_dev_node) { - /* - * User has passed path to device node. Lets find out MTD - * device number of the device and update req->mtd_num with it - */ - req->mtd_num = mtd_node_to_num(req->mtd_dev_node); - if (req->mtd_num == -1) - return -1; - } - - memset(&r, 0, sizeof(struct ubi_attach_req)); - r.ubi_num = req->dev_num; - r.mtd_num = req->mtd_num; - r.vid_hdr_offset = req->vid_hdr_offset; - - if (req->max_beb_per1024) { - /* - * We first have to check if the running kernel supports the - * 'max_beb_per1024' parameter. To do this, we invoke the - * "attach" ioctl 2 times: first with incorrect value %-1 of - * 'max_beb_per1024'. - * - * If the ioctl succeeds, it means that the kernel doesn't - * support the feature and just ignored our 'max_beb_per1024' - * value. - * - * If the ioctl returns -EINVAL, we assume this is because - * 'max_beb_per1024' was set to -1, and we invoke the ioctl for - * the second time with the 'max_beb_per1024' value. - */ - r.max_beb_per1024 = -1; - ret = do_attach(node, &r); - if (ret == 0) { - req->dev_num = r.ubi_num; - /* - * The call succeeded. It means that the kernel ignored - * 'max_beb_per1024' parameter. - */ - return 1; - } else if (errno != EINVAL) - return ret; - } - - r.max_beb_per1024 = req->max_beb_per1024; - - ret = do_attach(node, &r); - if (ret == 0) - req->dev_num = r.ubi_num; - - return ret; -} - -int ubi_detach_mtd(libubi_t desc, const char *node, int mtd_num) -{ - int ret, ubi_dev; - - ret = mtd_num2ubi_dev(desc, mtd_num, &ubi_dev); - if (ret == -1) { - errno = ENODEV; - return ret; - } - - return ubi_remove_dev(desc, node, ubi_dev); -} - -int ubi_detach(libubi_t desc, const char *node, const char *mtd_dev_node) -{ - int mtd_num; - - if (!mtd_dev_node) { - errno = EINVAL; - return -1; - } - - mtd_num = mtd_node_to_num(mtd_dev_node); - if (mtd_num == -1) - return -1; - - return ubi_detach_mtd(desc, node, mtd_num); -} - -int ubi_remove_dev(libubi_t desc, const char *node, int ubi_dev) -{ - int fd, ret; - - desc = desc; - - fd = open(node, O_RDONLY); - if (fd == -1) - return sys_errmsg("cannot open \"%s\"", node); - ret = ioctl(fd, UBI_IOCDET, &ubi_dev); - if (ret == -1) - goto out_close; - -#ifdef UDEV_SETTLE_HACK -// if (system("udevsettle") == -1) -// return -1; - usleep(100000); -#endif - -out_close: - close(fd); - return ret; -} - -int ubi_probe_node(libubi_t desc, const char *node) -{ - struct stat st; - struct ubi_info info; - int i, fd, major, minor; - struct libubi *lib = (struct libubi *)desc; - char file[strlen(lib->ubi_vol) + 100]; - - if (stat(node, &st)) - return sys_errmsg("cannot get information about \"%s\"", node); - - if (!S_ISCHR(st.st_mode)) { - errmsg("\"%s\" is not a character device", node); - errno = EINVAL; - return -1; - } - - major = major(st.st_rdev); - minor = minor(st.st_rdev); - - if (ubi_get_info((libubi_t *)lib, &info)) - return -1; - - for (i = info.lowest_dev_num; i <= info.highest_dev_num; i++) { - int major1, minor1, ret; - - ret = dev_get_major(lib, i, &major1, &minor1); - if (ret) { - if (errno == ENOENT) - continue; - if (!errno) - goto out_not_ubi; - return -1; - } - - if (major1 == major) - break; - } - - if (i > info.highest_dev_num) - goto out_not_ubi; - - if (minor == 0) - return 1; - - /* This is supposdely an UBI volume device node */ - sprintf(file, lib->ubi_vol, i, minor - 1); - fd = open(file, O_RDONLY); - if (fd == -1) - goto out_not_ubi; - - if (close(fd)) - sys_errmsg("close failed on \"%s\"", file); - - return 2; - -out_not_ubi: - errmsg("\"%s\" has major:minor %d:%d, but this does not correspond to " - "any existing UBI device or volume", node, major, minor); - errno = ENODEV; - return -1; -} - -int ubi_get_info(libubi_t desc, struct ubi_info *info) -{ - DIR *sysfs_ubi; - struct dirent *dirent; - struct libubi *lib = (struct libubi *)desc; - - memset(info, 0, sizeof(struct ubi_info)); - - if (read_major(lib->ctrl_dev, &info->ctrl_major, &info->ctrl_minor)) { - /* - * Older UBI versions did not have control device, so we do not - * panic here for compatibility reasons. May be few years later - * we could return -1 here, but for now just set major:minor to - * -1. - */ - info->ctrl_major = info->ctrl_minor = -1; - } - - /* - * We have to scan the UBI sysfs directory to identify how many UBI - * devices are present. - */ - sysfs_ubi = opendir(lib->sysfs_ubi); - if (!sysfs_ubi) - return -1; - - info->lowest_dev_num = INT_MAX; - while (1) { - int dev_num, ret; - char tmp_buf[256]; - - errno = 0; - dirent = readdir(sysfs_ubi); - if (!dirent) - break; - - if (strlen(dirent->d_name) >= 255) { - errmsg("invalid entry in %s: \"%s\"", - lib->sysfs_ubi, dirent->d_name); - errno = EINVAL; - goto out_close; - } - - ret = sscanf(dirent->d_name, UBI_DEV_NAME_PATT"%s", - &dev_num, tmp_buf); - if (ret == 1) { - info->dev_count += 1; - if (dev_num > info->highest_dev_num) - info->highest_dev_num = dev_num; - if (dev_num < info->lowest_dev_num) - info->lowest_dev_num = dev_num; - } - } - - if (!dirent && errno) { - sys_errmsg("readdir failed on \"%s\"", lib->sysfs_ubi); - goto out_close; - } - - if (closedir(sysfs_ubi)) - return sys_errmsg("closedir failed on \"%s\"", lib->sysfs_ubi); - - if (info->lowest_dev_num == INT_MAX) - info->lowest_dev_num = 0; - - if (read_positive_int(lib->ubi_version, &info->version)) - return -1; - - return 0; - -out_close: - closedir(sysfs_ubi); - return -1; -} - -int ubi_mkvol(libubi_t desc, const char *node, struct ubi_mkvol_request *req) -{ - int fd, ret; - struct ubi_mkvol_req r; - size_t n; - - memset(&r, 0, sizeof(struct ubi_mkvol_req)); - - desc = desc; - r.vol_id = req->vol_id; - r.alignment = req->alignment; - r.bytes = req->bytes; - r.vol_type = req->vol_type; - - n = strlen(req->name); - if (n > UBI_MAX_VOLUME_NAME) - return -1; - - strncpy(r.name, req->name, UBI_MAX_VOLUME_NAME + 1); - r.name_len = n; - - desc = desc; - fd = open(node, O_RDONLY); - if (fd == -1) - return sys_errmsg("cannot open \"%s\"", node); - - ret = ioctl(fd, UBI_IOCMKVOL, &r); - if (ret == -1) { - close(fd); - return ret; - } - - close(fd); - req->vol_id = r.vol_id; - -#ifdef UDEV_SETTLE_HACK -// if (system("udevsettle") == -1) -// return -1; - usleep(100000); -#endif - - return 0; -} - -int ubi_rmvol(libubi_t desc, const char *node, int vol_id) -{ - int fd, ret; - - desc = desc; - fd = open(node, O_RDONLY); - if (fd == -1) - return sys_errmsg("cannot open \"%s\"", node); - - ret = ioctl(fd, UBI_IOCRMVOL, &vol_id); - if (ret == -1) { - close(fd); - return ret; - } - - close(fd); - -#ifdef UDEV_SETTLE_HACK -// if (system("udevsettle") == -1) -// return -1; - usleep(100000); -#endif - - return 0; -} - -int ubi_rnvols(libubi_t desc, const char *node, struct ubi_rnvol_req *rnvol) -{ - int fd, ret; - - desc = desc; - fd = open(node, O_RDONLY); - if (fd == -1) - return -1; - - ret = ioctl(fd, UBI_IOCRNVOL, rnvol); - if (ret == -1) { - close(fd); - return ret; - } - - close(fd); - -#ifdef UDEV_SETTLE_HACK -// if (system("udevsettle") == -1) -// return -1; - usleep(100000); -#endif - - return 0; -} - -int ubi_rsvol(libubi_t desc, const char *node, int vol_id, long long bytes) -{ - int fd, ret; - struct ubi_rsvol_req req; - - desc = desc; - fd = open(node, O_RDONLY); - if (fd == -1) - return sys_errmsg("cannot open \"%s\"", node); - - req.bytes = bytes; - req.vol_id = vol_id; - - ret = ioctl(fd, UBI_IOCRSVOL, &req); - close(fd); - return ret; -} - -int ubi_vol_block_create(int fd) -{ - return ioctl(fd, UBI_IOCVOLCRBLK); -} - -int ubi_vol_block_remove(int fd) -{ - return ioctl(fd, UBI_IOCVOLRMBLK); -} - -int ubi_update_start(libubi_t desc, int fd, long long bytes) -{ - desc = desc; - if (ioctl(fd, UBI_IOCVOLUP, &bytes)) - return -1; - return 0; -} - -int ubi_leb_change_start(libubi_t desc, int fd, int lnum, int bytes) -{ - struct ubi_leb_change_req req; - - desc = desc; - memset(&req, 0, sizeof(struct ubi_leb_change_req)); - req.lnum = lnum; - req.bytes = bytes; - req.dtype = 3; - - if (ioctl(fd, UBI_IOCEBCH, &req)) - return -1; - return 0; -} - -int ubi_dev_present(libubi_t desc, int dev_num) -{ - struct stat st; - struct libubi *lib = (struct libubi *)desc; - char file[strlen(lib->ubi_dev) + 50]; - - sprintf(file, lib->ubi_dev, dev_num); - return !stat(file, &st); -} - -int ubi_get_dev_info1(libubi_t desc, int dev_num, struct ubi_dev_info *info) -{ - DIR *sysfs_ubi; - struct dirent *dirent; - struct libubi *lib = (struct libubi *)desc; - - memset(info, 0, sizeof(struct ubi_dev_info)); - info->dev_num = dev_num; - - if (!ubi_dev_present(desc, dev_num)) - return -1; - - sysfs_ubi = opendir(lib->sysfs_ubi); - if (!sysfs_ubi) - return -1; - - info->lowest_vol_id = INT_MAX; - - while (1) { - int vol_id, ret, devno; - char tmp_buf[256]; - - errno = 0; - dirent = readdir(sysfs_ubi); - if (!dirent) - break; - - if (strlen(dirent->d_name) >= 255) { - errmsg("invalid entry in %s: \"%s\"", - lib->sysfs_ubi, dirent->d_name); - goto out_close; - } - - ret = sscanf(dirent->d_name, UBI_VOL_NAME_PATT"%s", &devno, &vol_id, tmp_buf); - if (ret == 2 && devno == dev_num) { - info->vol_count += 1; - if (vol_id > info->highest_vol_id) - info->highest_vol_id = vol_id; - if (vol_id < info->lowest_vol_id) - info->lowest_vol_id = vol_id; - } - } - - if (!dirent && errno) { - sys_errmsg("readdir failed on \"%s\"", lib->sysfs_ubi); - goto out_close; - } - - if (closedir(sysfs_ubi)) - return sys_errmsg("closedir failed on \"%s\"", lib->sysfs_ubi); - - if (info->lowest_vol_id == INT_MAX) - info->lowest_vol_id = 0; - - if (dev_get_major(lib, dev_num, &info->major, &info->minor)) - return -1; - - if (dev_read_int(lib->dev_mtd_num, dev_num, &info->mtd_num)) - return -1; - if (dev_read_int(lib->dev_avail_ebs, dev_num, &info->avail_lebs)) - return -1; - if (dev_read_int(lib->dev_total_ebs, dev_num, &info->total_lebs)) - return -1; - if (dev_read_int(lib->dev_bad_count, dev_num, &info->bad_count)) - return -1; - if (dev_read_int(lib->dev_eb_size, dev_num, &info->leb_size)) - return -1; - if (dev_read_int(lib->dev_bad_rsvd, dev_num, &info->bad_rsvd)) - return -1; - if (dev_read_ll(lib->dev_max_ec, dev_num, &info->max_ec)) - return -1; - if (dev_read_int(lib->dev_max_vols, dev_num, &info->max_vol_count)) - return -1; - if (dev_read_int(lib->dev_min_io_size, dev_num, &info->min_io_size)) - return -1; - - info->avail_bytes = (long long)info->avail_lebs * info->leb_size; - info->total_bytes = (long long)info->total_lebs * info->leb_size; - - return 0; - -out_close: - closedir(sysfs_ubi); - return -1; -} - -int ubi_get_dev_info(libubi_t desc, const char *node, struct ubi_dev_info *info) -{ - int err, dev_num; - struct libubi *lib = (struct libubi *)desc; - - err = ubi_probe_node(desc, node); - if (err != 1) { - if (err == 2) - errno = ENODEV; - return -1; - } - - if (dev_node2num(lib, node, &dev_num)) - return -1; - - return ubi_get_dev_info1(desc, dev_num, info); -} - -int ubi_get_vol_info1(libubi_t desc, int dev_num, int vol_id, - struct ubi_vol_info *info) -{ - int ret; - struct libubi *lib = (struct libubi *)desc; - char buf[50]; - - memset(info, 0, sizeof(struct ubi_vol_info)); - info->dev_num = dev_num; - info->vol_id = vol_id; - - if (vol_get_major(lib, dev_num, vol_id, &info->major, &info->minor)) - return -1; - - ret = vol_read_data(lib->vol_type, dev_num, vol_id, buf, 50); - if (ret < 0) - return -1; - - if (strncmp(buf, "static\n", ret) == 0) - info->type = UBI_STATIC_VOLUME; - else if (strncmp(buf, "dynamic\n", ret) == 0) - info->type = UBI_DYNAMIC_VOLUME; - else { - errmsg("bad value at \"%s\"", buf); - errno = EINVAL; - return -1; - } - - ret = vol_read_int(lib->vol_alignment, dev_num, vol_id, - &info->alignment); - if (ret) - return -1; - ret = vol_read_ll(lib->vol_data_bytes, dev_num, vol_id, - &info->data_bytes); - if (ret) - return -1; - ret = vol_read_int(lib->vol_rsvd_ebs, dev_num, vol_id, &info->rsvd_lebs); - if (ret) - return -1; - ret = vol_read_int(lib->vol_eb_size, dev_num, vol_id, &info->leb_size); - if (ret) - return -1; - ret = vol_read_int(lib->vol_corrupted, dev_num, vol_id, - &info->corrupted); - if (ret) - return -1; - info->rsvd_bytes = (long long)info->leb_size * info->rsvd_lebs; - - ret = vol_read_data(lib->vol_name, dev_num, vol_id, &info->name, - UBI_VOL_NAME_MAX + 2); - if (ret < 0) - return -1; - - info->name[ret - 1] = '\0'; - return 0; -} - -int ubi_get_vol_info(libubi_t desc, const char *node, struct ubi_vol_info *info) -{ - int err, vol_id, dev_num; - struct libubi *lib = (struct libubi *)desc; - - err = ubi_probe_node(desc, node); - if (err != 2) { - if (err == 1) - errno = ENODEV; - return -1; - } - - if (vol_node2nums(lib, node, &dev_num, &vol_id)) - return -1; - - return ubi_get_vol_info1(desc, dev_num, vol_id, info); -} - -int ubi_get_vol_info1_nm(libubi_t desc, int dev_num, const char *name, - struct ubi_vol_info *info) -{ - int i, err; - unsigned int nlen = strlen(name); - struct ubi_dev_info dev_info; - - if (nlen == 0) { - errmsg("bad \"name\" input parameter"); - errno = EINVAL; - return -1; - } - - err = ubi_get_dev_info1(desc, dev_num, &dev_info); - if (err) - return err; - - for (i = dev_info.lowest_vol_id; - i <= dev_info.highest_vol_id; i++) { - err = ubi_get_vol_info1(desc, dev_num, i, info); - if (err == -1) { - if (errno == ENOENT) - continue; - return -1; - } - - if (nlen == strlen(info->name) && !strcmp(name, info->name)) - return 0; - } - - errno = ENOENT; - return -1; -} - -int ubi_set_property(int fd, uint8_t property, uint64_t value) -{ - struct ubi_set_vol_prop_req r; - - memset(&r, 0, sizeof(struct ubi_set_vol_prop_req)); - r.property = property; - r.value = value; - - return ioctl(fd, UBI_IOCSETVOLPROP, &r); -} - -int ubi_leb_unmap(int fd, int lnum) -{ - return ioctl(fd, UBI_IOCEBUNMAP, &lnum); -} - -int ubi_is_mapped(int fd, int lnum) -{ - return ioctl(fd, UBI_IOCEBISMAP, &lnum); -} diff --git a/ubi-utils/libubi_int.h b/ubi-utils/libubi_int.h deleted file mode 100644 index 86ce18a..0000000 --- a/ubi-utils/libubi_int.h +++ /dev/null @@ -1,134 +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. - * - * Author: Artem Bityutskiy - * - * UBI (Unsorted Block Images) library. - */ - -#ifndef __LIBUBI_INT_H__ -#define __LIBUBI_INT_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The below are pre-define UBI file and directory names. - * - * Note, older kernels put 'ubiX_Y' directories straight to '/sys/class/ubi/'. - * New kernels puts 'ubiX_Y' directories to '/sys/class/ubi/ubiX/', which is - * saner. And for compatibility reasons it also puts symlinks to 'ubiX_Y' - * directories to '/sys/class/ubi/'. For now libubi assumes old layout. - */ - -#ifndef SYSFS_ROOT -#define SYSFS_ROOT "/sys" -#endif -#define SYSFS_UBI "class/ubi" -#define SYSFS_CTRL "class/misc/ubi_ctrl/" - -#define CTRL_DEV "dev" - -#define UBI_VER "version" -#define UBI_DEV_NAME_PATT "ubi%d" - -#define DEV_DEV "dev" -#define DEV_AVAIL_EBS "avail_eraseblocks" -#define DEV_TOTAL_EBS "total_eraseblocks" -#define DEV_BAD_COUNT "bad_peb_count" -#define DEV_EB_SIZE "eraseblock_size" -#define DEV_MAX_EC "max_ec" -#define DEV_MAX_RSVD "reserved_for_bad" -#define DEV_MAX_VOLS "max_vol_count" -#define DEV_MIN_IO_SIZE "min_io_size" -#define DEV_MTD_NUM "mtd_num" - -#define UBI_VOL_NAME_PATT "ubi%d_%d" -#define VOL_TYPE "type" -#define VOL_DEV "dev" -#define VOL_ALIGNMENT "alignment" -#define VOL_DATA_BYTES "data_bytes" -#define VOL_RSVD_EBS "reserved_ebs" -#define VOL_EB_SIZE "usable_eb_size" -#define VOL_CORRUPTED "corrupted" -#define VOL_NAME "name" - -/** - * libubi - UBI library description data structure. - * @sysfs: sysfs file system path - * @sysfs_ctrl: UBI control device directory in sysfs - * @ctrl_dev: UBI control device major/minor numbers sysfs file - * @sysfs_ubi: UBI directory in sysfs - * @ubi_dev: UBI device sysfs directory pattern - * @ubi_version: UBI version file sysfs path - * @dev_dev: UBI device major/minor numbers file pattern - * @dev_avail_ebs: count of available eraseblocks sysfs path pattern - * @dev_total_ebs: total eraseblocks count sysfs path pattern - * @dev_bad_count: count of bad eraseblocks sysfs path pattern - * @dev_eb_size: size of UBI device's eraseblocks sysfs path pattern - * @dev_max_ec: maximum erase counter sysfs path pattern - * @dev_bad_rsvd: count of physical eraseblock reserved for bad eraseblocks - * handling - * @dev_max_vols: maximum volumes number count sysfs path pattern - * @dev_min_io_size: minimum I/O unit size sysfs path pattern - * @dev_mtd_num: MTD device number - * @ubi_vol: UBI volume sysfs directory pattern - * @vol_type: volume type sysfs path pattern - * @vol_dev: volume major/minor numbers file pattern - * @vol_alignment: volume alignment sysfs path pattern - * @vol_data_bytes: volume data size sysfs path pattern - * @vol_rsvd_ebs: volume reserved size sysfs path pattern - * @vol_eb_size: volume eraseblock size sysfs path pattern - * @vol_corrupted: volume corruption flag sysfs path pattern - * @vol_name: volume name sysfs path pattern - */ -struct libubi -{ - char *sysfs; - char *sysfs_ctrl; - char *ctrl_dev; - char *sysfs_ubi; - char *ubi_dev; - char *ubi_version; - char *dev_dev; - char *dev_avail_ebs; - char *dev_total_ebs; - char *dev_bad_count; - char *dev_eb_size; - char *dev_max_ec; - char *dev_bad_rsvd; - char *dev_max_vols; - char *dev_min_io_size; - char *dev_mtd_num; - char *ubi_vol; - char *vol_type; - char *vol_dev; - char *vol_alignment; - char *vol_data_bytes; - char *vol_rsvd_ebs; - char *vol_eb_size; - char *vol_corrupted; - char *vol_name; - char *vol_max_count; -}; - -#ifdef __cplusplus -} -#endif - -#endif /* !__LIBUBI_INT_H__ */ diff --git a/ubi-utils/libubigen.c b/ubi-utils/libubigen.c deleted file mode 100644 index d2a949b..0000000 --- a/ubi-utils/libubigen.c +++ /dev/null @@ -1,315 +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. - */ - -/* - * Generating UBI images. - * - * Authors: Oliver Lohmann - * Artem Bityutskiy - */ - -#define PROGRAM_NAME "libubigen" - -#include <stdlib.h> -#include <stdint.h> -#include <unistd.h> -#include <string.h> - -#include <mtd/ubi-media.h> -#include <mtd_swab.h> -#include <libubigen.h> -#include <crc32.h> -#include "common.h" - -void ubigen_info_init(struct ubigen_info *ui, int peb_size, int min_io_size, - int subpage_size, int vid_hdr_offs, int ubi_ver, - uint32_t image_seq) -{ - if (!vid_hdr_offs) { - vid_hdr_offs = UBI_EC_HDR_SIZE + subpage_size - 1; - vid_hdr_offs /= subpage_size; - vid_hdr_offs *= subpage_size; - } - - ui->peb_size = peb_size; - ui->min_io_size = min_io_size; - ui->vid_hdr_offs = vid_hdr_offs; - ui->data_offs = vid_hdr_offs + UBI_VID_HDR_SIZE + min_io_size - 1; - ui->data_offs /= min_io_size; - ui->data_offs *= min_io_size; - ui->leb_size = peb_size - ui->data_offs; - ui->ubi_ver = ubi_ver; - ui->image_seq = image_seq; - - ui->max_volumes = ui->leb_size / UBI_VTBL_RECORD_SIZE; - if (ui->max_volumes > UBI_MAX_VOLUMES) - ui->max_volumes = UBI_MAX_VOLUMES; - ui->vtbl_size = ui->max_volumes * UBI_VTBL_RECORD_SIZE; -} - -struct ubi_vtbl_record *ubigen_create_empty_vtbl(const struct ubigen_info *ui) -{ - struct ubi_vtbl_record *vtbl; - int i; - - vtbl = calloc(1, ui->vtbl_size); - if (!vtbl) { - sys_errmsg("cannot allocate %d bytes of memory", ui->vtbl_size); - return NULL; - } - - for (i = 0; i < ui->max_volumes; i++) { - uint32_t crc = mtd_crc32(UBI_CRC32_INIT, &vtbl[i], - UBI_VTBL_RECORD_SIZE_CRC); - vtbl[i].crc = cpu_to_be32(crc); - } - - return vtbl; -} - -int ubigen_add_volume(const struct ubigen_info *ui, - const struct ubigen_vol_info *vi, - struct ubi_vtbl_record *vtbl) -{ - struct ubi_vtbl_record *vtbl_rec = &vtbl[vi->id]; - uint32_t tmp; - - if (vi->id >= ui->max_volumes) { - errmsg("too high volume id %d, max. volumes is %d", - vi->id, ui->max_volumes); - errno = EINVAL; - return -1; - } - - if (vi->alignment >= ui->leb_size) { - errmsg("too large alignment %d, max is %d (LEB size)", - vi->alignment, ui->leb_size); - errno = EINVAL; - return -1; - } - - memset(vtbl_rec, 0, sizeof(struct ubi_vtbl_record)); - tmp = (vi->bytes + ui->leb_size - 1) / ui->leb_size; - vtbl_rec->reserved_pebs = cpu_to_be32(tmp); - vtbl_rec->alignment = cpu_to_be32(vi->alignment); - vtbl_rec->vol_type = vi->type; - tmp = ui->leb_size % vi->alignment; - vtbl_rec->data_pad = cpu_to_be32(tmp); - vtbl_rec->flags = vi->flags; - - memcpy(vtbl_rec->name, vi->name, vi->name_len); - vtbl_rec->name[vi->name_len] = '\0'; - vtbl_rec->name_len = cpu_to_be16(vi->name_len); - - tmp = mtd_crc32(UBI_CRC32_INIT, vtbl_rec, UBI_VTBL_RECORD_SIZE_CRC); - vtbl_rec->crc = cpu_to_be32(tmp); - return 0; -} - -void ubigen_init_ec_hdr(const struct ubigen_info *ui, - struct ubi_ec_hdr *hdr, long long ec) -{ - uint32_t crc; - - memset(hdr, 0, sizeof(struct ubi_ec_hdr)); - - hdr->magic = cpu_to_be32(UBI_EC_HDR_MAGIC); - hdr->version = ui->ubi_ver; - hdr->ec = cpu_to_be64(ec); - hdr->vid_hdr_offset = cpu_to_be32(ui->vid_hdr_offs); - hdr->data_offset = cpu_to_be32(ui->data_offs); - hdr->image_seq = cpu_to_be32(ui->image_seq); - - crc = mtd_crc32(UBI_CRC32_INIT, hdr, UBI_EC_HDR_SIZE_CRC); - hdr->hdr_crc = cpu_to_be32(crc); -} - -void ubigen_init_vid_hdr(const struct ubigen_info *ui, - const struct ubigen_vol_info *vi, - struct ubi_vid_hdr *hdr, int lnum, - const void *data, int data_size) -{ - uint32_t crc; - - memset(hdr, 0, sizeof(struct ubi_vid_hdr)); - - hdr->magic = cpu_to_be32(UBI_VID_HDR_MAGIC); - hdr->version = ui->ubi_ver; - hdr->vol_type = vi->type; - hdr->vol_id = cpu_to_be32(vi->id); - hdr->lnum = cpu_to_be32(lnum); - hdr->data_pad = cpu_to_be32(vi->data_pad); - hdr->compat = vi->compat; - - if (vi->type == UBI_VID_STATIC) { - hdr->data_size = cpu_to_be32(data_size); - hdr->used_ebs = cpu_to_be32(vi->used_ebs); - crc = mtd_crc32(UBI_CRC32_INIT, data, data_size); - hdr->data_crc = cpu_to_be32(crc); - } - - crc = mtd_crc32(UBI_CRC32_INIT, hdr, UBI_VID_HDR_SIZE_CRC); - hdr->hdr_crc = cpu_to_be32(crc); -} - -int ubigen_write_volume(const struct ubigen_info *ui, - const struct ubigen_vol_info *vi, long long ec, - long long bytes, int in, int out) -{ - int len = vi->usable_leb_size, rd, lnum = 0; - char *inbuf, *outbuf; - - if (vi->id >= ui->max_volumes) { - errmsg("too high volume id %d, max. volumes is %d", - vi->id, ui->max_volumes); - errno = EINVAL; - return -1; - } - - if (vi->alignment >= ui->leb_size) { - errmsg("too large alignment %d, max is %d (LEB size)", - vi->alignment, ui->leb_size); - errno = EINVAL; - return -1; - } - - inbuf = malloc(ui->leb_size); - if (!inbuf) - return sys_errmsg("cannot allocate %d bytes of memory", - ui->leb_size); - outbuf = malloc(ui->peb_size); - if (!outbuf) { - sys_errmsg("cannot allocate %d bytes of memory", ui->peb_size); - goto out_free; - } - - memset(outbuf, 0xFF, ui->data_offs); - ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec); - - while (bytes) { - int l; - struct ubi_vid_hdr *vid_hdr; - - if (bytes < len) - len = bytes; - bytes -= len; - - l = len; - do { - rd = read(in, inbuf + len - l, l); - if (rd != l) { - sys_errmsg("cannot read %d bytes from the input file", l); - goto out_free1; - } - - l -= rd; - } while (l); - - vid_hdr = (struct ubi_vid_hdr *)(&outbuf[ui->vid_hdr_offs]); - ubigen_init_vid_hdr(ui, vi, vid_hdr, lnum, inbuf, len); - - memcpy(outbuf + ui->data_offs, inbuf, len); - memset(outbuf + ui->data_offs + len, 0xFF, - ui->peb_size - ui->data_offs - len); - - if (write(out, outbuf, ui->peb_size) != ui->peb_size) { - sys_errmsg("cannot write %d bytes to the output file", ui->peb_size); - goto out_free1; - } - - lnum += 1; - } - - free(outbuf); - free(inbuf); - return 0; - -out_free1: - free(outbuf); -out_free: - free(inbuf); - return -1; -} - -int ubigen_write_layout_vol(const struct ubigen_info *ui, int peb1, int peb2, - long long ec1, long long ec2, - struct ubi_vtbl_record *vtbl, int fd) -{ - int ret; - struct ubigen_vol_info vi; - char *outbuf; - struct ubi_vid_hdr *vid_hdr; - off_t seek; - - vi.bytes = ui->leb_size * UBI_LAYOUT_VOLUME_EBS; - vi.id = UBI_LAYOUT_VOLUME_ID; - vi.alignment = UBI_LAYOUT_VOLUME_ALIGN; - vi.data_pad = ui->leb_size % UBI_LAYOUT_VOLUME_ALIGN; - vi.usable_leb_size = ui->leb_size - vi.data_pad; - vi.data_pad = ui->leb_size - vi.usable_leb_size; - vi.type = UBI_LAYOUT_VOLUME_TYPE; - vi.name = UBI_LAYOUT_VOLUME_NAME; - vi.name_len = strlen(UBI_LAYOUT_VOLUME_NAME); - vi.compat = UBI_LAYOUT_VOLUME_COMPAT; - - outbuf = malloc(ui->peb_size); - if (!outbuf) - return sys_errmsg("failed to allocate %d bytes", - ui->peb_size); - - memset(outbuf, 0xFF, ui->data_offs); - vid_hdr = (struct ubi_vid_hdr *)(&outbuf[ui->vid_hdr_offs]); - memcpy(outbuf + ui->data_offs, vtbl, ui->vtbl_size); - memset(outbuf + ui->data_offs + ui->vtbl_size, 0xFF, - ui->peb_size - ui->data_offs - ui->vtbl_size); - - seek = (off_t) peb1 * ui->peb_size; - if (lseek(fd, seek, SEEK_SET) != seek) { - sys_errmsg("cannot seek output file"); - goto out_free; - } - - ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec1); - ubigen_init_vid_hdr(ui, &vi, vid_hdr, 0, NULL, 0); - ret = write(fd, outbuf, ui->peb_size); - if (ret != ui->peb_size) { - sys_errmsg("cannot write %d bytes", ui->peb_size); - goto out_free; - } - - seek = (off_t) peb2 * ui->peb_size; - if (lseek(fd, seek, SEEK_SET) != seek) { - sys_errmsg("cannot seek output file"); - goto out_free; - } - ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec2); - ubigen_init_vid_hdr(ui, &vi, vid_hdr, 1, NULL, 0); - ret = write(fd, outbuf, ui->peb_size); - if (ret != ui->peb_size) { - sys_errmsg("cannot write %d bytes", ui->peb_size); - goto out_free; - } - - free(outbuf); - return 0; - -out_free: - free(outbuf); - return -1; -} |