diff options
author | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2009-03-17 10:14:54 +0200 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2009-03-17 10:16:38 +0200 |
commit | 606f38a2221648ca5c5fa292c9f71d2ddd59fa66 (patch) | |
tree | 26d11905fda474261433c580c6fb58f4f4a85e59 /ubi-utils/new-utils/src | |
parent | a2d010f8fca904fffa3c6e5a5d148cc96a37a08a (diff) |
ubi-utils: re-arrange directory layout
Move new-utils to ubi-utils and old ones to ubi-utils/old-utils.
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'ubi-utils/new-utils/src')
22 files changed, 0 insertions, 7177 deletions
diff --git a/ubi-utils/new-utils/src/common.c b/ubi-utils/new-utils/src/common.c deleted file mode 100644 index bcb775c..0000000 --- a/ubi-utils/new-utils/src/common.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (C) 2007, 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. - */ - -/* - * This file contains various common stuff used by UBI utilities. - * - * Authors: Artem Bityutskiy - * Adrian Hunter - */ - -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <stdlib.h> - -/** - * get_multiplier - convert size specifier to an integer multiplier. - * @str: the size specifier string - * - * This function parses the @str size specifier, which may be one of - * 'KiB', 'MiB', or 'GiB' into an integer multiplier. Returns positive - * size multiplier in case of success and %-1 in case of failure. - */ -static int get_multiplier(const char *str) -{ - if (!str) - return 1; - - /* Remove spaces before the specifier */ - while (*str == ' ' || *str == '\t') - str += 1; - - if (!strcmp(str, "KiB")) - return 1024; - if (!strcmp(str, "MiB")) - return 1024 * 1024; - if (!strcmp(str, "GiB")) - return 1024 * 1024 * 1024; - - /* Handle deprecated stuff */ - if (!strcmp(str, "KB") || !strcmp(str, "Kib") || !strcmp(str, "kib") || - !strcmp(str, "kiB")) { - fprintf(stderr, "Warning: use \"KiB\" instead of \"%s\" to " - "specify Kilobytes - support will be removed\n", str); - return 1024; - } - if (!strcmp(str, "MB") || !strcmp(str, "Mib") || !strcmp(str, "mb")) { - fprintf(stderr, "Warning: use \"MiB\" instead of \"%s\", " - "this support will be removed\n", str); - return 1024*1024; - } - if (!strcmp(str, "GB") || !strcmp(str, "Gib") || !strcmp(str, "gb")) { - fprintf(stderr, "Warning: use \"GiB\" instead of \"%s\", " - "this support will be removed\n", str); - return 1024*1024*1024; - } - - return -1; -} - -/** - * ubiutils_get_bytes - convert a string containing amount of bytes into an - * integer - * @str: string to convert - * - * This function parses @str which may have one of 'KiB', 'MiB', or 'GiB' - * size specifiers. Returns positive amount of bytes in case of success and %-1 - * in case of failure. - */ -long long ubiutils_get_bytes(const char *str) -{ - char *endp; - long long bytes = strtoull(str, &endp, 0); - - if (endp == str || bytes < 0) { - fprintf(stderr, "incorrect amount of bytes: \"%s\"\n", str); - return -1; - } - - if (*endp != '\0') { - int mult = get_multiplier(endp); - - if (mult == -1) { - fprintf(stderr, "bad size specifier: \"%s\" - " - "should be 'KiB', 'MiB' or 'GiB'\n", endp); - return -1; - } - bytes *= mult; - } - - return bytes; -} - -/** - * ubiutils_print_bytes - print bytes. - * @bytes: variable to print - * @bracket: whether brackets have to be put or not - * - * This is a helper function which prints amount of bytes in a human-readable - * form, i.e., it prints the exact amount of bytes following by the approximate - * amount of Kilobytes, Megabytes, or Gigabytes, depending on how big @bytes - * is. - */ -void ubiutils_print_bytes(long long bytes, int bracket) -{ - const char *p; - - if (bracket) - p = " ("; - else - p = ", "; - - printf("%lld bytes", bytes); - - if (bytes > 1024 * 1024 * 1024) - printf("%s%.1f GiB", p, (double)bytes / (1024 * 1024 * 1024)); - else if (bytes > 1024 * 1024) - printf("%s%.1f MiB", p, (double)bytes / (1024 * 1024)); - else if (bytes > 1024 && bytes != 0) - printf("%s%.1f KiB", p, (double)bytes / 1024); - else - return; - - if (bracket) - printf(")"); -} - -/** - * ubiutils_print_text - print text and fold it. - * @stream: file stream to print to - * @text: text to print - * @width: maximum allowed text width - * - * Print text and fold it so that each line would not have more then @width - * characters. - */ -void ubiutils_print_text(FILE *stream, const char *text, int width) -{ - int pos, bpos = 0; - const char *p; - char line[1024]; - - if (width > 1023) { - fprintf(stream, "%s\n", text); - return; - } - p = text; - pos = 0; - while (p[pos]) { - while (!isspace(p[pos])) { - line[pos] = p[pos]; - if (!p[pos]) - break; - ++pos; - if (pos == width) { - line[pos] = '\0'; - fprintf(stream, "%s\n", line); - p += pos; - pos = 0; - } - } - while (pos < width) { - line[pos] = p[pos]; - if (!p[pos]) { - bpos = pos; - break; - } - if (isspace(p[pos])) - bpos = pos; - ++pos; - } - line[bpos] = '\0'; - fprintf(stream, "%s\n", line); - p += bpos; - pos = 0; - while (p[pos] && isspace(p[pos])) - ++p; - } -} diff --git a/ubi-utils/new-utils/src/common.h b/ubi-utils/new-utils/src/common.h deleted file mode 100644 index 56fa020..0000000 --- a/ubi-utils/new-utils/src/common.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) Artem Bityutskiy, 2007, 2008 - * - * 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. - */ - -#ifndef __UBI_UTILS_COMMON_H__ -#define __UBI_UTILS_COMMON_H__ - -#include <stdio.h> -#include <string.h> -#include <errno.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define MIN(a ,b) ((a) < (b) ? (a) : (b)) -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) - -/* Verbose messages */ -#define verbose(verbose, fmt, ...) do { \ - if (verbose) \ - printf(PROGRAM_NAME ": " fmt "\n", ##__VA_ARGS__); \ -} while(0) - -/* Normal messages */ -#define normsg(fmt, ...) do { \ - printf(PROGRAM_NAME ": " fmt "\n", ##__VA_ARGS__); \ -} while(0) -#define normsg_cont(fmt, ...) do { \ - printf(PROGRAM_NAME ": " fmt, ##__VA_ARGS__); \ -} while(0) -#define normsg_cont(fmt, ...) do { \ - printf(PROGRAM_NAME ": " fmt, ##__VA_ARGS__); \ -} while(0) - -/* Error messages */ -#define errmsg(fmt, ...) ({ \ - fprintf(stderr, PROGRAM_NAME ": error!: " fmt "\n", ##__VA_ARGS__); \ - -1; \ -}) - -/* System error messages */ -#define sys_errmsg(fmt, ...) ({ \ - int _err = errno; \ - size_t _i; \ - fprintf(stderr, PROGRAM_NAME ": error!: " fmt "\n", ##__VA_ARGS__); \ - for (_i = 0; _i < sizeof(PROGRAM_NAME) + 1; _i++) \ - fprintf(stderr, " "); \ - fprintf(stderr, "error %d (%s)\n", _err, strerror(_err)); \ - -1; \ -}) - -/* Warnings */ -#define warnmsg(fmt, ...) do { \ - fprintf(stderr, PROGRAM_NAME ": warning!: " fmt "\n", ##__VA_ARGS__); \ -} while(0) - -static inline int is_power_of_2(unsigned long long n) -{ - return (n != 0 && ((n & (n - 1)) == 0)); -} - -long long ubiutils_get_bytes(const char *str); -void ubiutils_print_bytes(long long bytes, int bracket); -void ubiutils_print_text(FILE *stream, const char *txt, int len); - -#ifdef __cplusplus -} -#endif - -#endif /* !__UBI_UTILS_COMMON_H__ */ diff --git a/ubi-utils/new-utils/src/crc32.c b/ubi-utils/new-utils/src/crc32.c deleted file mode 100644 index 6b1e50c..0000000 --- a/ubi-utils/new-utils/src/crc32.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or - * code or tables extracted from it, as desired without restriction. - * - * First, the polynomial itself and its table of feedback terms. The - * polynomial is - * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 - * - * Note that we take it "backwards" and put the highest-order term in - * the lowest-order bit. The X^32 term is "implied"; the LSB is the - * X^31 term, etc. The X^0 term (usually shown as "+1") results in - * the MSB being 1 - * - * Note that the usual hardware shift register implementation, which - * is what we're using (we're merely optimizing it by doing eight-bit - * chunks at a time) shifts bits into the lowest-order term. In our - * implementation, that means shifting towards the right. Why do we - * do it this way? Because the calculated CRC must be transmitted in - * order from highest-order term to lowest-order term. UARTs transmit - * characters in order from LSB to MSB. By storing the CRC this way - * we hand it to the UART in the order low-byte to high-byte; the UART - * sends each low-bit to hight-bit; and the result is transmission bit - * by bit from highest- to lowest-order term without requiring any bit - * shuffling on our part. Reception works similarly - * - * The feedback terms table consists of 256, 32-bit entries. Notes - * - * The table can be generated at runtime if desired; code to do so - * is shown later. It might not be obvious, but the feedback - * terms simply represent the results of eight shift/xor opera - * tions for all combinations of data and CRC register values - * - * The values must be right-shifted by eight bits by the "updcrc - * logic; the shift must be unsigned (bring in zeroes). On some - * hardware you could probably optimize the shift in assembler by - * using byte-swap instructions - * polynomial $edb88320 - */ - -#include <stdint.h> - -const uint32_t crc32_table[256] = { - 0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L, - 0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L, - 0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L, - 0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL, - 0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L, - 0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L, - 0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L, - 0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL, - 0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L, - 0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL, - 0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L, - 0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L, - 0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L, - 0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL, - 0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL, - 0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L, - 0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL, - 0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L, - 0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L, - 0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L, - 0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL, - 0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L, - 0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L, - 0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL, - 0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L, - 0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L, - 0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L, - 0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L, - 0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L, - 0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL, - 0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL, - 0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L, - 0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L, - 0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL, - 0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL, - 0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L, - 0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL, - 0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L, - 0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL, - 0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L, - 0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL, - 0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L, - 0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L, - 0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL, - 0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L, - 0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L, - 0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L, - 0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L, - 0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L, - 0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L, - 0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL, - 0x2d02ef8dL -}; diff --git a/ubi-utils/new-utils/src/crc32.h b/ubi-utils/new-utils/src/crc32.h deleted file mode 100644 index ee3145b..0000000 --- a/ubi-utils/new-utils/src/crc32.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef CRC32_H -#define CRC32_H - -#include <stdint.h> - -extern const uint32_t crc32_table[256]; - -/* Return a 32-bit CRC of the contents of the buffer. */ - - static inline uint32_t -crc32(uint32_t val, const void *ss, int len) -{ - const unsigned char *s = ss; - while (--len >= 0) - val = crc32_table[(val ^ *s++) & 0xff] ^ (val >> 8); - return val; -} - -#endif diff --git a/ubi-utils/new-utils/src/dictionary.c b/ubi-utils/new-utils/src/dictionary.c deleted file mode 100644 index b7c9ebf..0000000 --- a/ubi-utils/new-utils/src/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/new-utils/src/dictionary.h b/ubi-utils/new-utils/src/dictionary.h deleted file mode 100644 index c7d1790..0000000 --- a/ubi-utils/new-utils/src/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/new-utils/src/libiniparser.c b/ubi-utils/new-utils/src/libiniparser.c deleted file mode 100644 index 3bea51e..0000000 --- a/ubi-utils/new-utils/src/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/new-utils/src/libmtd.c b/ubi-utils/new-utils/src/libmtd.c deleted file mode 100644 index b60ddbd..0000000 --- a/ubi-utils/new-utils/src/libmtd.c +++ /dev/null @@ -1,314 +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 - * - * MTD library. - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <unistd.h> -#include <fcntl.h> - -#include <mtd/mtd-user.h> -#include <libmtd.h> -#include "common.h" - -#define PROGRAM_NAME "libmtd" -#define MTD_DEV_MAJOR 90 - -/** - * mtd_get_info - get information about an MTD device. - * @node: name of the MTD device node - * @mtd: the MTD device information is returned here - * - * This function gets information about MTD device defined by the @node device - * node file and saves this information in the @mtd object. Returns %0 in case - * of success and %-1 in case of failure. - */ -int mtd_get_info(const char *node, struct mtd_info *mtd) -{ - struct stat st; - struct mtd_info_user ui; - int ret; - loff_t offs = 0; - - if (stat(node, &st)) - return sys_errmsg("cannot open \"%s\"", node); - - if (!S_ISCHR(st.st_mode)) { - errno = EINVAL; - return errmsg("\"%s\" is not a character device", node); - } - - mtd->major = major(st.st_rdev); - mtd->minor = minor(st.st_rdev); - - if (mtd->major != MTD_DEV_MAJOR) { - errno = EINVAL; - return errmsg("\"%s\" has major number %d, MTD devices have " - "major %d", node, mtd->major, MTD_DEV_MAJOR); - } - - mtd->num = mtd->minor / 2; - mtd->rdonly = mtd->minor & 1; - - mtd->fd = open(node, O_RDWR); - if (mtd->fd == -1) - return sys_errmsg("cannot open \"%s\"", node); - - if (ioctl(mtd->fd, MEMGETINFO, &ui)) { - sys_errmsg("MEMGETINFO ioctl request failed"); - goto out_close; - } - - ret = ioctl(mtd->fd, MEMGETBADBLOCK, &offs); - if (ret == -1) { - if (errno != EOPNOTSUPP) { - sys_errmsg("MEMGETBADBLOCK ioctl failed"); - goto out_close; - } - errno = 0; - mtd->allows_bb = 0; - } else - mtd->allows_bb = 1; - - mtd->type = ui.type; - mtd->size = ui.size; - mtd->eb_size = ui.erasesize; - mtd->min_io_size = ui.writesize; - - if (mtd->min_io_size <= 0) { - errmsg("mtd%d (%s) has insane min. I/O unit size %d", - mtd->num, node, mtd->min_io_size); - goto out_close; - } - if (mtd->eb_size <= 0 || mtd->eb_size < mtd->min_io_size) { - errmsg("mtd%d (%s) has insane eraseblock size %d", - mtd->num, node, mtd->eb_size); - goto out_close; - } - if (mtd->size <= 0 || mtd->size < mtd->eb_size) { - errmsg("mtd%d (%s) has insane size %lld", - mtd->num, node, mtd->size); - goto out_close; - } - mtd->eb_cnt = mtd->size / mtd->eb_size; - - switch(mtd->type) { - case MTD_ABSENT: - errmsg("mtd%d (%s) is removable and is not present", - mtd->num, node); - goto out_close; - case MTD_RAM: - mtd->type_str = "RAM-based"; - break; - case MTD_ROM: - mtd->type_str = "ROM"; - break; - case MTD_NORFLASH: - mtd->type_str = "NOR"; - break; - case MTD_NANDFLASH: - mtd->type_str = "NAND"; - break; - case MTD_DATAFLASH: - mtd->type_str = "DataFlash"; - break; - case MTD_UBIVOLUME: - mtd->type_str = "UBI-emulated MTD"; - break; - default: - mtd->type_str = "Unknown flash type"; - break; - } - - if (!(ui.flags & MTD_WRITEABLE)) - mtd->rdonly = 1; - - return 0; - -out_close: - close(mtd->fd); - return -1; -} - -/** - * mtd_erase - erase an eraseblock. - * @mtd: MTD device description object - * @eb: eraseblock to erase - * - * This function erases the eraseblock and returns %0 in case of success and - * %-1 in case of failure. - */ -int mtd_erase(const struct mtd_info *mtd, int eb) -{ - struct erase_info_user ei; - - ei.start = eb * mtd->eb_size;; - ei.length = mtd->eb_size; - return ioctl(mtd->fd, MEMERASE, &ei); -} - -/** - * mtd_is_bad - check if eraseblock is bad. - * @mtd: MTD device description object - * @eb: eraseblock to check - * - * This function checks if eraseblock @eb is bad. Returns %0 if not, %1 if yes, - * and %-1 in case of failure. - */ -int mtd_is_bad(const struct mtd_info *mtd, int eb) -{ - int ret; - loff_t seek; - - if (eb < 0 || eb >= mtd->eb_cnt) { - errmsg("bad eraseblock number %d, mtd%d has %d eraseblocks", - eb, mtd->num, mtd->eb_cnt); - errno = EINVAL; - return -1; - } - - if (!mtd->allows_bb) - return 0; - - seek = (loff_t)eb * mtd->eb_size; - ret = ioctl(mtd->fd, MEMGETBADBLOCK, &seek); - if (ret == -1) { - sys_errmsg("MEMGETBADBLOCK ioctl failed for " - "eraseblock %d (mtd%d)", eb, mtd->num); - return -1; - } - - return ret; -} - -/** - * mtd_read - read data from an MTD device. - * @mtd: MTD device description object - * @eb: eraseblock to read from - * @offs: offset withing the eraseblock to read from - * @buf: buffer to read data to - * @len: how many bytes to read - * - * This function reads @len bytes of data from eraseblock @eb and offset @offs - * of the MTD device defined by @mtd and stores the read data at buffer @buf. - * Returns %0 in case of success and %-1 in case of failure. - */ -int mtd_read(const struct mtd_info *mtd, int eb, int offs, void *buf, int len) -{ - int ret, rd = 0; - off_t seek; - - if (eb < 0 || eb >= mtd->eb_cnt) { - errmsg("bad eraseblock number %d, mtd%d has %d eraseblocks", - eb, mtd->num, mtd->eb_cnt); - errno = EINVAL; - return -1; - } - if (offs < 0 || offs + len > mtd->eb_size) { - errmsg("bad offset %d or length %d, mtd%d eraseblock size is %d", - offs, len, mtd->num, mtd->eb_size); - errno = EINVAL; - return -1; - } - - /* Seek to the beginning of the eraseblock */ - seek = (off_t)eb * mtd->eb_size + offs; - if (lseek(mtd->fd, seek, SEEK_SET) != seek) { - sys_errmsg("cannot seek mtd%d to offset %llu", - mtd->num, (unsigned long long)seek); - return -1; - } - - while (rd < len) { - ret = read(mtd->fd, buf, len); - if (ret < 0) { - sys_errmsg("cannot read %d bytes from mtd%d (eraseblock %d, offset %d)", - len, mtd->num, eb, offs); - return -1; - } - rd += ret; - } - - return 0; -} - -/** - * mtd_write - write data to an MTD device. - * @mtd: MTD device description object - * @eb: eraseblock to write to - * @offs: offset withing the eraseblock to write to - * @buf: buffer to write - * @len: how many bytes to write - * - * This function writes @len bytes of data to eraseblock @eb and offset @offs - * of the MTD device defined by @mtd. Returns %0 in case of success and %-1 in - * case of failure. - */ -int mtd_write(const struct mtd_info *mtd, int eb, int offs, void *buf, int len) -{ - int ret; - off_t seek; - - if (eb < 0 || eb >= mtd->eb_cnt) { - errmsg("bad eraseblock number %d, mtd%d has %d eraseblocks", - eb, mtd->num, mtd->eb_cnt); - errno = EINVAL; - return -1; - } - if (offs < 0 || offs + len > mtd->eb_size) { - errmsg("bad offset %d or length %d, mtd%d eraseblock size is %d", - offs, len, mtd->num, mtd->eb_size); - errno = EINVAL; - return -1; - } -#if 0 - if (offs % mtd->subpage_size) { - errmsg("write offset %d is not aligned to mtd%d min. I/O size %d", - offs, mtd->num, mtd->subpage_size); - errno = EINVAL; - return -1; - } - if (len % mtd->subpage_size) { - errmsg("write length %d is not aligned to mtd%d min. I/O size %d", - len, mtd->num, mtd->subpage_size); - errno = EINVAL; - return -1; - } -#endif - - /* Seek to the beginning of the eraseblock */ - seek = (off_t)eb * mtd->eb_size + offs; - if (lseek(mtd->fd, seek, SEEK_SET) != seek) { - sys_errmsg("cannot seek mtd%d to offset %llu", - mtd->num, (unsigned long long)seek); - return -1; - } - - ret = write(mtd->fd, buf, len); - if (ret != len) { - sys_errmsg("cannot write %d bytes to mtd%d (eraseblock %d, offset %d)", - len, mtd->num, eb, offs); - return -1; - } - - return 0; -} diff --git a/ubi-utils/new-utils/src/libscan.c b/ubi-utils/new-utils/src/libscan.c deleted file mode 100644 index dc1f083..0000000 --- a/ubi-utils/new-utils/src/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. - */ - -#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 "common.h" -#include "crc32.h" - -#define PROGRAM_NAME "libscan" - -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_info *mtd, 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 hdr; - 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, 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, eb, 0, &hdr, sizeof(struct ubi_ec_hdr));; - if (ret < 0) - goto out_ec; - - /* Check the EC header */ - if (be32_to_cpu(hdr.magic) != UBI_EC_HDR_MAGIC) { - if (all_ff(&hdr, 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 = crc32(UBI_CRC32_INIT, &hdr, UBI_EC_HDR_SIZE_CRC); - if (be32_to_cpu(hdr.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(hdr.hdr_crc)); - continue; - } - - ec = be64_to_cpu(hdr.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(hdr.vid_hdr_offset); - si->data_offs = be32_to_cpu(hdr.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(hdr.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(hdr.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(hdr.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(hdr.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/new-utils/src/libubi.c b/ubi-utils/new-utils/src/libubi.c deleted file mode 100644 index 1aa66d8..0000000 --- a/ubi-utils/new-utils/src/libubi.c +++ /dev/null @@ -1,1206 +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. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <dirent.h> -#include <unistd.h> -#include <sys/ioctl.h> -#include <limits.h> -#include "libubi.h" -#include "libubi_int.h" -#include "common.h" - -#define PROGRAM_NAME "libubi" - -/** - * 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, 50); - if (rd == -1) { - sys_errmsg("cannot read \"%s\"", file); - goto out_error; - } - if (rd == 50) { - errmsg("contents of \"%s\" is too long", file); - errno = EINVAL; - goto out_error; - } - - if (sscanf(buf, "%lld\n", value) != 1) { - /* This must be a UBI bug */ - 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; - } - - /* 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)) { - sys_errmsg("close failed on \"%s\"", file); - return -1; - } - - 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; - } - - *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 - * - * This function returns positive UBI device number 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(int required) -{ - int fd, version; - struct libubi *lib; - - lib = calloc(1, sizeof(struct libubi)); - if (!lib) - return NULL; - - /* TODO: this must be discovered instead */ - lib->sysfs = strdup("/sys"); - if (!lib->sysfs) - goto out_error; - - lib->sysfs_ctrl = mkpath(lib->sysfs, 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(lib->sysfs, SYSFS_UBI); - if (!lib->sysfs_ubi) - goto out_error; - - /* Make sure UBI is present */ - fd = open(lib->sysfs_ubi, O_RDONLY); - if (fd == -1) { - if (required) - errmsg("cannot open \"%s\", UBI does not seem to " - "exist in system", lib->sysfs_ubi); - 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->sysfs); - free(lib); -} - -int ubi_attach_mtd(libubi_t desc, const char *node, - struct ubi_attach_request *req) -{ - int fd, ret; - struct ubi_attach_req r; - - memset(&r, sizeof(struct ubi_attach_req), '\0'); - - desc = desc; - r.ubi_num = req->dev_num; - r.mtd_num = req->mtd_num; - r.vid_hdr_offset = req->vid_hdr_offset; - - 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; - - req->dev_num = r.ubi_num; - -#ifdef UDEV_SETTLE_HACK - if (system("udevsettle") == -1) - return -1; -#endif - - 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_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; -#endif - -out_close: - close(fd); - return ret; -} - -int ubi_node_type(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) { - sys_errmsg("cannot open \"%s\"", node); - return -1; - } - - return 2; - -out_not_ubi: - errmsg("\"%s\" has major:minor %d:%d, but this does not correspond to " - "any UBI device or volume", node, major, minor); - errno = 0; - 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) > 256) { - errmsg("invalid entry in %s: \"%s\"", - lib->sysfs_ubi, dirent->d_name); - 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, sizeof(struct ubi_mkvol_req), '\0'); - - 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; - - fd = open(node, O_RDONLY); - if (fd == -1) - return sys_errmsg("cannot open \"%s\"", node); - - ret = ioctl(fd, UBI_IOCMKVOL, &r); - if (ret == -1) - goto out_close; - - req->vol_id = r.vol_id; - -#ifdef UDEV_SETTLE_HACK - if (system("udevsettle") == -1) - return -1; -#endif - -out_close: - close(fd); - return ret; -} - -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) - goto out_close; - -#ifdef UDEV_SETTLE_HACK - if (system("udevsettle") == -1) - return -1; -#endif - -out_close: - close(fd); - return ret; -} - -int ubi_rnvols(libubi_t desc, const char *node, struct ubi_rnvol_req *rnvol) -{ - int fd, ret; - - fd = open(node, O_RDONLY); - if (fd == -1) - return -1; - ret = ioctl(fd, UBI_IOCRNVOL, rnvol); - if (ret == -1) - goto out_close; - -#ifdef UDEV_SETTLE_HACK - if (system("udevsettle") == -1) - return -1; -#endif - -out_close: - close(fd); - return ret; -} - -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_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, int dtype) -{ - 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 = dtype; - - if (ioctl(fd, UBI_IOCEBCH, &req)) - return -1; - return 0; -} - -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; - - 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) > 256) { - 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_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 = info->avail_lebs * info->leb_size; - info->total_bytes = 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 dev_num; - struct libubi *lib = (struct libubi *)desc; - - 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 (dev_get_major(lib, dev_num, &info->dev_major, &info->dev_minor)) - return -1; - 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 = 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 vol_id, dev_num; - struct libubi *lib = (struct libubi *)desc; - - 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; -} diff --git a/ubi-utils/new-utils/src/libubi_int.h b/ubi-utils/new-utils/src/libubi_int.h deleted file mode 100644 index 2e664b8..0000000 --- a/ubi-utils/new-utils/src/libubi_int.h +++ /dev/null @@ -1,133 +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__ - -#include <string.h> -#include <errno.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. - */ - -#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 - * @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/new-utils/src/libubigen.c b/ubi-utils/new-utils/src/libubigen.c deleted file mode 100644 index 91bb274..0000000 --- a/ubi-utils/new-utils/src/libubigen.c +++ /dev/null @@ -1,330 +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 - */ - -#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" - -#define PROGRAM_NAME "libubigen" - -/** - * 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 - */ -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) -{ - 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->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; -} - -/** - * ubigen_create_empty_vtbl - creates empty volume table. - * - * 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) -{ - 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 = crc32(UBI_CRC32_INIT, &vtbl[i], - UBI_VTBL_RECORD_SIZE_CRC); - vtbl[i].crc = cpu_to_be32(crc); - } - - return vtbl; -} - -/** - * 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) -{ - struct ubi_vtbl_record *vtbl_rec = &vtbl[vi->id]; - uint32_t tmp; - - if (vi->id >= ui->max_volumes) - return errmsg("too high volume id %d, max. volumes is %d", - vi->id, ui->max_volumes); - - if (vi->alignment >= ui->leb_size) - return errmsg("too large alignment %d, max is %d (LEB size)", - vi->alignment, ui->leb_size); - - 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 = crc32(UBI_CRC32_INIT, vtbl_rec, UBI_VTBL_RECORD_SIZE_CRC); - vtbl_rec->crc = cpu_to_be32(tmp); - return 0; -} - -/** - * 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) -{ - 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); - - crc = crc32(UBI_CRC32_INIT, hdr, UBI_EC_HDR_SIZE_CRC); - hdr->hdr_crc = cpu_to_be32(crc); -} - -/** - * 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. - */ -static void 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 = crc32(UBI_CRC32_INIT, data, data_size); - hdr->data_crc = cpu_to_be32(crc); - } - - crc = crc32(UBI_CRC32_INIT, hdr, UBI_VID_HDR_SIZE_CRC); - hdr->hdr_crc = cpu_to_be32(crc); -} - -/** - * ubigen_write_volume - write UBI volume. - * @ui: libubigen information - * @vi: volume information - * @ec: erase coutner 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) -{ - int len = vi->usable_leb_size, rd, lnum = 0; - char inbuf[ui->leb_size], outbuf[ui->peb_size]; - - if (vi->id >= ui->max_volumes) - return errmsg("too high volume id %d, max. volumes is %d", - vi->id, ui->max_volumes); - - if (vi->alignment >= ui->leb_size) - return errmsg("too large alignment %d, max is %d (LEB size)", - vi->alignment, ui->leb_size); - - 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) - return sys_errmsg("cannot read %d bytes from the input file", l); - - l -= rd; - } while (l); - - vid_hdr = (struct ubi_vid_hdr *)(&outbuf[ui->vid_hdr_offs]); - 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) - return sys_errmsg("cannot write %d bytes to the output file", ui->peb_size); - - lnum += 1; - } - - return 0; -} - -/** - * 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) -{ - int ret; - struct ubigen_vol_info vi; - char outbuf[ui->peb_size]; - 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; - - 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 = peb1 * ui->peb_size; - if (lseek(fd, seek, SEEK_SET) != seek) - return sys_errmsg("cannot seek output file"); - ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec1); - init_vid_hdr(ui, &vi, vid_hdr, 0, NULL, 0); - ret = write(fd, outbuf, ui->peb_size); - if (ret != ui->peb_size) - return sys_errmsg("cannot write %d bytes", ui->peb_size); - - seek = peb2 * ui->peb_size; - if (lseek(fd, seek, SEEK_SET) != seek) - return sys_errmsg("cannot seek output file"); - ubigen_init_ec_hdr(ui, (struct ubi_ec_hdr *)outbuf, ec2); - init_vid_hdr(ui, &vi, vid_hdr, 1, NULL, 0); - ret = write(fd, outbuf, ui->peb_size); - if (ret != ui->peb_size) - return sys_errmsg("cannot write %d bytes", ui->peb_size); - - return 0; -} diff --git a/ubi-utils/new-utils/src/ubiattach.c b/ubi-utils/new-utils/src/ubiattach.c deleted file mode 100644 index 1f72620..0000000 --- a/ubi-utils/new-utils/src/ubiattach.c +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2007 Nokia Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * 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., 51 - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * An utility to attach MTD devices to UBI. - * - * Author: Artem Bityutskiy - */ - -#include <stdio.h> -#include <stdint.h> -#include <getopt.h> -#include <stdlib.h> -#include <string.h> - -#include <libubi.h> -#include "common.h" - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubiattach" - -/* The variables below are set by command line arguments */ -struct args { - int devn; - int mtdn; - int vidoffs; - const char *node; -}; - -static struct args args = { - .devn = UBI_DEV_NUM_AUTO, - .mtdn = -1, - .vidoffs = 0, - .node = NULL, -}; - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION - " - a tool to attach MTD device to UBI."; - -static const char *optionsstr = -"-d, --devn=<UBI device number> the number to assign to the newly created UBI device\n" -" (the number is assigned automatically if this is not\n" -" specified\n" -"-m, --mtdn=<MTD device number> MTD device number to attach\n" -"-O, --vid-hdr-offset VID header offset (do not specify this unless you\n" -" really know what you do and the optimal defaults will\n" -" be used)\n" -"-h, --help print help message\n" -"-V, --version print program version"; - -static const char *usage = -"Usage: " PROGRAM_NAME " <UBI control device node file name> [-m <MTD device number>] [-d <UBI device number>]\n" -"\t\t[--mtdn=<MTD device number>] [--devn <UBI device number>]\n" -"Example 1: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 - attach MTD device 0 (mtd0) to UBI\n" -"Example 2: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 -d 3 - attach MTD device 0 (mtd0) to UBI and\n" -" and create UBI device number 3 (ubi3)"; - -static const struct option long_options[] = { - { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, - { .name = "mtdn", .has_arg = 1, .flag = NULL, .val = 'm' }, - { .name = "vid-hdr-offset", .has_arg = 1, .flag = NULL, .val = 'O' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0}, -}; - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - char *endp; - - key = getopt_long(argc, argv, "m:d:O:hV", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'd': - args.devn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.devn < 0) - return errmsg("bad UBI device number: \"%s\"", optarg); - - break; - - case 'm': - args.mtdn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.mtdn < 0) - return errmsg("bad MTD device number: \"%s\"", optarg); - - break; - - case 'O': - args.vidoffs = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.vidoffs <= 0) - return errmsg("bad VID header offset: \"%s\"", optarg); - - break; - - case 'h': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case ':': - return errmsg("parameter is missing"); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - if (optind == argc) - return errmsg("UBI control device name was not specified (use -h for help)"); - else if (optind != argc - 1) - return errmsg("more then one UBI control device specified (use -h for help)"); - - if (args.mtdn == -1) - return errmsg("MTD device number was not specified (use -h for help)"); - - args.node = argv[optind]; - return 0; -} - -int main(int argc, char * const argv[]) -{ - int err; - libubi_t libubi; - struct ubi_info ubi_info; - struct ubi_dev_info dev_info; - struct ubi_attach_request req; - - err = parse_opt(argc, argv); - if (err) - return -1; - - libubi = libubi_open(1); - if (libubi == NULL) - return sys_errmsg("cannot open libubi"); - - /* - * Make sure the kernel is fresh enough and this feature is supported. - */ - err = ubi_get_info(libubi, &ubi_info); - if (err) { - sys_errmsg("cannot get UBI information"); - goto out_libubi; - } - - if (ubi_info.ctrl_major == -1) { - errmsg("MTD attach/detach feature is not supported by your kernel"); - goto out_libubi; - } - - req.dev_num = args.devn; - req.mtd_num = args.mtdn; - req.vid_hdr_offset = args.vidoffs; - - err = ubi_attach_mtd(libubi, args.node, &req); - if (err) { - sys_errmsg("cannot attach mtd%d", args.mtdn); - goto out_libubi; - } - - /* Print some information about the new UBI device */ - err = ubi_get_dev_info1(libubi, req.dev_num, &dev_info); - if (err) { - sys_errmsg("cannot get information about newly created UBI device"); - goto out_libubi; - } - - printf("UBI device number %d, total %d LEBs (", dev_info.dev_num, dev_info.total_lebs); - ubiutils_print_bytes(dev_info.total_bytes, 0); - printf("), available %d LEBs (", dev_info.avail_lebs); - ubiutils_print_bytes(dev_info.avail_bytes, 0); - printf("), LEB size "); - ubiutils_print_bytes(dev_info.leb_size, 1); - printf("\n"); - - libubi_close(libubi); - return 0; - -out_libubi: - libubi_close(libubi); - return -1; -} diff --git a/ubi-utils/new-utils/src/ubicrc32.c b/ubi-utils/new-utils/src/ubicrc32.c deleted file mode 100644 index d39af10..0000000 --- a/ubi-utils/new-utils/src/ubicrc32.c +++ /dev/null @@ -1,124 +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. - */ - -/* - * Calculate CRC32 with UBI start value (0xFFFFFFFF) for a given binary image. - * - * Author: Oliver Lohmann - */ - -#include <stdio.h> -#include <stdint.h> -#include <stdlib.h> -#include <getopt.h> -#include <unistd.h> -#include <mtd/ubi-media.h> - -#include "crc32.h" -#include "common.h" - -#define BUFSIZE 4096 - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubicrc32" - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION - " - a tool to calculate CRC32 with UBI start value (0xFFFFFFFF)"; - -static const char *optionsstr = -"-h, --help print help message\n" -"-V, --version print program version"; - -static const char *usage = -"Usage: " PROGRAM_NAME " <file to calculate CRC32 for> [-h] [--help]"; - -static const struct option long_options[] = { - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0}, -}; - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - - key = getopt_long(argc, argv, "hV", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'h': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case ':': - return errmsg("parameter is missing"); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - return 0; -} - -int main(int argc, char * const argv[]) -{ - int err = 0; - uint32_t crc = UBI_CRC32_INIT; - char buf[BUFSIZE]; - FILE *fp; - - if (argc > 1) { - fp = fopen(argv[1], "r"); - if (!fp) - return sys_errmsg("cannot open \"%s\"", argv[1]); - } else - fp = stdin; - - err = parse_opt(argc, argv); - if (err) - return err; - - while (!feof(fp)) { - size_t read; - - read = fread(buf, 1, BUFSIZE, fp); - if (ferror(fp)) { - sys_errmsg("cannot read input file"); - err = -1; - goto out_close; - } - crc = crc32(crc, buf, read); - } - - printf("0x%08x\n", crc); - -out_close: - if (fp != stdin) - fclose(fp); - return err; -} diff --git a/ubi-utils/new-utils/src/ubidetach.c b/ubi-utils/new-utils/src/ubidetach.c deleted file mode 100644 index 50670d0..0000000 --- a/ubi-utils/new-utils/src/ubidetach.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2007 Nokia Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * 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., 51 - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * An utility to delete UBI devices (detach MTD devices from UBI). - * - * Author: Artem Bityutskiy - */ - -#include <stdio.h> -#include <stdint.h> -#include <getopt.h> -#include <stdlib.h> -#include <string.h> - -#include <libubi.h> -#include "common.h" - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubidetach" - -/* The variables below are set by command line arguments */ -struct args { - int devn; - int mtdn; - const char *node; -}; - -static struct args args = { - .devn = UBI_DEV_NUM_AUTO, - .mtdn = -1, - .node = NULL, -}; - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION -" - a tool to remove UBI devices (detach MTD devices from UBI)"; - -static const char *optionsstr = -"-d, --devn=<UBI device number> UBI device number to delete\n" -"-m, --mtdn=<MTD device number> or altrnatively, MTD device number to detach -\n" -" this will delete corresponding UBI device\n" -"-h, --help print help message\n" -"-V, --version print program version"; - -static const char *usage = -"Usage: " PROGRAM_NAME "<UBI control device node file name> [-d <UBI device number>] [-m <MTD device number>]\n" -"\t\t[--devn <UBI device number>] [--mtdn=<MTD device number>]\n" -"Example 1: " PROGRAM_NAME " /dev/ubi_ctrl -d 2 - delete UBI device 2 (ubi2)\n" -"Example 2: " PROGRAM_NAME " /dev/ubi_ctrl -m 0 - detach MTD device 0 (mtd0)"; - -static const struct option long_options[] = { - { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, - { .name = "mtdn", .has_arg = 1, .flag = NULL, .val = 'm' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0}, -}; - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - char *endp; - - key = getopt_long(argc, argv, "m:d:hV", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'd': - args.devn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.devn < 0) - return errmsg("bad UBI device number: \"%s\"", optarg); - - break; - - case 'm': - args.mtdn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.mtdn < 0) - return errmsg("bad MTD device number: \"%s\"", optarg); - - break; - - case 'h': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case ':': - return errmsg("parameter is missing"); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - if (optind == argc) - return errmsg("UBI control device name was not specified (use -h for help)"); - else if (optind != argc - 1) - return errmsg("more then one UBI control device specified (use -h for help)"); - - if (args.mtdn == -1 && args.devn == -1) - return errmsg("neither MTD nor UBI devices were specified (use -h for help)"); - - if (args.mtdn != -1 && args.devn != -1) - return errmsg("specify either MTD or UBI device (use -h for help)"); - - args.node = argv[optind]; - return 0; -} - -int main(int argc, char * const argv[]) -{ - int err; - libubi_t libubi; - struct ubi_info ubi_info; - - err = parse_opt(argc, argv); - if (err) - return -1; - - libubi = libubi_open(1); - if (libubi == NULL) - return sys_errmsg("cannot open libubi"); - - /* - * Make sure the kernel is fresh enough and this feature is supported. - */ - err = ubi_get_info(libubi, &ubi_info); - if (err) { - sys_errmsg("cannot get UBI information"); - goto out_libubi; - } - - if (ubi_info.ctrl_major == -1) { - errmsg("MTD detach/detach feature is not supported by your kernel"); - goto out_libubi; - } - - if (args.devn != -1) { - err = ubi_remove_dev(libubi, args.node, args.devn); - if (err) { - sys_errmsg("cannot remove ubi%d", args.devn); - goto out_libubi; - } - } else { - err = ubi_detach_mtd(libubi, args.node, args.mtdn); - if (err) { - sys_errmsg("cannot detach mtd%d", args.mtdn); - goto out_libubi; - } - } - - libubi_close(libubi); - return 0; - -out_libubi: - libubi_close(libubi); - return -1; -} - diff --git a/ubi-utils/new-utils/src/ubiformat.c b/ubi-utils/new-utils/src/ubiformat.c deleted file mode 100644 index 0074c7a..0000000 --- a/ubi-utils/new-utils/src/ubiformat.c +++ /dev/null @@ -1,780 +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. - */ - -/* - * An utility to format MTD devices into UBI and flash UBI images. - * - * Author: Artem Bityutskiy - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <stdint.h> -#include <stdlib.h> -#include <getopt.h> -#include <fcntl.h> - -#include <libubi.h> -#include <libmtd.h> -#include <libscan.h> -#include <libubigen.h> -#include <mtd_swab.h> -#include "crc32.h" -#include "common.h" - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubiformat" - -/* The variables below are set by command line arguments */ -struct args { - unsigned int yes:1; - unsigned int quiet:1; - unsigned int verbose:1; - unsigned int override_ec:1; - unsigned int novtbl:1; - int subpage_size; - int vid_hdr_offs; - int ubi_ver; - off_t image_sz; - long long ec; - const char *image; - const char *node; -}; - -static struct args args = -{ - .ubi_ver = 1, -}; - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION - " - a tool to format MTD devices and flash UBI images"; - -static const char *optionsstr = -"-s, --sub-page-size=<bytes> minimum input/output unit used for UBI\n" -" headers, e.g. sub-page size in case of NAND\n" -" flash (equivalent to the minimum input/output\n" -" unit size by default)\n" -"-O, --vid-hdr-offset=<offs> offset if the VID header from start of the\n" -" physical eraseblock (default is the next\n" -" minimum I/O unit or sub-page after the EC\n" -" header)\n" -"-n, --no-volume-table only erase all eraseblock and preserve erase\n" -" counters, do not write empty volume table\n" -"-f, --flash-image=<file> flash image file, or '-' for stdin\n" -"-S, --image-size=<bytes> bytes in input, if not reading from file\n" -"-e, --erase-counter=<value> use <value> as the erase counter value for all\n" -" eraseblocks\n" -"-y, --yes assume the answer is \"yes\" for all question\n" -" this program would otherwise ask\n" -"-q, --quiet suppress progress percentage information\n" -"-v, --verbose be verbose\n" -"-x, --ubi-ver=<num> UBI version number to put to EC headers\n" -" (default is 1)\n" -"-h, -?, --help print help message\n" -"-V, --version print program version\n"; - -static const char *usage = -"Usage: " PROGRAM_NAME " <MTD device node file name> [-h] [-V] [-y] [-q] [-v]\n" -"\t\t\t[-x <num>] [-E <value>] [-s <bytes>] [-O <offs>] [-n]\n" -"\t\t\t[--help] [--version] [--yes] [--verbose] [--quiet]\n" -"\t\t\t[--ec=<value>] [--vid-hdr-offset=<offs>]\n" -"\t\t\t[--ubi-ver=<num>] [--no-volume-table]\n" -"\t\t\t[--flash-image=<file>] [--image-size=<bytes>]\n\n" - -"Example 1: " PROGRAM_NAME " /dev/mtd0 -y - format MTD device number 0 and do\n" -" not ask questions.\n" -"Example 2: " PROGRAM_NAME " /dev/mtd0 -q -e 0 - format MTD device number 0,\n" -" be quiet and force erase counter value 0."; - -static const struct option long_options[] = { - { .name = "sub-page-size", .has_arg = 1, .flag = NULL, .val = 's' }, - { .name = "vid-hdr-offset", .has_arg = 1, .flag = NULL, .val = 'O' }, - { .name = "no-volume-table", .has_arg = 0, .flag = NULL, .val = 'n' }, - { .name = "flash-image", .has_arg = 1, .flag = NULL, .val = 'f' }, - { .name = "image-size", .has_arg = 1, .flag = NULL, .val = 'S' }, - { .name = "yes", .has_arg = 0, .flag = NULL, .val = 'y' }, - { .name = "erase-counter", .has_arg = 1, .flag = NULL, .val = 'e' }, - { .name = "quiet", .has_arg = 0, .flag = NULL, .val = 'q' }, - { .name = "verbose", .has_arg = 0, .flag = NULL, .val = 'v' }, - { .name = "ubi-ver", .has_arg = 1, .flag = NULL, .val = 'x' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0}, -}; - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - char *endp; - - key = getopt_long(argc, argv, "nh?Vyqve:x:s:O:f:S:", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 's': - args.subpage_size = ubiutils_get_bytes(optarg); - if (args.subpage_size <= 0) - return errmsg("bad sub-page size: \"%s\"", optarg); - if (!is_power_of_2(args.subpage_size)) - return errmsg("sub-page size should be power of 2"); - break; - - case 'O': - args.vid_hdr_offs = strtoul(optarg, &endp, 0); - if (args.vid_hdr_offs <= 0 || *endp != '\0' || endp == optarg) - return errmsg("bad VID header offset: \"%s\"", optarg); - break; - - case 'e': - args.ec = strtoull(optarg, &endp, 0); - if (args.ec <= 0 || *endp != '\0' || endp == optarg) - return errmsg("bad erase counter value: \"%s\"", optarg); - if (args.ec >= EC_MAX) - return errmsg("too high erase %llu, counter, max is %u", args.ec, EC_MAX); - args.override_ec = 1; - break; - - case 'f': - args.image = optarg; - break; - - case 'S': - args.image_sz = ubiutils_get_bytes(optarg); - if (args.image_sz <= 0) - return errmsg("bad image-size: \"%s\"", optarg); - break; - - case 'n': - args.novtbl = 1; - break; - - case 'y': - args.yes = 1; - break; - - case 'q': - args.quiet = 1; - break; - - case 'x': - args.ubi_ver = strtoul(optarg, &endp, 0); - if (args.ubi_ver < 0 || *endp != '\0' || endp == optarg) - return errmsg("bad UBI version: \"%s\"", optarg); - break; - - case 'v': - args.verbose = 1; - break; - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case 'h': - case '?': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case ':': - return errmsg("parameter is missing"); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - if (args.quiet && args.verbose) - return errmsg("using \"-q\" and \"-v\" at the same time does not make sense"); - - if (optind == argc) - return errmsg("MTD device name was not specified (use -h for help)"); - else if (optind != argc - 1) - return errmsg("more then one MTD device specified (use -h for help)"); - - if (args.image && args.novtbl) - return errmsg("-n cannot be used together with -f"); - - args.node = argv[optind]; - return 0; -} - -static int want_exit(void) -{ - char buf[4]; - - while (1) { - normsg_cont("continue? (yes/no) "); - if (scanf("%3s", buf) == EOF) { - sys_errmsg("scanf returned unexpected EOF, assume \"yes\""); - return 1; - } - if (!strncmp(buf, "yes", 3) || !strncmp(buf, "y", 1)) - return 0; - if (!strncmp(buf, "no", 2) || !strncmp(buf, "n", 1)) - return 1; - } -} - -static int answer_is_yes(void) -{ - char buf[4]; - - while (1) { - if (scanf("%3s", buf) == EOF) { - sys_errmsg("scanf returned unexpected EOF, assume \"no\""); - return 0; - } - if (!strncmp(buf, "yes", 3) || !strncmp(buf, "y", 1)) - return 1; - if (!strncmp(buf, "no", 2) || !strncmp(buf, "n", 1)) - return 0; - } -} - -static void print_bad_eraseblocks(const struct mtd_info *mtd, - const struct ubi_scan_info *si) -{ - int first = 1, eb; - - if (si->bad_cnt == 0) - return; - - normsg_cont("bad eraseblocks: "); - for (eb = 0; eb < mtd->eb_cnt; eb++) { - if (si->ec[eb] != EB_BAD) - continue; - if (first) { - printf("%d", eb); - first = 0; - } else - printf(", %d", eb); - } - printf("\n"); -} - -static int change_ec(struct ubi_ec_hdr *hdr, long long ec) -{ - uint32_t crc; - - /* Check the EC header */ - if (be32_to_cpu(hdr->magic) != UBI_EC_HDR_MAGIC) - return errmsg("bad UBI magic %#08x, should be %#08x", - be32_to_cpu(hdr->magic), UBI_EC_HDR_MAGIC); - - crc = crc32(UBI_CRC32_INIT, hdr, UBI_EC_HDR_SIZE_CRC); - if (be32_to_cpu(hdr->hdr_crc) != crc) - return errmsg("bad CRC %#08x, should be %#08x\n", - crc, be32_to_cpu(hdr->hdr_crc)); - - hdr->ec = cpu_to_be64(ec); - crc = crc32(UBI_CRC32_INIT, hdr, UBI_EC_HDR_SIZE_CRC); - hdr->hdr_crc = cpu_to_be32(crc); - - return 0; -} - -static int drop_ffs(const struct mtd_info *mtd, const void *buf, int len) -{ - int i; - - for (i = len - 1; i >= 0; i--) - if (((const uint8_t *)buf)[i] != 0xFF) - break; - - /* The resulting length must be aligned to the minimum flash I/O size */ - len = i + 1; - len = (len + mtd->min_io_size - 1) / mtd->min_io_size; - len *= mtd->min_io_size; - return len; -} - -static int open_file(off_t *sz) -{ - int fd; - - if (!strcmp(args.image, "-")) { - if (args.image_sz == 0) - return errmsg("must use '-S' with non-zero value when reading from stdin"); - - *sz = args.image_sz; - fd = dup(STDIN_FILENO); - if (fd < 0) - return sys_errmsg("failed to dup stdin"); - } else { - struct stat st; - - if (stat(args.image, &st)) - return sys_errmsg("cannot open \"%s\"", args.image); - - *sz = st.st_size; - fd = open(args.image, O_RDONLY); - if (fd == -1) - return sys_errmsg("cannot open \"%s\"", args.image); - } - - return fd; -} - -static int read_all(int fd, void *buf, size_t len) -{ - while (len > 0) { - ssize_t l = read(fd, buf, len); - if (l == 0) - return errmsg("eof reached; %zu bytes remaining", len); - else if (l > 0) { - buf += l; - len -= l; - } else if (errno == EINTR || errno == EAGAIN) - continue; - else - return sys_errmsg("reading failed; %zu bytes remaining", len); - } - - return 0; -} - -static int flash_image(const struct mtd_info *mtd, struct ubi_scan_info *si) -{ - int fd, img_ebs, eb, written_ebs = 0, divisor; - off_t st_size; - - fd = open_file(&st_size); - if (fd < 0) - return fd; - - img_ebs = st_size / mtd->eb_size; - - if (img_ebs > si->good_cnt) { - sys_errmsg("file \"%s\" is too large (%lld bytes)", - args.image, (long long)st_size); - goto out_close; - } - - if (st_size % mtd->eb_size) { - return sys_errmsg("file \"%s\" (size %lld bytes) is not multiple of eraseblock size (%d bytes)", - args.image, (long long)st_size, mtd->eb_size); - goto out_close; - } - - verbose(args.verbose, "will write %d eraseblocks", img_ebs); - divisor = img_ebs; - for (eb = 0; eb < mtd->eb_cnt; eb++) { - int err, new_len; - char buf[mtd->eb_size]; - long long ec; - - if (!args.quiet && !args.verbose) { - printf("\r" PROGRAM_NAME ": flashing eraseblock %d -- %2lld %% complete ", - eb, (long long)(eb + 1) * 100 / divisor); - fflush(stdout); - } - - if (si->ec[eb] == EB_BAD) { - divisor += 1; - continue; - } - - if (args.verbose) { - normsg_cont("eraseblock %d: erase", eb); - fflush(stdout); - } - - err = mtd_erase(mtd, eb); - if (err) { - sys_errmsg("failed to erase eraseblock %d", eb); - goto out_close; - } - - err = read_all(fd, buf, mtd->eb_size); - if (err) { - sys_errmsg("failed to read eraseblock %d from \"%s\"", - written_ebs, args.image); - goto out_close; - } - - - if (si->ec[eb] <= EC_MAX) - ec = si->ec[eb] + 1; - else if (!args.override_ec) - ec = si->mean_ec; - else - ec = args.ec; - - if (args.verbose) { - printf(", change EC to %lld", ec); - fflush(stdout); - } - - err = change_ec((struct ubi_ec_hdr *)buf, ec); - if (err) { - errmsg("bad EC header at eraseblock %d of \"%s\"", - written_ebs, args.image); - goto out_close; - } - - if (args.verbose) { - printf(", write data\n"); - fflush(stdout); - } - - new_len = drop_ffs(mtd, buf, mtd->eb_size); - - err = mtd_write(mtd, eb, 0, buf, new_len); - if (err) { - sys_errmsg("cannot write eraseblock %d", eb); - goto out_close; - } - if (++written_ebs >= img_ebs) - break; - } - - if (!args.quiet && !args.verbose) - printf("\n"); - close(fd); - return eb + 1; - -out_close: - close(fd); - return -1; -} - -static int format(const struct mtd_info *mtd, const struct ubigen_info *ui, - const struct ubi_scan_info *si, int start_eb, int novtbl) -{ - int eb, err, write_size; - struct ubi_ec_hdr *hdr; - struct ubi_vtbl_record *vtbl; - int eb1 = -1, eb2 = -1; - long long ec1 = -1, ec2 = -1; - - write_size = UBI_EC_HDR_SIZE + mtd->subpage_size - 1; - write_size /= mtd->subpage_size; - write_size *= mtd->subpage_size; - hdr = malloc(write_size); - if (!hdr) - return sys_errmsg("cannot allocate %d bytes of memory", write_size); - - memset(hdr, 0xFF, write_size); - - for (eb = start_eb; eb < mtd->eb_cnt; eb++) { - long long ec; - - if (!args.quiet && !args.verbose) { - printf("\r" PROGRAM_NAME ": formatting eraseblock %d -- %2lld %% complete ", - eb, (long long)(eb + 1 - start_eb) * 100 / (mtd->eb_cnt - start_eb)); - fflush(stdout); - } - - if (si->ec[eb] == EB_BAD) - continue; - - if (si->ec[eb] <= EC_MAX) - ec = si->ec[eb] + 1; - else if (!args.override_ec) - ec = si->mean_ec; - else - ec = args.ec; - ubigen_init_ec_hdr(ui, hdr, ec); - - if (args.verbose) { - normsg_cont("eraseblock %d: erase", eb); - fflush(stdout); - } - - err = mtd_erase(mtd, eb); - if (err) { - if (!args.quiet) - printf("\n"); - sys_errmsg("failed to erase eraseblock %d", eb); - goto out_free; - } - - if ((eb1 == -1 || eb2 == -1) && !novtbl) { - if (eb1 == -1) { - eb1 = eb; - ec1 = ec; - } else if (eb2 == -1) { - eb2 = eb; - ec2 = ec; - } - if (args.verbose) - printf(", do not write EC, leave for vtbl\n"); - continue; - } - - if (args.verbose) { - printf(", write EC %lld\n", ec); - fflush(stdout); - } - - err = mtd_write(mtd, eb, 0, hdr, write_size); - if (err) { - if (!args.quiet && !args.verbose) - printf("\n"); - sys_errmsg("cannot write EC header (%d bytes buffer) to eraseblock %d", - write_size, eb); - if (args.subpage_size != mtd->min_io_size) - normsg("may be %d is incorrect?", args.subpage_size); - goto out_free; - } - } - - if (!args.quiet && !args.verbose) - printf("\n"); - - if (!novtbl) { - if (eb1 == -1 || eb2 == -1) { - errmsg("no eraseblocks for volume table"); - goto out_free; - } - - verbose(args.verbose, "write volume table to eraseblocks %d and %d", eb1, eb2); - vtbl = ubigen_create_empty_vtbl(ui); - if (!vtbl) - goto out_free; - - err = ubigen_write_layout_vol(ui, eb1, eb2, ec1, ec2, vtbl, mtd->fd); - free(vtbl); - if (err) { - errmsg("cannot write layout volume"); - goto out_free; - } - } - - free(hdr); - return 0; - -out_free: - free(hdr); - return -1; -} - -int main(int argc, char * const argv[]) -{ - int err, verbose; - struct mtd_info mtd; - libubi_t libubi; - struct ubigen_info ui; - struct ubi_scan_info *si; - - err = parse_opt(argc, argv); - if (err) - return -1; - - err = mtd_get_info(args.node, &mtd); - if (err) - return errmsg("cannot get information about \"%s\"", args.node); - - if (args.subpage_size == 0) - args.subpage_size = mtd.min_io_size; - else { - if (args.subpage_size > mtd.min_io_size) { - errmsg("sub-page cannot be larger than min. I/O unit"); - goto out_close; - } - - if (mtd.min_io_size % args.subpage_size) { - errmsg("min. I/O unit size should be multiple of sub-page size"); - goto out_close; - } - } - - /* Validate VID header offset if it was specified */ - if (args.vid_hdr_offs != 0) { - if (args.vid_hdr_offs % 8) { - errmsg("VID header offset has to be multiple of min. I/O unit size"); - goto out_close; - } - if (args.vid_hdr_offs + (int)UBI_VID_HDR_SIZE > mtd.eb_size) { - errmsg("bad VID header offset"); - goto out_close; - } - } - - /* - * Because of MTD interface limitations 'mtd_get_info()' cannot get - * sub-page so we force the user to pass it via the command line. Let's - * hope the user passed us something sane. - */ - mtd.subpage_size = args.subpage_size; - - if (mtd.rdonly) { - errmsg("mtd%d (%s) is a read-only device", mtd.num, args.node); - goto out_close; - } - - /* Make sure this MTD device is not attached to UBI */ - libubi = libubi_open(0); - if (libubi) { - int ubi_dev_num; - - err = mtd_num2ubi_dev(libubi, mtd.num, &ubi_dev_num); - libubi_close(libubi); - if (!err) { - errmsg("please, first detach mtd%d (%s) from ubi%d", - mtd.num, args.node, ubi_dev_num); - goto out_close; - } - } - - if (!args.quiet) { - normsg_cont("mtd%d (%s), size ", mtd.num, mtd.type_str); - ubiutils_print_bytes(mtd.size, 1); - printf(", %d eraseblocks of ", mtd.eb_size); - ubiutils_print_bytes(mtd.eb_size, 1); - printf(", min. I/O size %d bytes\n", mtd.min_io_size); - } - - if (args.quiet) - verbose = 0; - else if (args.verbose) - verbose = 2; - else - verbose = 1; - err = ubi_scan(&mtd, &si, verbose); - if (err) { - errmsg("failed to scan mtd%d (%s)", mtd.num, args.node); - goto out_close; - } - - if (si->good_cnt == 0) { - errmsg("all %d eraseblocks are bad", si->bad_cnt); - goto out_free; - } - - if (si->good_cnt < 2 && (!args.novtbl || args.image)) { - errmsg("too few non-bad eraseblocks (%d) on mtd%d", si->good_cnt, mtd.num); - goto out_free; - } - - if (!args.quiet) { - if (si->ok_cnt) - normsg("%d eraseblocks have valid erase counter, mean value is %lld", - si->ok_cnt, si->mean_ec); - if (si->empty_cnt) - normsg("%d eraseblocks are supposedly empty", si->empty_cnt); - if (si->corrupted_cnt) - normsg("%d corrupted erase counters", si->corrupted_cnt); - print_bad_eraseblocks(&mtd, si); - } - - if (si->alien_cnt) { - if (!args.yes || !args.quiet) - warnmsg("%d of %d eraseblocks contain non-ubifs data", - si->alien_cnt, si->good_cnt); - if (!args.yes && want_exit()) { - if (args.yes && !args.quiet) - printf("yes\n"); - goto out_free; - } - } - - if (!args.override_ec && si->empty_cnt < si->good_cnt) { - int percent = ((double)si->ok_cnt)/si->good_cnt * 100; - - /* - * Make sure the majority of eraseblocks have valid - * erase counters. - */ - if (percent < 50) { - if (!args.yes || !args.quiet) - warnmsg("only %d of %d eraseblocks have valid erase counter", - si->ok_cnt, si->good_cnt); - normsg("erase counter 0 will be used for all eraseblocks"); - normsg("note, arbitrary erase counter value may be specified using -e option"); - if (!args.yes && want_exit()) { - if (args.yes && !args.quiet) - printf("yes\n"); - goto out_free; - } - args.ec = 0; - args.override_ec = 1; - } else if (percent < 95) { - if (!args.yes || !args.quiet) - warnmsg("only %d of %d eraseblocks have valid erase counter", - si->ok_cnt, si->good_cnt); - normsg("mean erase counter %lld will be used for the rest of eraseblock", - si->mean_ec); - if (!args.yes && want_exit()) { - if (args.yes && !args.quiet) - printf("yes\n"); - goto out_free; - } - args.ec = si->mean_ec; - args.override_ec = 1; - } - } - - if (!args.quiet && args.override_ec) - normsg("use erase counter %lld for all eraseblocks", args.ec); - - ubigen_info_init(&ui, mtd.eb_size, mtd.min_io_size, args.subpage_size, - args.vid_hdr_offs, args.ubi_ver); - - if (si->vid_hdr_offs != -1 && ui.vid_hdr_offs != si->vid_hdr_offs) { - /* - * Hmm, what we read from flash and what we calculated using - * min. I/O unit size and sub-page size differs. - */ - if (!args.yes || !args.quiet) { - warnmsg("VID header and data offsets on flash are %d and %d, " - "which is different to calculated offsets %d and %d", - si->vid_hdr_offs, si->data_offs, ui.vid_hdr_offs, - ui.data_offs); - normsg_cont("use new offsets %d and %d? (yes/no) ", - si->vid_hdr_offs, si->data_offs); - } - if (args.yes || answer_is_yes()) { - if (args.yes && !args.quiet) - printf("yes\n"); - } else { - ui.vid_hdr_offs = si->vid_hdr_offs; - ui.data_offs = si->data_offs; - } - } - - if (args.image) { - err = flash_image(&mtd, si); - if (err < 0) - goto out_free; - - err = format(&mtd, &ui, si, err, 1); - if (err) - goto out_free; - } else { - err = format(&mtd, &ui, si, 0, args.novtbl); - if (err) - goto out_free; - } - - ubi_scan_free(si); - close(mtd.fd); - return 0; - -out_free: - ubi_scan_free(si); -out_close: - close(mtd.fd); - return -1; -} diff --git a/ubi-utils/new-utils/src/ubimkvol.c b/ubi-utils/new-utils/src/ubimkvol.c deleted file mode 100644 index 820c9d8..0000000 --- a/ubi-utils/new-utils/src/ubimkvol.c +++ /dev/null @@ -1,313 +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. - */ - -/* - * An utility to create UBI volumes. - * - * Authors: Artem Bityutskiy <dedekind@infradead.org> - * Frank Haverkamp <haver@vnet.ibm.com> - */ - -#include <stdio.h> -#include <stdint.h> -#include <getopt.h> -#include <stdlib.h> -#include <string.h> - -#include <libubi.h> -#include "common.h" - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubimkvol" - -/* The variables below are set by command line arguments */ -struct args { - int vol_id; - int vol_type; - long long bytes; - int lebs; - int alignment; - const char *name; - const char *node; - int maxavs; - /* For deprecated -d option handling */ - int devn; - char dev_name[256]; -}; - -static struct args args = { - .vol_type = UBI_DYNAMIC_VOLUME, - .bytes = -1, - .lebs = -1, - .alignment = 1, - .vol_id = UBI_VOL_NUM_AUTO, - .devn = -1, -}; - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION - " - a tool to create UBI volumes."; - -static const char *optionsstr = -"-a, --alignment=<alignment> volume alignment (default is 1)\n" -"-n, --vol_id=<volume ID> UBI volume ID, if not specified, the volume ID\n" -" will be assigned automatically\n" -"-N, --name=<name> volume name\n" -"-s, --size=<bytes> volume size volume size in bytes, kilobytes (KiB)\n" -" or megabytes (MiB)\n" -"-S, --lebs=<LEBs count> alternative way to give volume size in logical\n" -" eraseblocks\n" -"-m, --maxavsize set volume size to maximum available size\n" -"-t, --type=<static|dynamic> volume type (dynamic, static), default is dynamic\n" -"-h, -?, --help print help message\n" -"-V, --version print program version\n\n" -"The following is a compatibility option which is deprecated, do not use it\n" -"-d, --devn=<devn> UBI device number - may be used instead of the UBI\n" -" device node name in which case the utility assumes\n" -" that the device node is \"/dev/ubi<devn>\""; - - -static const char *usage = -"Usage: " PROGRAM_NAME " <UBI device node file name> [-h] [-a <alignment>] [-n <volume ID>] [-N <name>]\n" -"\t\t\t[-s <bytes>] [-S <LEBs>] [-t <static|dynamic>] [-V] [-m]\n" -"\t\t\t[--alignment=<alignment>][--vol_id=<volume ID>] [--name=<name>]\n" -"\t\t\t[--size=<bytes>] [--lebs=<LEBs>] [--type=<static|dynamic>] [--help]\n" -"\t\t\t[--version] [--maxavsize]\n\n" -"Example: " PROGRAM_NAME " /dev/ubi0 -s 20MiB -N config_data - create a 20 Megabytes volume\n" -" named \"config_data\" on UBI device /dev/ubi0."; - -static const struct option long_options[] = { - { .name = "alignment", .has_arg = 1, .flag = NULL, .val = 'a' }, - { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, - { .name = "name", .has_arg = 1, .flag = NULL, .val = 'N' }, - { .name = "size", .has_arg = 1, .flag = NULL, .val = 's' }, - { .name = "lebs", .has_arg = 1, .flag = NULL, .val = 'S' }, - { .name = "type", .has_arg = 1, .flag = NULL, .val = 't' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { .name = "maxavsize", .has_arg = 0, .flag = NULL, .val = 'm' }, - /* Deprecated -d option */ - { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, - { NULL, 0, NULL, 0}, -}; - -static int param_sanity_check(void) -{ - int len; - - if (args.bytes == -1 && !args.maxavs && args.lebs == -1) - return errmsg("volume size was not specified (use -h for help)"); - - if ((args.bytes != -1 && (args.maxavs || args.lebs != -1)) || - (args.lebs != -1 && (args.maxavs || args.bytes != -1)) || - (args.maxavs && (args.bytes != -1 || args.lebs != -1))) - return errmsg("size specified with more then one option"); - - if (args.name == NULL) - return errmsg("volume name was not specified (use -h for help)"); - - len = strlen(args.name); - if (len > UBI_MAX_VOLUME_NAME) - return errmsg("too long name (%d symbols), max is %d", len, UBI_MAX_VOLUME_NAME); - - return 0; -} - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - char *endp; - - key = getopt_long(argc, argv, "a:n:N:s:S:t:h?Vmd:", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 't': - if (!strcmp(optarg, "dynamic")) - args.vol_type = UBI_DYNAMIC_VOLUME; - else if (!strcmp(optarg, "static")) - args.vol_type = UBI_STATIC_VOLUME; - else - return errmsg("bad volume type: \"%s\"", optarg); - break; - - case 's': - args.bytes = ubiutils_get_bytes(optarg); - if (args.bytes <= 0) - return errmsg("bad volume size: \"%s\"", optarg); - break; - - case 'S': - args.lebs = strtoull(optarg, &endp, 0); - if (endp == optarg || args.lebs <= 0 || *endp != '\0') - return errmsg("bad LEB count: \"%s\"", optarg); - break; - - case 'a': - args.alignment = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.alignment <= 0) - return errmsg("bad volume alignment: \"%s\"", optarg); - break; - - case 'n': - args.vol_id = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.vol_id < 0) - return errmsg("bad volume ID: " "\"%s\"", optarg); - break; - - case 'd': - /* Handle deprecated -d option */ - warnmsg("-d is depricated and will be removed, do not use it"); - args.devn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.devn < 0) - return errmsg("bad UBI device number: " "\"%s\"", optarg); - break; - - case 'N': - args.name = optarg; - break; - - case 'h': - case '?': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case 'm': - args.maxavs = 1; - break; - - case ':': - return errmsg("parameter is missing"); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - /* Handle deprecated -d option */ - if (args.devn != -1) { - sprintf(args.dev_name, "/dev/ubi%d", args.devn); - args.node = args.dev_name; - } else { - if (optind == argc) - return errmsg("UBI device name was not specified (use -h for help)"); - else if (optind != argc - 1) - return errmsg("more then one UBI device specified (use -h for help)"); - - args.node = argv[optind]; - } - - if (param_sanity_check()) - return -1; - - return 0; -} - -int main(int argc, char * const argv[]) -{ - int err; - libubi_t libubi; - struct ubi_dev_info dev_info; - struct ubi_vol_info vol_info; - struct ubi_mkvol_request req; - - err = parse_opt(argc, argv); - if (err) - return err; - - libubi = libubi_open(1); - if (!libubi) - return sys_errmsg("cannot open libubi"); - - err = ubi_node_type(libubi, args.node); - if (err == 2) { - errmsg("\"%s\" is an UBI volume node, not an UBI device node", - args.node); - goto out_libubi; - } else if (err < 0) { - errmsg("\"%s\" is not an UBI device node", args.node); - goto out_libubi; - } - - err = ubi_get_dev_info(libubi, args.node, &dev_info); - if (err) { - sys_errmsg("cannot get information about UBI device \"%s\"", - args.node); - goto out_libubi; - } - - if (dev_info.avail_bytes == 0) { - errmsg("UBI device does not have free logical eraseblocks"); - goto out_libubi; - } - - if (args.maxavs) { - args.bytes = dev_info.avail_bytes; - printf("Set volume size to %lld\n", args.bytes); - } - - if (args.lebs != -1) { - args.bytes = dev_info.leb_size; - args.bytes -= dev_info.leb_size % args.alignment; - args.bytes *= args.lebs; - } - - req.vol_id = args.vol_id; - req.alignment = args.alignment; - req.bytes = args.bytes; - req.vol_type = args.vol_type; - req.name = args.name; - - err = ubi_mkvol(libubi, args.node, &req); - if (err < 0) { - sys_errmsg("cannot UBI create volume"); - goto out_libubi; - } - - args.vol_id = req.vol_id; - - /* Print information about the created device */ - err = ubi_get_vol_info1(libubi, dev_info.dev_num, args.vol_id, &vol_info); - if (err) { - sys_errmsg("cannot get information about newly created UBI volume"); - goto out_libubi; - } - - printf("Volume ID %d, size %d LEBs (", vol_info.vol_id, vol_info.rsvd_lebs); - ubiutils_print_bytes(vol_info.rsvd_bytes, 0); - printf("), LEB size "); - ubiutils_print_bytes(vol_info.leb_size, 1); - printf(", %s, name \"%s\", alignment %d\n", - req.vol_type == UBI_DYNAMIC_VOLUME ? "dynamic" : "static", - vol_info.name, vol_info.alignment); - - libubi_close(libubi); - return 0; - -out_libubi: - libubi_close(libubi); - return -1; -} diff --git a/ubi-utils/new-utils/src/ubinfo.c b/ubi-utils/new-utils/src/ubinfo.c deleted file mode 100644 index 536ec01..0000000 --- a/ubi-utils/new-utils/src/ubinfo.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (C) 2007, 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 version 2 as published by - * the Free Software Foundation. - * - * 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., 51 - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * An utility to get UBI information. - * - * Author: Artem Bityutskiy - */ - -#include <stdio.h> -#include <stdint.h> -#include <getopt.h> -#include <stdlib.h> -#include <string.h> - -#include <libubi.h> -#include "common.h" - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubinfo" - -/* The variables below are set by command line arguments */ -struct args { - int devn; - int vol_id; - int all; - const char *node; -}; - -static struct args args = { - .vol_id = -1, - .devn = -1, - .all = 0, - .node = NULL, -}; - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION - " - a tool to print UBI information."; - -static const char *optionsstr = -"-d, --devn=<UBI device number> UBI device number to get information about\n" -"-n, --vol_id=<volume ID> ID of UBI volume to print information about\n" -"-a, --all print information about all devices and volumes,\n" -" or about all volumes if the UBI device was\n" -" specified\n" -"-h, --help print help message\n" -"-V, --version print program version"; - -static const char *usage = -"Usage 1: " PROGRAM_NAME " [-d <UBI device number>] [-n <volume ID>] [-a] [-h] [-V] [--vol_id=<volume ID>]\n" -"\t\t[--devn <UBI device number>] [--all] [--help] [--version]\n" -"Usage 2: " PROGRAM_NAME " <UBI device node file name> [-a] [-h] [-V] [--all] [--help] [--version]\n" -"Usage 3: " PROGRAM_NAME " <UBI volume node file name> [-h] [-V] [--help] [--version]\n\n" -"Example 1: " PROGRAM_NAME " - (no arguments) print general UBI information\n" -"Example 2: " PROGRAM_NAME " -d 1 - print information about UBI device number 1\n" -"Example 3: " PROGRAM_NAME " /dev/ubi0 -a - print information about all volumes of UBI\n" -" device /dev/ubi0\n" -"Example 4: " PROGRAM_NAME " /dev/ubi1_0 - print information about UBI volume /dev/ubi1_0\n" -"Example 5: " PROGRAM_NAME " -a - print all information\n"; - -static const struct option long_options[] = { - { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, - { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, - { .name = "all", .has_arg = 0, .flag = NULL, .val = 'a' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0}, -}; - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - char *endp; - - key = getopt_long(argc, argv, "an:d:hV", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'a': - args.all = 1; - break; - - case 'n': - args.vol_id = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.vol_id < 0) - return errmsg("bad volume ID: " "\"%s\"", optarg); - break; - - case 'd': - args.devn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.devn < 0) - return errmsg("bad UBI device number: \"%s\"", optarg); - - break; - - case 'h': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case ':': - return errmsg("parameter is missing"); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - if (optind == argc - 1) - args.node = argv[optind]; - else if (optind < argc) - return errmsg("more then one UBI devices specified (use -h for help)"); - - return 0; -} - -static int translate_dev(libubi_t libubi, const char *node) -{ - int err; - - err = ubi_node_type(libubi, node); - if (err == -1) { - if (errno) - return errmsg("unrecognized device node \"%s\"", node); - return errmsg("\"%s\" does not correspond to any UBI device or volume", node); - } - - if (err == 1) { - struct ubi_dev_info dev_info; - - err = ubi_get_dev_info(libubi, node, &dev_info); - if (err) - return sys_errmsg("cannot get information about UBI device \"%s\"", node); - - args.devn = dev_info.dev_num; - } else { - struct ubi_vol_info vol_info; - - err = ubi_get_vol_info(libubi, node, &vol_info); - if (err) - return sys_errmsg("cannot get information about UBI volume \"%s\"", node); - - if (args.vol_id != -1) - return errmsg("both volume character device node (\"%s\") and " - "volume ID (%d) are specify, use only one of them" - "(use -h for help)", node, args.vol_id); - - args.devn = vol_info.dev_num; - args.vol_id = vol_info.vol_id; - } - - return 0; -} - -static int print_vol_info(libubi_t libubi, int dev_num, int vol_id) -{ - int err; - struct ubi_vol_info vol_info; - - err = ubi_get_vol_info1(libubi, dev_num, vol_id, &vol_info); - if (err) - return sys_errmsg("cannot get information about UBI volume %d on ubi%d", - vol_id, dev_num); - - printf("Volume ID: %d (on ubi%d)\n", vol_info.vol_id, vol_info.dev_num); - printf("Type: %s\n", - vol_info.type == UBI_DYNAMIC_VOLUME ? "dynamic" : "static"); - printf("Alignment: %d\n", vol_info.alignment); - - printf("Size: %d LEBs (", vol_info.rsvd_lebs); - ubiutils_print_bytes(vol_info.rsvd_bytes, 0); - printf(")\n"); - - if (vol_info.type == UBI_STATIC_VOLUME) { - printf("Data bytes: "); - ubiutils_print_bytes(vol_info.data_bytes, 1); - printf("\n"); - } - printf("State: %s\n", vol_info.corrupted ? "corrupted" : "OK"); - printf("Name: %s\n", vol_info.name); - printf("Character device major/minor: %d:%d\n", - vol_info.major, vol_info.minor); - - return 0; -} - -static int print_dev_info(libubi_t libubi, int dev_num, int all) -{ - int i, err, first = 1; - struct ubi_dev_info dev_info; - struct ubi_vol_info vol_info; - - err = ubi_get_dev_info1(libubi, dev_num, &dev_info); - if (err) - return sys_errmsg("cannot get information about UBI device %d", dev_num); - - printf("ubi%d:\n", dev_info.dev_num); - printf("Volumes count: %d\n", dev_info.vol_count); - printf("Logical eraseblock size: %d\n", dev_info.leb_size); - - printf("Total amount of logical eraseblocks: %d (", dev_info.total_lebs); - ubiutils_print_bytes(dev_info.total_bytes, 0); - printf(")\n"); - - printf("Amount of available logical eraseblocks: %d (", dev_info.avail_lebs); - ubiutils_print_bytes(dev_info.avail_bytes, 0); - printf(")\n"); - - printf("Maximum count of volumes %d\n", dev_info.max_vol_count); - printf("Count of bad physical eraseblocks: %d\n", dev_info.bad_count); - printf("Count of reserved physical eraseblocks: %d\n", dev_info.bad_rsvd); - printf("Current maximum erase counter value: %lld\n", dev_info.max_ec); - printf("Minimum input/output unit size: %d bytes\n", dev_info.min_io_size); - printf("Character device major/minor: %d:%d\n", - dev_info.major, dev_info.minor); - - if (dev_info.vol_count == 0) - return 0; - - printf("Present volumes: "); - for (i = dev_info.lowest_vol_id; - i <= dev_info.highest_vol_id; i++) { - err = ubi_get_vol_info1(libubi, dev_info.dev_num, i, &vol_info); - if (err == -1) { - if (errno == ENOENT) - continue; - - return sys_errmsg("libubi failed to probe volume %d on ubi%d", - i, dev_info.dev_num); - } - - if (!first) - printf(", %d", i); - else { - printf("%d", i); - first = 0; - } - } - printf("\n"); - - if (!all) - return 0; - - first = 1; - printf("\n"); - - for (i = dev_info.lowest_vol_id; - i <= dev_info.highest_vol_id; i++) { - if(!first) - printf("-----------------------------------\n"); - err = ubi_get_vol_info1(libubi, dev_info.dev_num, i, &vol_info); - if (err == -1) { - if (errno == ENOENT) - continue; - - return sys_errmsg("libubi failed to probe volume %d on ubi%d", - i, dev_info.dev_num); - } - first = 0; - - err = print_vol_info(libubi, dev_info.dev_num, i); - if (err) - return err; - } - - return 0; -} - -static int print_general_info(libubi_t libubi, int all) -{ - int i, err, first = 1; - struct ubi_info ubi_info; - struct ubi_dev_info dev_info; - - err = ubi_get_info(libubi, &ubi_info); - if (err) - return sys_errmsg("cannot get UBI information"); - - printf("UBI version: %d\n", ubi_info.version); - printf("Count of UBI devices: %d\n", ubi_info.dev_count); - if (ubi_info.ctrl_major != -1) - printf("UBI control device major/minor: %d:%d\n", - ubi_info.ctrl_major, ubi_info.ctrl_minor); - else - printf("UBI control device is not supported by this kernel\n"); - - if (ubi_info.dev_count == 0) - return 0; - - printf("Present UBI devices: "); - for (i = ubi_info.lowest_dev_num; - i <= ubi_info.highest_dev_num; i++) { - err = ubi_get_dev_info1(libubi, i, &dev_info); - if (err == -1) { - if (errno == ENOENT) - continue; - - return sys_errmsg("libubi failed to probe UBI device %d", i); - } - - if (!first) - printf(", ubi%d", i); - else { - printf("ubi%d", i); - first = 0; - } - } - printf("\n"); - - if (!all) - return 0; - - first = 1; - printf("\n"); - - for (i = ubi_info.lowest_dev_num; - i <= ubi_info.highest_dev_num; i++) { - if(!first) - printf("\n===================================\n\n"); - err = ubi_get_dev_info1(libubi, i, &dev_info); - if (err == -1) { - if (errno == ENOENT) - continue; - - return sys_errmsg("libubi failed to probe UBI device %d", i); - } - first = 0; - - err = print_dev_info(libubi, i, all); - if (err) - return err; - } - return 0; -} - -int main(int argc, char * const argv[]) -{ - int err; - libubi_t libubi; - - err = parse_opt(argc, argv); - if (err) - return -1; - - if (!args.node && args.devn != -1) - return errmsg("specify either device number or node file (use -h for help)"); - - libubi = libubi_open(1); - if (libubi == NULL) - return sys_errmsg("cannot open libubi"); - - if (args.node) { - /* - * A character device was specified, translate this into UBI - * device number and volume ID. - */ - err = translate_dev(libubi, args.node); - if (err) - goto out_libubi; - } - - if (args.vol_id != -1 && args.devn == -1) { - errmsg("volume ID is specified, but UBI device number is not " - "(use -h for help)\n"); - goto out_libubi; - } - - if (args.devn != -1 && args.vol_id != -1) { - print_vol_info(libubi, args.devn, args.vol_id); - goto out; - } - - if (args.devn == -1 && args.vol_id == -1) - err = print_general_info(libubi, args.all); - else if (args.devn != -1 && args.vol_id == -1) - err = print_dev_info(libubi, args.devn, args.all); - - if (err) - goto out_libubi; - -out: - libubi_close(libubi); - return 0; - -out_libubi: - libubi_close(libubi); - return -1; -} diff --git a/ubi-utils/new-utils/src/ubinize.c b/ubi-utils/new-utils/src/ubinize.c deleted file mode 100644 index 0762aa8..0000000 --- a/ubi-utils/new-utils/src/ubinize.c +++ /dev/null @@ -1,612 +0,0 @@ -/* - * Copyright (C) 2008 Nokia Corporation - * 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. - */ - -/* - * Generate UBI images. - * - * Authors: Artem Bityutskiy - * Oliver Lohmann - */ - -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <stdlib.h> -#include <getopt.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> - -#include <mtd/ubi-media.h> -#include <libubigen.h> -#include <libiniparser.h> -#include "common.h" - -#define PROGRAM_VERSION "1.1" -#define PROGRAM_NAME "ubinize" - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION -" - a tool to generate UBI images. An UBI image may contain one or more UBI " -"volumes which have to be defined in the input configuration ini-file. The " -"ini file defines all the UBI volumes - their characteristics and the and the " -"contents, but it does not define the characteristics of the flash the UBI " -"image is generated for. Instead, the flash characteristics are defined via " -"the command-line options. Note, if not sure about some of the command-line " -"parameters, do not specify them and let the utility to use default values."; - -static const char *optionsstr = -"-o, --output=<file name> output file name\n" -"-p, --peb-size=<bytes> size of the physical eraseblock of the flash\n" -" this UBI image is created for in bytes,\n" -" kilobytes (KiB), or megabytes (MiB)\n" -" (mandatory parameter)\n" -"-m, --min-io-size=<bytes> minimum input/output unit size of the flash\n" -" in bytes\n" -"-s, --sub-page-size=<bytes> minimum input/output unit used for UBI\n" -" headers, e.g. sub-page size in case of NAND\n" -" flash (equivalent to the minimum input/output\n" -" unit size by default)\n" -"-O, --vid-hdr-offset=<num> offset if the VID header from start of the\n" -" physical eraseblock (default is the next\n" -" minimum I/O unit or sub-page after the EC\n" -" header)\n" -"-e, --erase-counter=<num> the erase counter value to put to EC headers\n" -" (default is 0)\n" -"-x, --ubi-ver=<num> UBI version number to put to EC headers\n" -" (default is 1)\n" -"-v, --verbose be verbose\n" -"-h, --help print help message\n" -"-V, --version print program version"; - -static const char *usage = -"Usage: " PROGRAM_NAME " [-o filename] [-h] [-V] [--output=<filename>] [--help]\n" -"\t\t[--version] ini-file\n" -"Example: " PROGRAM_NAME " -o ubi.img -p 16KiB -m 512 -s 256 cfg.ini - create UBI image\n" -" 'ubi.img' as described by configuration file 'cfg.ini'"; - -static const char *ini_doc = "INI-file format.\n" -"The input configuration ini-file describes all the volumes which have to\n" -"be included to the output UBI image. Each volume is described in its own\n" -"section which may be named arbitrarily. The section consists on\n" -"\"key=value\" pairs, for example:\n\n" -"[jffs2-volume]\n" -"mode=ubi\n" -"image=../jffs2.img\n" -"vol_id=1\n" -"vol_size=30MiB\n" -"vol_type=dynamic\n" -"vol_name=jffs2_volume\n" -"vol_flags=autoresize\n" -"vol_alignment=1\n\n" -"This example configuration file tells the utility to create an UBI image\n" -"with one volume with ID 1, volume size 30MiB, the volume is dynamic, has\n" -"name \"jffs2_volume\", \"autoresize\" volume flag, and alignment 1. The\n" -"\"image=../jffs2.img\" line tells the utility to take the contents of the\n" -"volume from the \"../jffs2.img\" file. The size of the image file has to be\n" -"less or equivalent to the volume size (30MiB). The \"mode=ubi\" line is\n" -"mandatory and just tells that the section describes an UBI volume - other\n" -"section modes may be added in the future.\n" -"Notes:\n" -" * size in vol_size might be specified kilobytes (KiB), megabytes (MiB),\n" -" gigabytes (GiB) or bytes (no modifier);\n" -" * if \"vol_size\" key is absent, the volume size is assumed to be\n" -" equivalent to the size of the image file (defined by \"image\" key);\n" -" * if the \"image\" is absent, the volume is assumed to be empty;\n" -" * volume alignment must not be greater than the logical eraseblock size;\n" -" * one ini file may contain arbitrary number of sections, the utility will\n" -" put all the volumes which are described by these section to the output\n" -" UBI image file."; - -struct option long_options[] = { - { .name = "output", .has_arg = 1, .flag = NULL, .val = 'o' }, - { .name = "peb-size", .has_arg = 1, .flag = NULL, .val = 'p' }, - { .name = "min-io-size", .has_arg = 1, .flag = NULL, .val = 'm' }, - { .name = "sub-page-size", .has_arg = 1, .flag = NULL, .val = 's' }, - { .name = "vid-hdr-offset", .has_arg = 1, .flag = NULL, .val = 'O' }, - { .name = "erase-counter", .has_arg = 1, .flag = NULL, .val = 'e' }, - { .name = "ubi-ver", .has_arg = 1, .flag = NULL, .val = 'x' }, - { .name = "verbose", .has_arg = 0, .flag = NULL, .val = 'v' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { NULL, 0, NULL, 0} -}; - -struct args { - const char *f_in; - const char *f_out; - int out_fd; - int peb_size; - int min_io_size; - int subpage_size; - int vid_hdr_offs; - int ec; - int ubi_ver; - int verbose; - dictionary *dict; -}; - -static struct args args = { - .peb_size = -1, - .min_io_size = -1, - .subpage_size = -1, - .ubi_ver = 1, -}; - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - char *endp; - - key = getopt_long(argc, argv, "o:p:m:s:O:e:x:vhV", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 'o': - args.out_fd = open(optarg, O_CREAT | O_TRUNC | O_WRONLY, - S_IWUSR | S_IRUSR | S_IRGRP | S_IWGRP | S_IROTH); - if (args.out_fd == -1) - return sys_errmsg("cannot open file \"%s\"", optarg); - args.f_out = optarg; - break; - - case 'p': - args.peb_size = ubiutils_get_bytes(optarg); - if (args.peb_size <= 0) - return errmsg("bad physical eraseblock size: \"%s\"", optarg); - break; - - case 'm': - args.min_io_size = ubiutils_get_bytes(optarg); - if (args.min_io_size <= 0) - return errmsg("bad min. I/O unit size: \"%s\"", optarg); - if (!is_power_of_2(args.min_io_size)) - return errmsg("min. I/O unit size should be power of 2"); - break; - - case 's': - args.subpage_size = ubiutils_get_bytes(optarg); - if (args.subpage_size <= 0) - return errmsg("bad sub-page size: \"%s\"", optarg); - if (!is_power_of_2(args.subpage_size)) - return errmsg("sub-page size should be power of 2"); - break; - - case 'O': - args.vid_hdr_offs = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.vid_hdr_offs < 0) - return errmsg("bad VID header offset: \"%s\"", optarg); - break; - - case 'e': - args.ec = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.ec < 0) - return errmsg("bad erase counter value: \"%s\"", optarg); - break; - - case 'x': - args.ubi_ver = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.ubi_ver < 0) - return errmsg("bad UBI version: \"%s\"", optarg); - break; - - case 'v': - args.verbose = 1; - break; - - case 'h': - ubiutils_print_text(stderr, doc, 80); - fprintf(stderr, "\n%s\n\n", ini_doc); - fprintf(stderr, "%s\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - if (optind == argc) - return errmsg("input configuration file was not specified (use -h for help)"); - - if (optind != argc - 1) - return errmsg("more then one configuration file was specified (use -h for help)"); - - args.f_in = argv[optind]; - - if (args.peb_size < 0) - return errmsg("physical eraseblock size was not specified (use -h for help)"); - - if (args.peb_size > 1024*1024) - return errmsg("too high physical eraseblock size %d", args.peb_size); - - if (args.min_io_size < 0) - return errmsg("min. I/O unit size was not specified (use -h for help)"); - - if (args.subpage_size < 0) - args.subpage_size = args.min_io_size; - - if (args.subpage_size > args.min_io_size) - return errmsg("sub-page cannot be larger then min. I/O unit"); - - if (args.peb_size % args.min_io_size) - return errmsg("physical eraseblock should be multiple of min. I/O units"); - - if (args.min_io_size % args.subpage_size) - return errmsg("min. I/O unit size should be multiple of sub-page size"); - - if (!args.f_out) - return errmsg("output file was not specified (use -h for help)"); - - if (args.vid_hdr_offs) { - if (args.vid_hdr_offs + (int)UBI_VID_HDR_SIZE >= args.peb_size) - return errmsg("bad VID header position"); - if (args.vid_hdr_offs % 8) - return errmsg("VID header offset has to be multiple of min. I/O unit size"); - } - - return 0; -} - -static int read_section(const struct ubigen_info *ui, const char *sname, - struct ubigen_vol_info *vi, const char **img, - struct stat *st) -{ - char buf[256]; - const char *p; - - *img = NULL; - - if (strlen(sname) > 128) - return errmsg("too long section name \"%s\"", sname); - - /* Make sure mode is UBI, otherwise ignore this section */ - sprintf(buf, "%s:mode", sname); - p = iniparser_getstring(args.dict, buf, NULL); - if (!p) { - errmsg("\"mode\" key not found in section \"%s\"", sname); - errmsg("the \"mode\" key is mandatory and has to be " - "\"mode=ubi\" if the section describes an UBI volume"); - return -1; - } - - /* If mode is not UBI, skip this section */ - if (strcmp(p, "ubi")) { - verbose(args.verbose, "skip non-ubi section \"%s\"", sname); - return 1; - } - - verbose(args.verbose, "mode=ubi, keep parsing"); - - /* Fetch volume type */ - sprintf(buf, "%s:vol_type", sname); - p = iniparser_getstring(args.dict, buf, NULL); - if (!p) { - normsg("volume type was not specified in " - "section \"%s\", assume \"dynamic\"\n", sname); - vi->type = UBI_VID_DYNAMIC; - } else { - if (!strcmp(p, "static")) - vi->type = UBI_VID_STATIC; - else if (!strcmp(p, "dynamic")) - vi->type = UBI_VID_DYNAMIC; - else - return errmsg("invalid volume type \"%s\" in section \"%s\"", - p, sname); - } - - verbose(args.verbose, "volume type: %s", - vi->type == UBI_VID_DYNAMIC ? "dynamic" : "static"); - - /* Fetch the name of the volume image file */ - sprintf(buf, "%s:image", sname); - p = iniparser_getstring(args.dict, buf, NULL); - if (p) { - *img = p; - if (stat(p, st)) - return sys_errmsg("cannot stat \"%s\" referred from section \"%s\"", - p, sname); - if (st->st_size == 0) - return errmsg("empty file \"%s\" referred from section \"%s\"", - p, sname); - } else if (vi->type == UBI_VID_STATIC) - return errmsg("image is not specified for static volume in section \"%s\"", - sname); - - /* Fetch volume id */ - sprintf(buf, "%s:vol_id", sname); - vi->id = iniparser_getint(args.dict, buf, -1); - if (vi->id == -1) - return errmsg("\"vol_id\" key not found in section \"%s\"", sname); - if (vi->id < 0) - return errmsg("negative volume ID %d in section \"%s\"", - vi->id, sname); - if (vi->id >= ui->max_volumes) - return errmsg("too high volume ID %d in section \"%s\", max. is %d", - vi->id, sname, ui->max_volumes); - - verbose(args.verbose, "volume ID: %d", vi->id); - - /* Fetch volume size */ - sprintf(buf, "%s:vol_size", sname); - p = iniparser_getstring(args.dict, buf, NULL); - if (p) { - vi->bytes = ubiutils_get_bytes(p); - if (vi->bytes <= 0) - return errmsg("bad \"vol_size\" key value \"%s\" (section \"%s\")", - p, sname); - - /* Make sure the image size is not larger than volume size */ - if (*img && st->st_size > vi->bytes) - return errmsg("error in section \"%s\": size of the image file " - "\"%s\" is %lld, which is larger than volume size %lld", - sname, *img, (long long)st->st_size, vi->bytes); - verbose(args.verbose, "volume size: %lld bytes", vi->bytes); - } else { - struct stat st; - - if (!*img) - return errmsg("neither image file (\"image=\") nor volume size " - "(\"vol_size=\") specified in section \"%s\"", sname); - - if (stat(*img, &st)) - return sys_errmsg("cannot stat \"%s\"", *img); - - vi->bytes = st.st_size; - - if (vi->bytes == 0) - return errmsg("file \"%s\" referred from section \"%s\" is empty", - *img, sname); - - normsg_cont("volume size was not specified in section \"%s\", assume" - " minimum to fit image \"%s\"", sname, *img); - ubiutils_print_bytes(vi->bytes, 1); - printf("\n"); - } - - /* Fetch volume name */ - sprintf(buf, "%s:vol_name", sname); - p = iniparser_getstring(args.dict, buf, NULL); - if (!p) - return errmsg("\"vol_name\" key not found in section \"%s\"", sname); - - vi->name = p; - vi->name_len = strlen(p); - if (vi->name_len > UBI_VOL_NAME_MAX) - return errmsg("too long volume name in section \"%s\", max. is %d characters", - vi->name, UBI_VOL_NAME_MAX); - - verbose(args.verbose, "volume name: %s", p); - - /* Fetch volume alignment */ - sprintf(buf, "%s:vol_alignment", sname); - vi->alignment = iniparser_getint(args.dict, buf, -1); - if (vi->alignment == -1) - vi->alignment = 1; - else if (vi->id < 0) - return errmsg("negative volume alignement %d in section \"%s\"", - vi->alignment, sname); - - verbose(args.verbose, "volume alignment: %d", vi->alignment); - - /* Fetch volume flags */ - sprintf(buf, "%s:vol_flags", sname); - p = iniparser_getstring(args.dict, buf, NULL); - if (p) { - if (!strcmp(p, "autoresize")) { - verbose(args.verbose, "autoresize flags found"); - vi->flags |= UBI_VTBL_AUTORESIZE_FLG; - } else { - return errmsg("unknown flags \"%s\" in section \"%s\"", - p, sname); - } - } - - /* Initialize the rest of the volume information */ - vi->data_pad = ui->leb_size % vi->alignment; - vi->usable_leb_size = ui->leb_size - vi->data_pad; - if (vi->type == UBI_VID_DYNAMIC) - vi->used_ebs = (vi->bytes + vi->usable_leb_size - 1) / vi->usable_leb_size; - else - vi->used_ebs = (st->st_size + vi->usable_leb_size - 1) / vi->usable_leb_size; - vi->compat = 0; - return 0; -} - -int main(int argc, char * const argv[]) -{ - int err = -1, sects, i, autoresize_was_already = 0; - struct ubigen_info ui; - struct ubi_vtbl_record *vtbl; - struct ubigen_vol_info *vi; - off_t seek; - - err = parse_opt(argc, argv); - if (err) - return -1; - - ubigen_info_init(&ui, args.peb_size, args.min_io_size, - args.subpage_size, args.vid_hdr_offs, - args.ubi_ver); - - verbose(args.verbose, "LEB size: %d", ui.leb_size); - verbose(args.verbose, "PEB size: %d", ui.peb_size); - verbose(args.verbose, "min. I/O size: %d", ui.min_io_size); - verbose(args.verbose, "sub-page size: %d", args.subpage_size); - verbose(args.verbose, "VID offset: %d", ui.vid_hdr_offs); - verbose(args.verbose, "data offset: %d", ui.data_offs); - - vtbl = ubigen_create_empty_vtbl(&ui); - if (!vtbl) - goto out; - - args.dict = iniparser_load(args.f_in); - if (!args.dict) { - errmsg("cannot load the input ini file \"%s\"", args.f_in); - goto out_vtbl; - } - - verbose(args.verbose, "loaded the ini-file \"%s\"", args.f_in); - - /* Each section describes one volume */ - sects = iniparser_getnsec(args.dict); - if (sects == -1) { - errmsg("ini-file parsing error (iniparser_getnsec)"); - goto out_dict; - } - - verbose(args.verbose, "count of sections: %d", sects); - if (sects == 0) { - errmsg("no sections found the ini-file \"%s\"", args.f_in); - goto out_dict; - } - - if (sects > ui.max_volumes) { - errmsg("too many sections (%d) in the ini-file \"%s\"", - sects, args.f_in); - normsg("each section corresponds to an UBI volume, maximum " - "count of volumes is %d", ui.max_volumes); - goto out_dict; - } - - vi = calloc(sizeof(struct ubigen_vol_info), sects); - if (!vi) { - errmsg("cannot allocate memory"); - goto out_dict; - } - - /* - * Skip 2 PEBs at the beginning of the file for the volume table which - * will be written later. - */ - seek = ui.peb_size * 2; - if (lseek(args.out_fd, seek, SEEK_SET) != seek) { - sys_errmsg("cannot seek file \"%s\"", args.f_out); - goto out_free; - } - - for (i = 0; i < sects; i++) { - const char *sname = iniparser_getsecname(args.dict, i); - const char *img = NULL; - struct stat st; - int fd, j; - - if (!sname) { - errmsg("ini-file parsing error (iniparser_getsecname)"); - goto out_free; - } - - if (args.verbose) - printf("\n"); - verbose(args.verbose, "parsing section \"%s\"", sname); - - err = read_section(&ui, sname, &vi[i], &img, &st); - if (err == -1) - goto out_free; - - verbose(args.verbose, "adding volume %d", vi[i].id); - - /* - * Make sure that volume ID and name is unique and that only - * one volume has auto-resize flag - */ - for (j = 0; j < i; j++) { - if (vi[i].id == vi[j].id) { - errmsg("volume IDs must be unique, but ID %d " - "in section \"%s\" is not", - vi[i].id, sname); - goto out_free; - } - - if (!strcmp(vi[i].name, vi[j].name)) { - errmsg("volume name must be unique, but name " - "\"%s\" in section \"%s\" is not", - vi[i].name, sname); - goto out_free; - } - } - - if (vi[i].flags & UBI_VTBL_AUTORESIZE_FLG) { - if (autoresize_was_already) - return errmsg("only one volume is allowed " - "to have auto-resize flag"); - autoresize_was_already = 1; - } - - err = ubigen_add_volume(&ui, &vi[i], vtbl); - if (err) { - errmsg("cannot add volume for section \"%s\"", sname); - goto out_free; - } - - if (img) { - fd = open(img, O_RDONLY); - if (fd == -1) { - sys_errmsg("cannot open \"%s\"", img); - goto out_free; - } - - verbose(args.verbose, "writing volume %d", vi[i].id); - verbose(args.verbose, "image file: %s", img); - - err = ubigen_write_volume(&ui, &vi[i], args.ec, st.st_size, fd, args.out_fd); - close(fd); - if (err) { - errmsg("cannot write volume for section \"%s\"", sname); - goto out_free; - } - } - - if (args.verbose) - printf("\n"); - } - - verbose(args.verbose, "writing layout volume"); - - err = ubigen_write_layout_vol(&ui, 0, 1, args.ec, args.ec, vtbl, args.out_fd); - if (err) { - errmsg("cannot write layout volume"); - goto out_free; - } - - verbose(args.verbose, "done"); - - free(vi); - iniparser_freedict(args.dict); - free(vtbl); - close(args.out_fd); - return 0; - -out_free: - free(vi); -out_dict: - iniparser_freedict(args.dict); -out_vtbl: - free(vtbl); -out: - close(args.out_fd); - remove(args.f_out); - return err; -} diff --git a/ubi-utils/new-utils/src/ubirename.c b/ubi-utils/new-utils/src/ubirename.c deleted file mode 100644 index 8f33718..0000000 --- a/ubi-utils/new-utils/src/ubirename.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2008 Logitech. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * 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., 51 - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -/* - * An utility to get rename UBI volumes. - * - * Author: Richard Titmuss - */ - -#include <stdio.h> -#include <stdint.h> -#include <getopt.h> -#include <stdlib.h> -#include <string.h> - -#include <libubi.h> -#include "common.h" - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubirename" - -static const char *usage = -"Usage: " PROGRAM_NAME " <UBI device node file name> [<old name> <new name>|...]\n\n" -"Example: " PROGRAM_NAME "/dev/ubi0 A B C D - rename volume A to B, and C to D\n\n" -"This utility allows re-naming several volumes in one go atomically.\n" -"For example, if you have volumes A and B, then you may rename A into B\n" -"and B into A at one go, and the operation will be atomic. This allows\n" -"implementing atomic UBI volumes upgrades. E.g., if you have volume A\n" -"and want to upgrade it atomically, you create a temporary volume B,\n" -"put your new data to B, then rename A to B and B to A, and then you\n" -"may remove old volume B.\n" -"It is also allowed to re-name multiple volumes at a time, but 16 max.\n" -"renames at once, which means you may specify up to 32 volume names.\n" -"If you have volumes A and B, and re-name A to B, bud do not re-name\n" -"B to something else in the same request, old volume B will be removed\n" -"and A will be renamed into B.\n"; - -static int get_vol_id(libubi_t libubi, struct ubi_dev_info *dev_info, - char *name) -{ - int err, i; - struct ubi_vol_info vol_info; - - for (i=dev_info->lowest_vol_id; i<=dev_info->highest_vol_id; i++) { - err = ubi_get_vol_info1(libubi, dev_info->dev_num, i, &vol_info); - if (err == -1) { - if (errno == ENOENT) - continue; - return -1; - } - - if (strcmp(name, vol_info.name) == 0) - return vol_info.vol_id; - } - - return -1; -} - -int main(int argc, char * const argv[]) -{ - int i, err; - int count = 0; - libubi_t libubi; - struct ubi_dev_info dev_info; - struct ubi_rnvol_req rnvol; - const char *node; - - if (argc < 3 || (argc & 1) == 1) { - errmsg("too few arguments"); - fprintf(stderr, "%s\n", usage); - return -1; - } - - if (argc > UBI_MAX_RNVOL + 2) { - errmsg("too many volumes to re-name, max. is %d", - UBI_MAX_RNVOL); - return -1; - } - - node = argv[1]; - libubi = libubi_open(1); - if (!libubi) - return sys_errmsg("cannot open libubi"); - - err = ubi_node_type(libubi, node); - if (err == 2) { - errmsg("\"%s\" is an UBI volume node, not an UBI device node", - node); - goto out_libubi; - } else if (err < 0) { - errmsg("\"%s\" is not an UBI device node", node); - goto out_libubi; - } - - err = ubi_get_dev_info(libubi, node, &dev_info); - if (err == -1) { - sys_errmsg("cannot get information about UBI device \"%s\"", node); - goto out_libubi; - } - - for (i = 2; i < argc; i += 2) { - err = get_vol_id(libubi, &dev_info, argv[i]); - if (err == -1) { - errmsg("\"%s\" volume not found", argv[i]); - goto out_libubi; - } - - rnvol.ents[count].vol_id = err; - rnvol.ents[count].name_len = strlen(argv[i + 1]); - strcpy(rnvol.ents[count++].name, argv[i + 1]); - } - - rnvol.count = count; - - err = ubi_rnvols(libubi, node, &rnvol); - if (err == -1) { - sys_errmsg("cannot rename volumes"); - goto out_libubi; - } - - libubi_close(libubi); - return 0; - -out_libubi: - libubi_close(libubi); - return -1; -} diff --git a/ubi-utils/new-utils/src/ubirmvol.c b/ubi-utils/new-utils/src/ubirmvol.c deleted file mode 100644 index a4cf1df..0000000 --- a/ubi-utils/new-utils/src/ubirmvol.c +++ /dev/null @@ -1,230 +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. - */ - -/* - * An utility to remove UBI volumes. - * - * Authors: Artem Bityutskiy <dedekind@infradead.org> - * Frank Haverkamp <haver@vnet.ibm.com> - */ - -#include <stdio.h> -#include <stdint.h> -#include <getopt.h> -#include <stdlib.h> -#include <string.h> - -#include <libubi.h> -#include "common.h" - -#define PROGRAM_VERSION "1.0" -#define PROGRAM_NAME "ubirmvol" - -/* The variables below are set by command line arguments */ -struct args { - int vol_id; - const char *node; - const char *name; - /* For deprecated -d option handling */ - int devn; - char dev_name[256]; -}; - -static struct args args = { - .vol_id = -1, - .devn = -1, -}; - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION - " - a tool to remove UBI volumes."; - -static const char *optionsstr = -"-n, --vol_id=<volume id> volume ID to remove\n" -"-N, --name=<volume name> volume name to remove\n" -"-h, -?, --help print help message\n" -"-V, --version print program version\n\n" -"The following is a compatibility option which is deprecated, do not use it\n" -"-d, --devn=<devn> UBI device number - may be used instead of the UBI\n" -" device node name in which case the utility assumes\n" -" that the device node is \"/dev/ubi<devn>\""; - -static const char *usage = -"Usage: " PROGRAM_NAME " <UBI device node file name> [-n <volume id>] [--vol_id=<volume id>]\n\n" -" [-N <volume name>] [--name=<volume name>] [-h] [--help]\n\n" -"Example: " PROGRAM_NAME "/dev/ubi0 -n 1 - remove UBI volume 1 from UBI device corresponding\n" -" to /dev/ubi0\n" -" " PROGRAM_NAME "/dev/ubi0 -N my_vol - remove UBI named \"my_vol\" from UBI device\n" -" corresponding to /dev/ubi0"; - -static const struct option long_options[] = { - { .name = "vol_id", .has_arg = 1, .flag = NULL, .val = 'n' }, - { .name = "name", .has_arg = 1, .flag = NULL, .val = 'N' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - /* Deprecated -d option */ - { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, - { NULL, 0, NULL, 0}, -}; - -static int param_sanity_check(void) -{ - if (args.vol_id == -1 && !args.name) { - errmsg("please, specify either volume ID or volume name"); - return -1; - } - - if (args.vol_id != -1 && args.name) { - errmsg("please, specify either volume ID or volume name, not both"); - return -1; - } - - return 0; -} - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - char *endp; - - key = getopt_long(argc, argv, "n:N:h?Vd:", long_options, NULL); - if (key == -1) - break; - - switch (key) { - - case 'n': - args.vol_id = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.vol_id < 0) { - errmsg("bad volume ID: " "\"%s\"", optarg); - return -1; - } - break; - - case 'N': - args.name = optarg; - break; - - case 'h': - case '?': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'd': - /* Handle deprecated -d option */ - warnmsg("-d is depricated and will be removed, do not use it"); - args.devn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.devn < 0) - return errmsg("bad UBI device number: " "\"%s\"", optarg); - break; - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case ':': - errmsg("parameter is missing"); - return -1; - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - /* Handle deprecated -d option */ - if (args.devn != -1) { - sprintf(args.dev_name, "/dev/ubi%d", args.devn); - args.node = args.dev_name; - } else { - if (optind == argc) { - errmsg("UBI device name was not specified (use -h for help)"); - return -1; - } else if (optind != argc - 1) { - errmsg("more then one UBI device specified (use -h for help)"); - return -1; - } - - args.node = argv[optind]; - } - - if (param_sanity_check()) - return -1; - - return 0; -} - -int main(int argc, char * const argv[]) -{ - int err; - libubi_t libubi; - - err = parse_opt(argc, argv); - if (err) - return -1; - - libubi = libubi_open(1); - if (libubi == NULL) - return sys_errmsg("cannot open libubi"); - - err = ubi_node_type(libubi, args.node); - if (err == 2) { - errmsg("\"%s\" is an UBI volume node, not an UBI device node", - args.node); - goto out_libubi; - } else if (err < 0) { - errmsg("\"%s\" is not an UBI device node", args.node); - goto out_libubi; - } - - if (args.name) { - struct ubi_dev_info dev_info; - struct ubi_vol_info vol_info; - - err = ubi_get_dev_info(libubi, args.node, &dev_info); - if (err) { - sys_errmsg("cannot get information about UBI device \"%s\"", - args.node); - goto out_libubi; - } - - err = ubi_get_vol_info1_nm(libubi, dev_info.dev_num, - args.name, &vol_info); - if (err) { - sys_errmsg("cannot find UBI volume \"%s\"", args.name); - goto out_libubi; - } - - args.vol_id = vol_info.vol_id; - } - - err = ubi_rmvol(libubi, args.node, args.vol_id); - if (err) { - sys_errmsg("cannot UBI remove volume"); - goto out_libubi; - } - - libubi_close(libubi); - return 0; - -out_libubi: - libubi_close(libubi); - return -1; -} diff --git a/ubi-utils/new-utils/src/ubiupdatevol.c b/ubi-utils/new-utils/src/ubiupdatevol.c deleted file mode 100644 index c83731c..0000000 --- a/ubi-utils/new-utils/src/ubiupdatevol.c +++ /dev/null @@ -1,355 +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. - */ - -/* - * An utility to update UBI volumes. - * - * Authors: Frank Haverkamp - * Joshua W. Boyer - * Artem Bityutskiy - */ - -#include <fcntl.h> -#include <stdio.h> -#include <stdint.h> -#include <getopt.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/stat.h> - -#include <libubi.h> -#include "common.h" - -#define PROGRAM_VERSION "1.1" -#define PROGRAM_NAME "ubiupdatevol" - -struct args { - int truncate; - const char *node; - const char *img; - /* For deprecated -d and -B options handling */ - int devn; - char dev_name[256]; - int broken_update; - int size; - int use_stdin; -}; - -static struct args args = { - .devn = -1, -}; - -static const char *doc = PROGRAM_NAME " version " PROGRAM_VERSION - " - a tool to write data to UBI volumes."; - -static const char *optionsstr = -"-t, --truncate truncate volume (wipe it out)\n" -"-h, --help print help message\n" -"-V, --version print program version\n\n" -"-s, --size=<bytes> bytes in input, if not reading from file\n" -"The following are compatibility options which are deprecated, do not use them\n" -"-d, --devn=<devn> UBI device number - may be used instead of the UBI\n" -" device node name in which case the utility assumes\n" -" that the device node is \"/dev/ubi<devn>\"\n" -"-B, --broken-update broken update, this is for testing"; - -static const char *usage = -"Usage: " PROGRAM_NAME " <UBI volume node file name> [-t] [-h] [-V] [--truncate] [--size=x] [--help]\n" -"\t\t\t[--version] <image file>\n\n" -"Example 1: " PROGRAM_NAME " /dev/ubi0_1 fs.img - write file \"fs.img\" to UBI volume /dev/ubi0_1\n" -"Example 2: " PROGRAM_NAME " /dev/ubi0_1 -t - wipe out UBI volume /dev/ubi0_1"; - -struct option long_options[] = { - { .name = "truncate", .has_arg = 0, .flag = NULL, .val = 't' }, - { .name = "help", .has_arg = 0, .flag = NULL, .val = 'h' }, - { .name = "version", .has_arg = 0, .flag = NULL, .val = 'V' }, - { .name = "size", .has_arg = 1, .flag = NULL, .val = 's' }, - /* Deprecated -d and -B options */ - { .name = "devn", .has_arg = 1, .flag = NULL, .val = 'd' }, - { .name = "broken-update", .has_arg = 1, .flag = NULL, .val = 'B' }, - { NULL, 0, NULL, 0} -}; - -static int parse_opt(int argc, char * const argv[]) -{ - while (1) { - int key; - char *endp; - - key = getopt_long(argc, argv, "n:th?Vd:s:", long_options, NULL); - if (key == -1) - break; - - switch (key) { - case 't': - args.truncate = 1; - break; - - case 's': - args.size = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.size < 0) - return errmsg("bad size: " "\"%s\"", optarg); - break; - - case 'h': - case '?': - fprintf(stderr, "%s\n\n", doc); - fprintf(stderr, "%s\n\n", usage); - fprintf(stderr, "%s\n", optionsstr); - exit(EXIT_SUCCESS); - - case 'd': - /* Handle deprecated -d option */ - warnmsg("-d is depricated and will be removed, do not use it"); - args.devn = strtoul(optarg, &endp, 0); - if (*endp != '\0' || endp == optarg || args.devn < 0) - return errmsg("bad UBI device number: " "\"%s\"", optarg); - break; - - case 'B': - /* Handle deprecated -B option */ - warnmsg("-B is depricated and will be removed, do not use it"); - args.broken_update = 1; - break; - - case 'V': - fprintf(stderr, "%s\n", PROGRAM_VERSION); - exit(EXIT_SUCCESS); - - case ':': - return errmsg("parameter is missing"); - - default: - fprintf(stderr, "Use -h for help\n"); - return -1; - } - } - - /* Handle deprecated -d option */ - if (args.devn != -1) { - sprintf(args.dev_name, "/dev/ubi%d", args.devn); - args.node = args.dev_name; - } else { - if (optind == argc) - return errmsg("UBI device name was not specified (use -h for help)"); - else if (optind != argc - 2 && !args.truncate) - return errmsg("specify UBI device name and image file name as first 2 " - "parameters (use -h for help)"); - } - - args.node = argv[optind]; - args.img = argv[optind + 1]; - - if (args.img && args.truncate) - return errmsg("You can't truncate and specify an image (use -h for help)"); - - if (args.img && !args.truncate) { - if (strcmp(args.img, "-") == 0) - args.use_stdin = 1; - if (args.use_stdin && !args.size) - return errmsg("file size must be specified if input is stdin"); - } - - return 0; -} - -static int truncate_volume(libubi_t libubi) -{ - int err, fd; - - fd = open(args.node, O_RDWR); - if (fd == -1) - return sys_errmsg("cannot open \"%s\"", args.node); - - err = ubi_update_start(libubi, fd, 0); - if (err) { - sys_errmsg("cannot truncate volume \"%s\"", args.node); - close(fd); - return -1; - } - - close(fd); - return 0; -} - -static int ubi_write(int fd, const void *buf, int len) -{ - int ret; - - while (len) { - ret = write(fd, buf, len); - if (ret < 0) { - if (errno == EINTR) { - warnmsg("do not interrupt me!"); - continue; - } - return sys_errmsg("cannot write %d bytes to volume \"%s\"", - len, args.node); - } - - if (ret == 0) - return errmsg("cannot write %d bytes to volume \"%s\"", len, args.node); - - len -= ret; - buf += ret; - } - - return 0; -} - -static int update_volume(libubi_t libubi, struct ubi_vol_info *vol_info) -{ - int err, fd, ifd; - long long bytes; - char *buf; - - buf = malloc(vol_info->leb_size); - if (!buf) - return errmsg("cannot allocate %d bytes of memory", vol_info->leb_size); - - if (!args.size) { - struct stat st; - err = stat(args.img, &st); - if (err < 0) { - errmsg("stat failed on \"%s\"", args.img); - goto out_free; - } - - bytes = st.st_size; - } else - bytes = args.size; - - if (bytes > vol_info->rsvd_bytes) { - errmsg("\"%s\" (size %lld) will not fit volume \"%s\" (size %lld)", - args.img, bytes, args.node, vol_info->rsvd_bytes); - goto out_free; - } - - /* A hack to handle deprecated -B option */ - if (args.broken_update) - bytes = 1; - - fd = open(args.node, O_RDWR); - if (fd == -1) { - sys_errmsg("cannot open UBI volume \"%s\"", args.node); - goto out_free; - } - - if (args.use_stdin) - ifd = STDIN_FILENO; - else { - ifd = open(args.img, O_RDONLY); - if (ifd == -1) { - sys_errmsg("cannot open \"%s\"", args.img); - goto out_close1; - } - } - - err = ubi_update_start(libubi, fd, bytes); - if (err) { - sys_errmsg("cannot start volume \"%s\" update", args.node); - goto out_close; - } - - while (bytes) { - int ret, to_copy = vol_info->leb_size; - - if (to_copy > bytes) - to_copy = bytes; - - ret = read(ifd, buf, to_copy); - if (ret <= 0) { - if (errno == EINTR) { - warnmsg("do not interrupt me!"); - continue; - } else { - sys_errmsg("cannot read %d bytes from \"%s\"", - to_copy, args.img); - goto out_close; - } - } - - err = ubi_write(fd, buf, ret); - if (err) - goto out_close; - bytes -= ret; - } - - close(ifd); - close(fd); - free(buf); - return 0; - -out_close: - close(ifd); -out_close1: - close(fd); -out_free: - free(buf); - return -1; -} - -int main(int argc, char * const argv[]) -{ - int err; - libubi_t libubi; - struct ubi_vol_info vol_info; - - err = parse_opt(argc, argv); - if (err) - return -1; - - libubi = libubi_open(1); - if (libubi == NULL) { - sys_errmsg("cannot open libubi"); - goto out_libubi; - } - - err = ubi_node_type(libubi, args.node); - if (err == 1) { - errmsg("\"%s\" is an UBI device node, not an UBI volume node", - args.node); - goto out_libubi; - } else if (err < 0) { - errmsg("\"%s\" is not an UBI volume node", args.node); - goto out_libubi; - } - - err = ubi_get_vol_info(libubi, args.node, &vol_info); - if (err) { - sys_errmsg("cannot get information about UBI volume \"%s\"", - args.node); - goto out_libubi; - } - - if (args.truncate) - err = truncate_volume(libubi); - else - err = update_volume(libubi, &vol_info); - if (err) - goto out_libubi; - - libubi_close(libubi); - return 0; - -out_libubi: - libubi_close(libubi); - return -1; -} |