From 09258f1e8b12acc4a2a02b60d942660798038fba Mon Sep 17 00:00:00 2001 From: Abhilash Kesavan Date: Thu, 25 Oct 2012 16:30:58 +0000 Subject: fdt: Add function to get config int from device tree Add a function to look up a configuration item such as machine id and return its value. Note: The code has been taken as is from the Chromium u-boot development tree and needs Simon Glass' sign-off. Signed-off-by: Abhilash Kesavan Signed-off-by: Simon Glass --- lib/fdtdec.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 4c23f458f0..1f500224d9 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -512,3 +512,25 @@ const u8 *fdtdec_locate_byte_array(const void *blob, int node, return NULL; return cell; } + +/** + * Look in the FDT for a config item with the given name and return its value + * as a 32-bit integer. The property must have at least 4 bytes of data. The + * value of the first cell is returned. + * + * @param blob FDT blob to use + * @param prop_name Node property name + * @param default_val default value to return if the property is not found + * @return integer value, if found, or default_val if not + */ +int fdtdec_get_config_int(const void *blob, const char *prop_name, + int default_val) +{ + int config_node; + + debug("%s: %s\n", __func__, prop_name); + config_node = fdt_path_offset(blob, "/config"); + if (config_node < 0) + return default_val; + return fdtdec_get_int(blob, config_node, prop_name, default_val); +} -- cgit v1.2.1 From 332ab0d54aaa5b8b27096996d10c8c6183c6972c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 25 Oct 2012 16:30:59 +0000 Subject: fdt: Add function to get a config string from device tree Add a function to look up a configuration string such as board name and returns its value. We look in the "/config" node for this. Signed-off-by: Simon Glass --- lib/fdtdec.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 1f500224d9..2d60c8aaaf 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -513,16 +513,6 @@ const u8 *fdtdec_locate_byte_array(const void *blob, int node, return cell; } -/** - * Look in the FDT for a config item with the given name and return its value - * as a 32-bit integer. The property must have at least 4 bytes of data. The - * value of the first cell is returned. - * - * @param blob FDT blob to use - * @param prop_name Node property name - * @param default_val default value to return if the property is not found - * @return integer value, if found, or default_val if not - */ int fdtdec_get_config_int(const void *blob, const char *prop_name, int default_val) { @@ -534,3 +524,21 @@ int fdtdec_get_config_int(const void *blob, const char *prop_name, return default_val; return fdtdec_get_int(blob, config_node, prop_name, default_val); } + +char *fdtdec_get_config_string(const void *blob, const char *prop_name) +{ + const char *nodep; + int nodeoffset; + int len; + + debug("%s: %s\n", __func__, prop_name); + nodeoffset = fdt_path_offset(blob, "/config"); + if (nodeoffset < 0) + return NULL; + + nodep = fdt_getprop(blob, nodeoffset, prop_name, &len); + if (!nodep) + return NULL; + + return (char *)nodep; +} -- cgit v1.2.1 From f20c461984c3d986fde037d4c5bf600aa0497676 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 25 Oct 2012 16:31:00 +0000 Subject: fdt: Add fdtdec_decode_region() to decode memory region A memory region has a start and a size and is often specified in a node by a 'reg' property. Add a function to decode this information from the fdt. Signed-off-by: Simon Glass --- lib/fdtdec.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 2d60c8aaaf..557097217c 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -542,3 +542,20 @@ char *fdtdec_get_config_string(const void *blob, const char *prop_name) return (char *)nodep; } + +int fdtdec_decode_region(const void *blob, int node, + const char *prop_name, void **ptrp, size_t *size) +{ + const fdt_addr_t *cell; + int len; + + debug("%s: %s\n", __func__, prop_name); + cell = fdt_getprop(blob, node, prop_name, &len); + if (!cell || (len != sizeof(fdt_addr_t) * 2)) + return -1; + + *ptrp = (void *)fdt_addr_to_cpu(*cell); + *size = fdt_size_to_cpu(cell[1]); + debug("%s: size=%zx\n", __func__, *size); + return 0; +} -- cgit v1.2.1 From 5921f6a2924827548caf55b28a6827b9d856e37f Mon Sep 17 00:00:00 2001 From: Abhilash Kesavan Date: Thu, 25 Oct 2012 16:31:01 +0000 Subject: fdt: Add function for decoding multiple gpios globally available Samsung's SDHCI bindings require multiple gpios to be parsed and configured at a time. Export the already available fdtdec_decode_gpios for this purpose. Signed-off-by: Abhilash Kesavan Commit-Ready: Che-Liang Chiou Signed-off-by: Simon Glass --- lib/fdtdec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 557097217c..32f03cc82b 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -426,9 +426,8 @@ int fdtdec_get_bool(const void *blob, int node, const char *prop_name) * @return number of GPIOs read if ok, -FDT_ERR_BADLAYOUT if max_count would * be exceeded, or -FDT_ERR_NOTFOUND if the property is missing. */ -static int fdtdec_decode_gpios(const void *blob, int node, - const char *prop_name, struct fdt_gpio_state *gpio, - int max_count) +int fdtdec_decode_gpios(const void *blob, int node, const char *prop_name, + struct fdt_gpio_state *gpio, int max_count) { const struct fdt_property *prop; const u32 *cell; -- cgit v1.2.1 From 7cde397b21a347134a39c40e24355a0e438adae3 Mon Sep 17 00:00:00 2001 From: Gerald Van Baren Date: Mon, 12 Nov 2012 23:13:54 -0500 Subject: fdt: Export fdtdec_lookup() and fix the name The name of this function is not consistent, so fix it, and export the function for external use. Signed-off-by: Simon Glass --- lib/fdtdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 32f03cc82b..96f3e7bccf 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -128,7 +128,7 @@ int fdtdec_get_is_enabled(const void *blob, int node) return 1; } -enum fdt_compat_id fd_dec_lookup(const void *blob, int node) +enum fdt_compat_id fdtdec_lookup(const void *blob, int node) { enum fdt_compat_id id; -- cgit v1.2.1 From 79289c0b5ff4a8c7869d7ca629cddc660dd06095 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Thu, 25 Oct 2012 16:31:04 +0000 Subject: fdt: Add function to read boolean property Signed-off-by: Vincent Palatin Commit-Ready: Vincent Palatin Commit-Ready: Gabe Black Signed-off-by: Simon Glass --- lib/fdtdec.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 96f3e7bccf..da12df209c 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -524,6 +524,20 @@ int fdtdec_get_config_int(const void *blob, const char *prop_name, return fdtdec_get_int(blob, config_node, prop_name, default_val); } +int fdtdec_get_config_bool(const void *blob, const char *prop_name) +{ + int config_node; + const void *prop; + + debug("%s: %s\n", __func__, prop_name); + config_node = fdt_path_offset(blob, "/config"); + if (config_node < 0) + return 0; + prop = fdt_get_property(blob, config_node, prop_name, NULL); + + return prop != NULL; +} + char *fdtdec_get_config_string(const void *blob, const char *prop_name) { const char *nodep; -- cgit v1.2.1 From aadef0a1bc3db81708471c9d18eb6c756659196f Mon Sep 17 00:00:00 2001 From: Che-Liang Chiou Date: Thu, 25 Oct 2012 16:31:05 +0000 Subject: fdt: Add fdtdec_get_uint64 to decode a 64-bit value from a property It decodes a 64-bit value from a property that is at least 8 bytes long. Signed-off-by: Che-Liang Chiou Signed-off-by: Simon Glass --- lib/fdtdec.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index da12df209c..150512e5a8 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -111,6 +111,19 @@ s32 fdtdec_get_int(const void *blob, int node, const char *prop_name, return default_val; } +uint64_t fdtdec_get_uint64(const void *blob, int node, const char *prop_name, + uint64_t default_val) +{ + const uint64_t *cell64; + int length; + + cell64 = fdt_getprop(blob, node, prop_name, &length); + if (!cell64 || length < sizeof(*cell64)) + return default_val; + + return fdt64_to_cpu(*cell64); +} + int fdtdec_get_is_enabled(const void *blob, int node) { const char *cell; -- cgit v1.2.1 From 202ff7537558edfd759b400cfe9e56c56fc7868c Mon Sep 17 00:00:00 2001 From: Sean Paul Date: Thu, 25 Oct 2012 16:31:06 +0000 Subject: fdt: Add polarity-aware gpio functions to fdtdec Add get and set gpio functions to fdtdec that take into account the polarity field in fdtdec_gpio_state.flags. Signed-off-by: Sean Paul Signed-off-by: Simon Glass --- lib/fdtdec.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 150512e5a8..e1b17a5fe5 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -487,6 +487,26 @@ int fdtdec_decode_gpio(const void *blob, int node, const char *prop_name, return err == 1 ? 0 : err; } +int fdtdec_get_gpio(struct fdt_gpio_state *gpio) +{ + int val; + + if (!fdt_gpio_isvalid(gpio)) + return -1; + + val = gpio_get_value(gpio->gpio); + return gpio->flags & FDT_GPIO_ACTIVE_LOW ? val ^ 1 : val; +} + +int fdtdec_set_gpio(struct fdt_gpio_state *gpio, int val) +{ + if (!fdt_gpio_isvalid(gpio)) + return -1; + + val = gpio->flags & FDT_GPIO_ACTIVE_LOW ? val ^ 1 : val; + return gpio_set_value(gpio->gpio, val); +} + int fdtdec_setup_gpio(struct fdt_gpio_state *gpio) { /* -- cgit v1.2.1 From 008784765ab7f37fb355d5f7fb180661b94c42ab Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 31 Oct 2012 14:02:42 +0000 Subject: fdt: Remove fdtdec_find_alias_node() function This function is not needed, since fdt_path_offset() performs the same service. Remove it. Signed-off-by: Simon Glass --- lib/fdtdec.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) (limited to 'lib') diff --git a/lib/fdtdec.c b/lib/fdtdec.c index e1b17a5fe5..348144aa70 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -52,28 +52,6 @@ const char *fdtdec_get_compatible(enum fdt_compat_id id) return compat_names[id]; } -/** - * Look in the FDT for an alias with the given name and return its node. - * - * @param blob FDT blob - * @param name alias name to look up - * @return node offset if found, or an error code < 0 otherwise - */ -static int find_alias_node(const void *blob, const char *name) -{ - const char *path; - int alias_node; - - debug("find_alias_node: %s\n", name); - alias_node = fdt_path_offset(blob, "/aliases"); - if (alias_node < 0) - return alias_node; - path = fdt_getprop(blob, alias_node, name, NULL); - if (!path) - return -FDT_ERR_NOTFOUND; - return fdt_path_offset(blob, path); -} - fdt_addr_t fdtdec_get_addr(const void *blob, int node, const char *prop_name) { @@ -184,7 +162,7 @@ int fdtdec_next_alias(const void *blob, const char *name, /* snprintf() is not available */ assert(strlen(name) < MAX_STR_LEN); sprintf(str, "%.*s%d", MAX_STR_LEN, name, *upto); - node = find_alias_node(blob, str); + node = fdt_path_offset(blob, str); if (node < 0) return node; err = fdt_node_check_compatible(blob, node, compat_names[id]); -- cgit v1.2.1 From 5fe8380db3d5cd9f6c155f800616bdcb6dd34d18 Mon Sep 17 00:00:00 2001 From: Stefan Reinauer Date: Sat, 3 Nov 2012 11:45:19 +0000 Subject: lzma: update to lzma sdk 9.20 Updated code taken from latest lzma sdk release 9.20 at http://downloads.sourceforge.net/sevenzip/lzma920.tar.bz2 This generates quite a lot of checkpatch warnings, but I guess we need to keep the code style as is to avoid a massive job each time we update this. Signed-off-by: Stefan Reinauer Signed-off-by: Simon Glass --- lib/lzma/LzmaDec.c | 14 +++----------- lib/lzma/LzmaDec.h | 6 +++--- lib/lzma/Types.h | 36 +++++++++++++++++++++++++++++++----- lib/lzma/history.txt | 35 +++++++++++++++++++++++++++++++++++ lib/lzma/lzma.txt | 34 +++++++++++++++++++--------------- 5 files changed, 91 insertions(+), 34 deletions(-) (limited to 'lib') diff --git a/lib/lzma/LzmaDec.c b/lib/lzma/LzmaDec.c index f941da27dd..4f45f80fe2 100644 --- a/lib/lzma/LzmaDec.c +++ b/lib/lzma/LzmaDec.c @@ -1,5 +1,5 @@ /* LzmaDec.c -- LZMA Decoder -2008-11-06 : Igor Pavlov : Public domain */ +2009-09-20 : Igor Pavlov : Public domain */ #include #include @@ -116,12 +116,6 @@ StopCompilingDueBUG #endif -static const Byte kLiteralNextStates[kNumStates * 2] = -{ - 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5, - 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10 -}; - #define LZMA_DIC_MIN (1 << 12) /* First LZMA-symbol is always decoded. @@ -180,6 +174,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte if (state < kNumLitStates) { + state -= (state < 4) ? state : 3; symbol = 1; WATCHDOG_RESET(); @@ -190,6 +185,7 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte { unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; unsigned offs = 0x100; + state -= (state < 10) ? 3 : 6; symbol = 1; WATCHDOG_RESET(); @@ -207,9 +203,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte } dic[dicPos++] = (Byte)symbol; processedPos++; - - state = kLiteralNextStates[state]; - /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */ continue; } else @@ -395,7 +388,6 @@ static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte else if (distance >= checkDicSize) return SZ_ERROR_DATA; state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; - /* state = kLiteralNextStates[state]; */ } len += kMatchMinLen; diff --git a/lib/lzma/LzmaDec.h b/lib/lzma/LzmaDec.h index 7fba87f076..63aa505e8c 100644 --- a/lib/lzma/LzmaDec.h +++ b/lib/lzma/LzmaDec.h @@ -1,8 +1,8 @@ /* LzmaDec.h -- LZMA Decoder -2008-10-04 : Igor Pavlov : Public domain */ +2009-02-07 : Igor Pavlov : Public domain */ -#ifndef __LZMADEC_H -#define __LZMADEC_H +#ifndef __LZMA_DEC_H +#define __LZMA_DEC_H #include "Types.h" diff --git a/lib/lzma/Types.h b/lib/lzma/Types.h index 1af5cfc4d8..8afcba556e 100644 --- a/lib/lzma/Types.h +++ b/lib/lzma/Types.h @@ -1,5 +1,5 @@ /* Types.h -- Basic types -2008-11-23 : Igor Pavlov : Public domain */ +2010-10-09 : Igor Pavlov : Public domain */ #ifndef __7Z_TYPES_H #define __7Z_TYPES_H @@ -65,9 +65,11 @@ typedef unsigned long UInt64; #if defined(_MSC_VER) || defined(__BORLANDC__) typedef __int64 Int64; typedef unsigned __int64 UInt64; +#define UINT64_CONST(n) n #else typedef long long int Int64; typedef unsigned long long int UInt64; +#define UINT64_CONST(n) n ## ULL #endif #endif @@ -92,13 +94,11 @@ typedef int Bool; #endif #define MY_CDECL __cdecl -#define MY_STD_CALL __stdcall -#define MY_FAST_CALL MY_NO_INLINE __fastcall +#define MY_FAST_CALL __fastcall #else #define MY_CDECL -#define MY_STD_CALL #define MY_FAST_CALL #endif @@ -106,6 +106,16 @@ typedef int Bool; /* The following interfaces use first parameter as pointer to structure */ +typedef struct +{ + Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */ +} IByteIn; + +typedef struct +{ + void (*Write)(void *p, Byte b); +} IByteOut; + typedef struct { SRes (*Read)(void *p, void *buf, size_t *size); @@ -140,7 +150,7 @@ typedef struct typedef struct { - SRes (*Look)(void *p, void **buf, size_t *size); + SRes (*Look)(void *p, const void **buf, size_t *size); /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream. (output(*size) > input(*size)) is not allowed (output(*size) < input(*size)) is allowed */ @@ -205,4 +215,20 @@ typedef struct #define IAlloc_Alloc(p, size) (p)->Alloc((p), size) #define IAlloc_Free(p, a) (p)->Free((p), a) +#ifdef _WIN32 + +#define CHAR_PATH_SEPARATOR '\\' +#define WCHAR_PATH_SEPARATOR L'\\' +#define STRING_PATH_SEPARATOR "\\" +#define WSTRING_PATH_SEPARATOR L"\\" + +#else + +#define CHAR_PATH_SEPARATOR '/' +#define WCHAR_PATH_SEPARATOR L'/' +#define STRING_PATH_SEPARATOR "/" +#define WSTRING_PATH_SEPARATOR L"/" + +#endif + #endif diff --git a/lib/lzma/history.txt b/lib/lzma/history.txt index aadf8255ed..443511bdd4 100644 --- a/lib/lzma/history.txt +++ b/lib/lzma/history.txt @@ -1,6 +1,41 @@ HISTORY of the LZMA SDK ----------------------- +9.18 beta 2010-11-02 +------------------------- +- New small SFX module for installers (SfxSetup). + + +9.12 beta 2010-03-24 +------------------------- +- The BUG in LZMA SDK 9.* was fixed: LZMA2 codec didn't work, + if more than 10 threads were used (or more than 20 threads in some modes). + + +9.11 beta 2010-03-15 +------------------------- +- PPMd compression method support + + +9.09 2009-12-12 +------------------------- +- The bug was fixed: + Utf16_To_Utf8 funstions in UTFConvert.cpp and 7zMain.c + incorrectly converted surrogate characters (the code >= 0x10000) to UTF-8. +- Some bugs were fixed + + +9.06 2009-08-17 +------------------------- +- Some changes in ANSI-C 7z Decoder interfaces. + + +9.04 2009-05-30 +------------------------- +- LZMA2 compression method support +- xz format support + + 4.65 2009-02-03 ------------------------- - Some minor fixes diff --git a/lib/lzma/lzma.txt b/lib/lzma/lzma.txt index aa20f9dc5c..144cd9aee2 100644 --- a/lib/lzma/lzma.txt +++ b/lib/lzma/lzma.txt @@ -1,4 +1,4 @@ -LZMA SDK 4.65 +LZMA SDK 9.20 ------------- LZMA SDK provides the documentation, samples, header files, libraries, @@ -20,6 +20,10 @@ LICENSE LZMA SDK is written and placed in the public domain by Igor Pavlov. +Some code in LZMA SDK is based on public domain code from another developers: + 1) PPMd var.H (2001): Dmitry Shkarin + 2) SHA-256: Wei Dai (Crypto++ library) + LZMA SDK Contents ----------------- @@ -33,7 +37,7 @@ LZMA SDK includes: UNIX/Linux version ------------------ To compile C++ version of file->file LZMA encoding, go to directory -C++/7zip/Compress/LZMA_Alone +CPP/7zip/Bundles/LzmaCon and call make to recompile it: make -f makefile.gcc clean all @@ -49,6 +53,7 @@ lzma.txt - LZMA SDK description (this file) 7zC.txt - 7z ANSI-C Decoder description methods.txt - Compression method IDs for .7z lzma.exe - Compiled file->file LZMA encoder/decoder for Windows +7zr.exe - 7-Zip with 7z/lzma/xz support. history.txt - history of the LZMA SDK @@ -66,7 +71,7 @@ C/ - C files LzmaEnc.* - LZMA encoding LzmaLib.* - LZMA Library for DLL calling Types.h - Basic types for another .c files - Threads.* - The code for multithreading. + Threads.* - The code for multithreading. LzmaLib - LZMA Library (.DLL for Windows) @@ -86,12 +91,6 @@ CPP/ -- CPP files Compress - files related to compression/decompression - Copy - Copy coder - RangeCoder - Range Coder (special code of compression/decompression) - LZMA - LZMA compression/decompression on C++ - LZMA_Alone - file->file LZMA compression/decompression - Branch - Filters for x86, IA-64, ARM, ARM-Thumb, PowerPC and SPARC code - Archive - files related to archiving Common - common files for archive handling @@ -100,6 +99,7 @@ CPP/ -- CPP files Bundles - Modules that are bundles of other modules Alone7z - 7zr.exe: Standalone version of 7z.exe that supports only 7z/LZMA/BCJ/BCJ2 + LzmaCon - lzma.exe: LZMA compression/decompression Format7zR - 7zr.dll: Reduced version of 7za.dll: extracting/compressing to 7z/LZMA/BCJ/BCJ2 Format7zExtractR - 7zxr.dll: Reduced version of 7zxa.dll: extracting from 7z/LZMA/BCJ/BCJ2. @@ -369,8 +369,8 @@ Interface: propData - LZMA properties (5 bytes) propSize - size of propData buffer (5 bytes) finishMode - It has meaning only if the decoding reaches output limit (*destLen). - LZMA_FINISH_ANY - Decode just destLen bytes. - LZMA_FINISH_END - Stream must be finished after (*destLen). + LZMA_FINISH_ANY - Decode just destLen bytes. + LZMA_FINISH_END - Stream must be finished after (*destLen). You can use LZMA_FINISH_END, when you know that current output buffer covers last bytes of stream. alloc - Memory allocator. @@ -431,7 +431,7 @@ Memory Requirements: { ... int res = LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, - const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode); + const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode); ... } @@ -527,7 +527,8 @@ static ISzAlloc g_Alloc = { SzAlloc, SzFree }; LzmaEnc_Destroy(enc, &g_Alloc, &g_Alloc); -If callback function return some error code, LzmaEnc_Encode also returns that code. +If callback function return some error code, LzmaEnc_Encode also returns that code +or it can return the code like SZ_ERROR_READ, SZ_ERROR_WRITE or SZ_ERROR_PROGRESS. Single-call RAM->RAM Compression @@ -549,8 +550,8 @@ Return code: -LZMA Defines ------------- +Defines +------- _LZMA_SIZE_OPT - Enable some optimizations in LZMA Decoder to get smaller executable code. @@ -562,6 +563,9 @@ _LZMA_UINT32_IS_ULONG - Define it if int is 16-bit on your compiler and long is _LZMA_NO_SYSTEM_SIZE_T - Define it if you don't want to use size_t type. +_7ZIP_PPMD_SUPPPORT - Define it if you don't want to support PPMD method in AMSI-C .7z decoder. + + C++ LZMA Encoder/Decoder ~~~~~~~~~~~~~~~~~~~~~~~~ C++ LZMA code use COM-like interfaces. So if you want to use it, -- cgit v1.2.1 From 40fef0490610686022f99b8e070df7ac761c11a0 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sun, 2 Dec 2012 04:55:18 +0000 Subject: Introduce arch_phys_memset which works like memset but on physical memory The default implementation of this function is just memset, but other implementations will be needed when physical memory isn't accessible by U-Boot using normal addressing mechanisms. Signed-off-by: Gabe Black Signed-off-by: Che-Liang Chiou Signed-off-by: Simon Glass --- lib/Makefile | 1 + lib/physmem.c | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 lib/physmem.c (limited to 'lib') diff --git a/lib/Makefile b/lib/Makefile index e44e045233..f83f6e8d8c 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -48,6 +48,7 @@ COBJS-$(CONFIG_LMB) += lmb.o COBJS-y += ldiv.o COBJS-$(CONFIG_MD5) += md5.o COBJS-y += net_utils.o +COBJS-$(CONFIG_PHYSMEM) += physmem.o COBJS-y += qsort.o COBJS-$(CONFIG_SHA1) += sha1.o COBJS-$(CONFIG_SHA256) += sha256.o diff --git a/lib/physmem.c b/lib/physmem.c new file mode 100644 index 0000000000..0f035edcbe --- /dev/null +++ b/lib/physmem.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2012 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + * + * Alternatively, this software may be distributed under the terms of the + * GNU General Public License ("GPL") version 2 as published by the Free + * Software Foundation. + */ + +#include +#include + +static phys_addr_t __arch_phys_memset(phys_addr_t s, int c, phys_size_t n) +{ + void *s_ptr = (void *)(uintptr_t)s; + + assert(((phys_addr_t)(uintptr_t)s) == s); + assert(((phys_addr_t)(uintptr_t)(s + n)) == s + n); + return (phys_addr_t)(uintptr_t)memset(s_ptr, c, n); +} + +phys_addr_t arch_phys_memset(phys_addr_t s, int c, phys_size_t n) + __attribute__((weak, alias("__arch_phys_memset"))); -- cgit v1.2.1 From a7d1d765793a05c0d6f7547122339dbecc94f6c3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Dec 2012 14:46:33 +0000 Subject: sha1: Use const where possible, and unsigned for input len In preparation for making the hash function common, we may as well use const where we can. Also the input length cannot be negative, but may be very large, so use unsigned. Signed-off-by: Simon Glass --- lib/sha1.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/sha1.c b/lib/sha1.c index da5bc16f3c..a121224855 100644 --- a/lib/sha1.c +++ b/lib/sha1.c @@ -73,7 +73,7 @@ void sha1_starts (sha1_context * ctx) ctx->state[4] = 0xC3D2E1F0; } -static void sha1_process (sha1_context * ctx, unsigned char data[64]) +static void sha1_process(sha1_context *ctx, const unsigned char data[64]) { unsigned long temp, W[16], A, B, C, D, E; @@ -230,7 +230,8 @@ static void sha1_process (sha1_context * ctx, unsigned char data[64]) /* * SHA-1 process buffer */ -void sha1_update (sha1_context * ctx, unsigned char *input, int ilen) +void sha1_update(sha1_context *ctx, const unsigned char *input, + unsigned int ilen) { int fill; unsigned long left; @@ -305,7 +306,8 @@ void sha1_finish (sha1_context * ctx, unsigned char output[20]) /* * Output = SHA-1( input buffer ) */ -void sha1_csum (unsigned char *input, int ilen, unsigned char output[20]) +void sha1_csum(const unsigned char *input, unsigned int ilen, + unsigned char *output) { sha1_context ctx; @@ -318,12 +320,12 @@ void sha1_csum (unsigned char *input, int ilen, unsigned char output[20]) * Output = SHA-1( input buffer ). Trigger the watchdog every 'chunk_sz' * bytes of input processed. */ -void sha1_csum_wd (unsigned char *input, int ilen, unsigned char output[20], - unsigned int chunk_sz) +void sha1_csum_wd(const unsigned char *input, unsigned int ilen, + unsigned char *output, unsigned int chunk_sz) { sha1_context ctx; #if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) - unsigned char *end, *curr; + const unsigned char *end, *curr; int chunk; #endif @@ -350,8 +352,9 @@ void sha1_csum_wd (unsigned char *input, int ilen, unsigned char output[20], /* * Output = HMAC-SHA-1( input buffer, hmac key ) */ -void sha1_hmac (unsigned char *key, int keylen, - unsigned char *input, int ilen, unsigned char output[20]) +void sha1_hmac(const unsigned char *key, int keylen, + const unsigned char *input, unsigned int ilen, + unsigned char *output) { int i; sha1_context ctx; -- cgit v1.2.1 From ec7381fbf6f77cc465eb06a1ab6f8a99df1e487c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Dec 2012 14:46:34 +0000 Subject: sha256: Use const where possible and add watchdog function In preparation for making the hash function common, we may as well use const where we can. Also add a watchdog version of the hashing function. Signed-off-by: Simon Glass --- lib/sha256.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/sha256.c b/lib/sha256.c index deb63a40b6..ab2db4890a 100644 --- a/lib/sha256.c +++ b/lib/sha256.c @@ -60,7 +60,7 @@ void sha256_starts(sha256_context * ctx) ctx->state[7] = 0x5BE0CD19; } -void sha256_process(sha256_context * ctx, uint8_t data[64]) +static void sha256_process(sha256_context *ctx, const uint8_t data[64]) { uint32_t temp1, temp2; uint32_t W[64]; @@ -191,7 +191,7 @@ void sha256_process(sha256_context * ctx, uint8_t data[64]) ctx->state[7] += H; } -void sha256_update(sha256_context * ctx, uint8_t * input, uint32_t length) +void sha256_update(sha256_context *ctx, const uint8_t *input, uint32_t length) { uint32_t left, fill; @@ -260,3 +260,36 @@ void sha256_finish(sha256_context * ctx, uint8_t digest[32]) PUT_UINT32_BE(ctx->state[6], digest, 24); PUT_UINT32_BE(ctx->state[7], digest, 28); } + +/* + * Output = SHA-256( input buffer ). Trigger the watchdog every 'chunk_sz' + * bytes of input processed. + */ +void sha256_csum_wd(const unsigned char *input, unsigned int ilen, + unsigned char *output, unsigned int chunk_sz) +{ + sha256_context ctx; +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + unsigned char *end, *curr; + int chunk; +#endif + + sha256_starts(&ctx); + +#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG) + curr = input; + end = input + ilen; + while (curr < end) { + chunk = end - curr; + if (chunk > chunk_sz) + chunk = chunk_sz; + sha256_update(&ctx, curr, chunk); + curr += chunk; + WATCHDOG_RESET(); + } +#else + sha256_update(&ctx, input, ilen); +#endif + + sha256_finish(&ctx, output); +} -- cgit v1.2.1 From b1f17bf5ff63a7e22e0299dd576c3b6cd38ae665 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Dec 2012 14:46:35 +0000 Subject: Add strcasecmp() and strncasecmp() strncasecmp() is present as strnicmp() but disabled. Make it available and define strcasecmp() also. There is a only a small performance penalty to having strcasecmp() call strncasecmp(), so do this instead of a standalone function, to save code space. Update the prototype in arch-specific headers as needed to avoid warnings. Signed-off-by: Simon Glass --- lib/string.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/string.c b/lib/string.c index c3ad055e2c..68f60bea12 100644 --- a/lib/string.c +++ b/lib/string.c @@ -21,14 +21,13 @@ #include -#if 0 /* not used - was: #ifndef __HAVE_ARCH_STRNICMP */ /** - * strnicmp - Case insensitive, length-limited string comparison + * strncasecmp - Case insensitive, length-limited string comparison * @s1: One string * @s2: The other string * @len: the maximum number of characters to compare */ -int strnicmp(const char *s1, const char *s2, size_t len) +int strncasecmp(const char *s1, const char *s2, size_t len) { /* Yes, Virginia, it had better be unsigned */ unsigned char c1, c2; @@ -52,7 +51,16 @@ int strnicmp(const char *s1, const char *s2, size_t len) } return (int)c1 - (int)c2; } -#endif + +/** + * strcasecmp - Case insensitive string comparison + * @s1: One string + * @s2: The other string + */ +int strcasecmp(const char *s1, const char *s2) +{ + return strncasecmp(s1, s2, -1U); +} char * ___strtok; -- cgit v1.2.1 From 3ec44111aa33f568493f565285a3a519ef38e1dc Mon Sep 17 00:00:00 2001 From: Lukasz Majewski Date: Tue, 11 Dec 2012 11:09:42 +0100 Subject: vsprintf:fix: Change type returned by ustrtoul The ustrtoul shall convert string defined size (e.g. 1GiB) to unsigned long type (as its name implies). Up till now it had returned int, which might cause problems with large numbers (GiB range), when interpreted as U2 signed numbers. Signed-off-by: Lukasz Majewski Signed-off-by: Kyungmin Park --- lib/vsprintf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/vsprintf.c b/lib/vsprintf.c index b7a79c0e0c..3c432f8764 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -103,7 +103,7 @@ long simple_strtol(const char *cp, char **endp, unsigned int base) return simple_strtoul(cp, endp, base); } -int ustrtoul(const char *cp, char **endp, unsigned int base) +unsigned long ustrtoul(const char *cp, char **endp, unsigned int base) { unsigned long result = simple_strtoul(cp, endp, base); switch (**endp) { -- cgit v1.2.1 From e772cb30f649c1bb8c9cb15e4c05cbf0760f2f61 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 11 Dec 2012 22:16:18 -0600 Subject: Make linux kernel string funcs available to tools isspace() and strim() are not in the typical user-mode string.h, so put them in a separate compilation unit so that they can be built into tools that need them independent of the other common string functions. This allows code shared by u-boot and the linux user-mode tools to link. Signed-off-by: Joe Hershberger --- lib/Makefile | 1 + lib/linux_string.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/string.c | 39 --------------------------------------- 3 files changed, 52 insertions(+), 39 deletions(-) create mode 100644 lib/linux_string.c (limited to 'lib') diff --git a/lib/Makefile b/lib/Makefile index f83f6e8d8c..86ca1a6ec1 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -69,6 +69,7 @@ endif COBJS-y += crc32.o COBJS-y += ctype.o COBJS-y += div64.o +COBJS-y += linux_string.o COBJS-y += string.o COBJS-y += time.o COBJS-$(CONFIG_BOOTP_PXE) += uuid.o diff --git a/lib/linux_string.c b/lib/linux_string.c new file mode 100644 index 0000000000..d5a5e08d98 --- /dev/null +++ b/lib/linux_string.c @@ -0,0 +1,51 @@ +/* + * linux/lib/string.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#ifdef USE_HOSTCC +#include +#endif + +#include +#include + +/** + * skip_spaces - Removes leading whitespace from @str. + * @str: The string to be stripped. + * + * Returns a pointer to the first non-whitespace character in @str. + */ +char *skip_spaces(const char *str) +{ + while (isspace(*str)) + ++str; + return (char *)str; +} + +/** + * strim - Removes leading and trailing whitespace from @s. + * @s: The string to be stripped. + * + * Note that the first trailing whitespace is replaced with a %NUL-terminator + * in the given string @s. Returns a pointer to the first non-whitespace + * character in @s. + */ +char *strim(char *s) +{ + size_t size; + char *end; + + s = skip_spaces(s); + size = strlen(s); + if (!size) + return s; + + end = s + size - 1; + while (end >= s && isspace(*end)) + end--; + *(end + 1) = '\0'; + + return s; +} diff --git a/lib/string.c b/lib/string.c index 68f60bea12..09dfae03c2 100644 --- a/lib/string.c +++ b/lib/string.c @@ -222,45 +222,6 @@ char * strrchr(const char * s, int c) } #endif - -/** - * skip_spaces - Removes leading whitespace from @str. - * @str: The string to be stripped. - * - * Returns a pointer to the first non-whitespace character in @str. - */ -char *skip_spaces(const char *str) -{ - while (isspace(*str)) - ++str; - return (char *)str; -} - -/** - * strim - Removes leading and trailing whitespace from @s. - * @s: The string to be stripped. - * - * Note that the first trailing whitespace is replaced with a %NUL-terminator - * in the given string @s. Returns a pointer to the first non-whitespace - * character in @s. - */ -char *strim(char *s) -{ - size_t size; - char *end; - - s = skip_spaces(s); - size = strlen(s); - if (!size) - return s; - - end = s + size - 1; - while (end >= s && isspace(*end)) - end--; - *(end + 1) = '\0'; - - return s; -} #ifndef __HAVE_ARCH_STRLEN /** * strlen - Find the length of a string -- cgit v1.2.1 From c4e0057fa78ebb524b9241ad7245fcd1074ba414 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 11 Dec 2012 22:16:19 -0600 Subject: env: Refactor do_apply to a flag Use a flag in hsearch_r for insert mode passed from import to allow the behavior be different based on use. Now that "do_check" is called for all imports, ensure console init is complete before updating the console on relocation import Signed-off-by: Joe Hershberger --- lib/hashtable.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) (limited to 'lib') diff --git a/lib/hashtable.c b/lib/hashtable.c index 94a7b61717..f0056acf6c 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -142,7 +142,7 @@ int hcreate_r(size_t nel, struct hsearch_data *htab) * be freed and the local static variable can be marked as not used. */ -void hdestroy_r(struct hsearch_data *htab, int do_apply) +void hdestroy_r(struct hsearch_data *htab) { int i; @@ -156,10 +156,7 @@ void hdestroy_r(struct hsearch_data *htab, int do_apply) for (i = 1; i <= htab->size; ++i) { if (htab->table[i].used > 0) { ENTRY *ep = &htab->table[i].entry; - if (do_apply && htab->apply != NULL) { - /* deletion is always forced */ - htab->apply(ep->key, ep->data, NULL, H_FORCE); - } + free((void *)ep->key); free(ep->data); } @@ -251,7 +248,7 @@ int hmatch_r(const char *match, int last_idx, ENTRY ** retval, } int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval, - struct hsearch_data *htab) + struct hsearch_data *htab, int flag) { unsigned int hval; unsigned int count; @@ -404,7 +401,7 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval, * do that. */ -int hdelete_r(const char *key, struct hsearch_data *htab, int do_apply) +int hdelete_r(const char *key, struct hsearch_data *htab, int flag) { ENTRY e, *ep; int idx; @@ -413,15 +410,21 @@ int hdelete_r(const char *key, struct hsearch_data *htab, int do_apply) e.key = (char *)key; - if ((idx = hsearch_r(e, FIND, &ep, htab)) == 0) { + idx = hsearch_r(e, FIND, &ep, htab, 0); + if (idx == 0) { __set_errno(ESRCH); return 0; /* not found */ } + /* Check for permission */ + if (htab->apply != NULL && + htab->apply(ep->key, ep->data, NULL, flag)) { + __set_errno(EPERM); + return 0; + } + /* free used ENTRY */ debug("hdelete: DELETING key \"%s\"\n", key); - if (do_apply && htab->apply != NULL) - htab->apply(ep->key, ep->data, NULL, H_FORCE); free((void *)ep->key); free(ep->data); htab->table[idx].used = -1; @@ -674,7 +677,7 @@ static int drop_var_from_set(const char *name, int nvars, char * vars[]) int himport_r(struct hsearch_data *htab, const char *env, size_t size, const char sep, int flag, - int nvars, char * const vars[], int do_apply) + int nvars, char * const vars[]) { char *data, *sp, *dp, *name, *value; char *localvars[nvars]; @@ -704,7 +707,7 @@ int himport_r(struct hsearch_data *htab, debug("Destroy Hash Table: %p table = %p\n", htab, htab->table); if (htab->table) - hdestroy_r(htab, do_apply); + hdestroy_r(htab); } /* @@ -770,7 +773,7 @@ int himport_r(struct hsearch_data *htab, if (!drop_var_from_set(name, nvars, localvars)) continue; - if (hdelete_r(name, htab, do_apply) == 0) + if (hdelete_r(name, htab, flag) == 0) debug("DELETE ERROR ##############################\n"); continue; @@ -795,14 +798,14 @@ int himport_r(struct hsearch_data *htab, e.data = value; /* if there is an apply function, check what it has to say */ - if (do_apply && htab->apply != NULL) { + if (htab->apply != NULL) { debug("searching before calling cb function" " for %s\n", name); /* * Search for variable in existing env, so to pass * its previous value to the apply callback */ - hsearch_r(e, FIND, &rv, htab); + hsearch_r(e, FIND, &rv, htab, 0); debug("previous value was %s\n", rv ? rv->data : ""); if (htab->apply(name, rv ? rv->data : NULL, value, flag)) { @@ -812,7 +815,7 @@ int himport_r(struct hsearch_data *htab, } } - hsearch_r(e, ENTER, &rv, htab); + hsearch_r(e, ENTER, &rv, htab, flag); if (rv == NULL) { printf("himport_r: can't insert \"%s=%s\" into hash table\n", name, value); @@ -839,7 +842,7 @@ int himport_r(struct hsearch_data *htab, * b) if the variable was not present in current env, we notify * it might be a typo */ - if (hdelete_r(localvars[i], htab, do_apply) == 0) + if (hdelete_r(localvars[i], htab, flag) == 0) printf("WARNING: '%s' neither in running nor in imported env!\n", localvars[i]); else printf("WARNING: '%s' not in imported env, deleting it!\n", localvars[i]); -- cgit v1.2.1 From 3d3b52f2586a8bf1c53496547062594fd4386454 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 11 Dec 2012 22:16:20 -0600 Subject: env: Consolidate common code in hsearch_r() The same chunk of code was replicated in two places and the following changes will make that chunk grow a bit, so combine into a static func. Signed-off-by: Joe Hershberger --- lib/hashtable.c | 71 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 34 deletions(-) (limited to 'lib') diff --git a/lib/hashtable.c b/lib/hashtable.c index f0056acf6c..f4d5795059 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -247,6 +247,34 @@ int hmatch_r(const char *match, int last_idx, ENTRY ** retval, return 0; } +/* + * Compare an existing entry with the desired key, and overwrite if the action + * is ENTER. This is simply a helper function for hsearch_r(). + */ +static inline int _compare_and_overwrite_entry(ENTRY item, ACTION action, + ENTRY **retval, struct hsearch_data *htab, int flag, + unsigned int hval, unsigned int idx) +{ + if (htab->table[idx].used == hval + && strcmp(item.key, htab->table[idx].entry.key) == 0) { + /* Overwrite existing value? */ + if ((action == ENTER) && (item.data != NULL)) { + free(htab->table[idx].entry.data); + htab->table[idx].entry.data = strdup(item.data); + if (!htab->table[idx].entry.data) { + __set_errno(ENOMEM); + *retval = NULL; + return 0; + } + } + /* return found entry */ + *retval = &htab->table[idx].entry; + return idx; + } + /* keep searching */ + return -1; +} + int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval, struct hsearch_data *htab, int flag) { @@ -255,6 +283,7 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval, unsigned int len = strlen(item.key); unsigned int idx; unsigned int first_deleted = 0; + int ret; /* Compute an value for the given string. Perhaps use a better method. */ hval = len; @@ -286,23 +315,10 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval, && !first_deleted) first_deleted = idx; - if (htab->table[idx].used == hval - && strcmp(item.key, htab->table[idx].entry.key) == 0) { - /* Overwrite existing value? */ - if ((action == ENTER) && (item.data != NULL)) { - free(htab->table[idx].entry.data); - htab->table[idx].entry.data = - strdup(item.data); - if (!htab->table[idx].entry.data) { - __set_errno(ENOMEM); - *retval = NULL; - return 0; - } - } - /* return found entry */ - *retval = &htab->table[idx].entry; - return idx; - } + ret = _compare_and_overwrite_entry(item, action, retval, htab, + flag, hval, idx); + if (ret != -1) + return ret; /* * Second hash function: @@ -328,23 +344,10 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval, break; /* If entry is found use it. */ - if ((htab->table[idx].used == hval) - && strcmp(item.key, htab->table[idx].entry.key) == 0) { - /* Overwrite existing value? */ - if ((action == ENTER) && (item.data != NULL)) { - free(htab->table[idx].entry.data); - htab->table[idx].entry.data = - strdup(item.data); - if (!htab->table[idx].entry.data) { - __set_errno(ENOMEM); - *retval = NULL; - return 0; - } - } - /* return found entry */ - *retval = &htab->table[idx].entry; - return idx; - } + ret = _compare_and_overwrite_entry(item, action, retval, + htab, flag, hval, idx); + if (ret != -1) + return ret; } while (htab->table[idx].used); } -- cgit v1.2.1 From 7afcf3a55b5f484b3d3442053fae8186a3fb92d7 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 11 Dec 2012 22:16:21 -0600 Subject: env: Refactor apply into change_ok Move the read of the old value to inside the check function. In some cases it can be avoided all together and at the least the code is only called from one place. Also name the function and the callback to more clearly describe what it does. Pass the ENTRY instead of just the name for direct access to the whole data structure. Pass an enum to the callback that specifies the operation being approved. Signed-off-by: Joe Hershberger --- lib/hashtable.c | 70 +++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 27 deletions(-) (limited to 'lib') diff --git a/lib/hashtable.c b/lib/hashtable.c index f4d5795059..6861a42029 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -66,12 +66,16 @@ * Instead the interface of all functions is extended to take an argument * which describes the current status. */ + typedef struct _ENTRY { int used; ENTRY entry; } _ENTRY; +static void _hdelete(const char *key, struct hsearch_data *htab, ENTRY *ep, + int idx); + /* * hcreate() */ @@ -259,6 +263,17 @@ static inline int _compare_and_overwrite_entry(ENTRY item, ACTION action, && strcmp(item.key, htab->table[idx].entry.key) == 0) { /* Overwrite existing value? */ if ((action == ENTER) && (item.data != NULL)) { + /* check for permission */ + if (htab->change_ok != NULL && htab->change_ok( + &htab->table[idx].entry, item.data, + env_op_overwrite, flag)) { + debug("change_ok() rejected setting variable " + "%s, skipping it!\n", item.key); + __set_errno(EPERM); + *retval = NULL; + return 0; + } + free(htab->table[idx].entry.data); htab->table[idx].entry.data = strdup(item.data); if (!htab->table[idx].entry.data) { @@ -383,6 +398,17 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval, ++htab->filled; + /* check for permission */ + if (htab->change_ok != NULL && htab->change_ok( + &htab->table[idx].entry, item.data, env_op_create, flag)) { + debug("change_ok() rejected setting variable " + "%s, skipping it!\n", item.key); + _hdelete(item.key, htab, &htab->table[idx].entry, idx); + __set_errno(EPERM); + *retval = NULL; + return 0; + } + /* return new entry */ *retval = &htab->table[idx].entry; return 1; @@ -404,6 +430,18 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval, * do that. */ +static void _hdelete(const char *key, struct hsearch_data *htab, ENTRY *ep, + int idx) +{ + /* free used ENTRY */ + debug("hdelete: DELETING key \"%s\"\n", key); + free((void *)ep->key); + free(ep->data); + htab->table[idx].used = -1; + + --htab->filled; +} + int hdelete_r(const char *key, struct hsearch_data *htab, int flag) { ENTRY e, *ep; @@ -420,19 +458,15 @@ int hdelete_r(const char *key, struct hsearch_data *htab, int flag) } /* Check for permission */ - if (htab->apply != NULL && - htab->apply(ep->key, ep->data, NULL, flag)) { + if (htab->change_ok != NULL && + htab->change_ok(ep, NULL, env_op_delete, flag)) { + debug("change_ok() rejected deleting variable " + "%s, skipping it!\n", key); __set_errno(EPERM); return 0; } - /* free used ENTRY */ - debug("hdelete: DELETING key \"%s\"\n", key); - free((void *)ep->key); - free(ep->data); - htab->table[idx].used = -1; - - --htab->filled; + _hdelete(key, htab, ep, idx); return 1; } @@ -800,24 +834,6 @@ int himport_r(struct hsearch_data *htab, e.key = name; e.data = value; - /* if there is an apply function, check what it has to say */ - if (htab->apply != NULL) { - debug("searching before calling cb function" - " for %s\n", name); - /* - * Search for variable in existing env, so to pass - * its previous value to the apply callback - */ - hsearch_r(e, FIND, &rv, htab, 0); - debug("previous value was %s\n", rv ? rv->data : ""); - if (htab->apply(name, rv ? rv->data : NULL, - value, flag)) { - debug("callback function refused to set" - " variable %s, skipping it!\n", name); - continue; - } - } - hsearch_r(e, ENTER, &rv, htab, flag); if (rv == NULL) { printf("himport_r: can't insert \"%s=%s\" into hash table\n", -- cgit v1.2.1 From be11235ab802844e12d84921a38fd8ae4ddda080 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 11 Dec 2012 22:16:23 -0600 Subject: env: Hide '.' variables in env print by default When printing all variables with env print, don't print variables that begin with '.'. If env print is called with a '-a' switch, then include variables that begin with '.' (just like the ls command). Variables printed explicitly will be printed even without the -a. Signed-off-by: Joe Hershberger --- lib/hashtable.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/hashtable.c b/lib/hashtable.c index 6861a42029..7c6b96cac8 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -522,7 +522,7 @@ static int cmpkey(const void *p1, const void *p2) return (strcmp(e1->key, e2->key)); } -ssize_t hexport_r(struct hsearch_data *htab, const char sep, +ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag, char **resp, size_t size, int argc, char * const argv[]) { @@ -559,6 +559,9 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep, if ((argc > 0) && (found == 0)) continue; + if ((flag & H_HIDE_DOT) && ep->key[0] == '.') + continue; + list[n++] = ep; totlen += strlen(ep->key) + 2; -- cgit v1.2.1 From 170ab11075d3be56e89d6444abf1148329130f4b Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 11 Dec 2012 22:16:24 -0600 Subject: env: Add support for callbacks to environment vars Add support for per-variable callbacks to the "hashtable" functions. Signed-off-by: Joe Hershberger !!!fix comment in callback --- lib/hashtable.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/hashtable.c b/lib/hashtable.c index 7c6b96cac8..e9226665f3 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -54,7 +54,8 @@ #define CONFIG_ENV_MAX_ENTRIES 512 #endif -#include "search.h" +#include +#include /* * [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986 @@ -274,6 +275,17 @@ static inline int _compare_and_overwrite_entry(ENTRY item, ACTION action, return 0; } + /* If there is a callback, call it */ + if (htab->table[idx].entry.callback && + htab->table[idx].entry.callback(item.key, + item.data, env_op_overwrite, flag)) { + debug("callback() rejected setting variable " + "%s, skipping it!\n", item.key); + __set_errno(EINVAL); + *retval = NULL; + return 0; + } + free(htab->table[idx].entry.data); htab->table[idx].entry.data = strdup(item.data); if (!htab->table[idx].entry.data) { @@ -398,6 +410,9 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval, ++htab->filled; + /* This is a new entry, so look up a possible callback */ + env_callback_init(&htab->table[idx].entry); + /* check for permission */ if (htab->change_ok != NULL && htab->change_ok( &htab->table[idx].entry, item.data, env_op_create, flag)) { @@ -409,6 +424,18 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval, return 0; } + /* If there is a callback, call it */ + if (htab->table[idx].entry.callback && + htab->table[idx].entry.callback(item.key, item.data, + env_op_create, flag)) { + debug("callback() rejected setting variable " + "%s, skipping it!\n", item.key); + _hdelete(item.key, htab, &htab->table[idx].entry, idx); + __set_errno(EINVAL); + *retval = NULL; + return 0; + } + /* return new entry */ *retval = &htab->table[idx].entry; return 1; @@ -437,6 +464,7 @@ static void _hdelete(const char *key, struct hsearch_data *htab, ENTRY *ep, debug("hdelete: DELETING key \"%s\"\n", key); free((void *)ep->key); free(ep->data); + ep->callback = NULL; htab->table[idx].used = -1; --htab->filled; @@ -466,6 +494,15 @@ int hdelete_r(const char *key, struct hsearch_data *htab, int flag) return 0; } + /* If there is a callback, call it */ + if (htab->table[idx].entry.callback && + htab->table[idx].entry.callback(key, NULL, env_op_delete, flag)) { + debug("callback() rejected deleting variable " + "%s, skipping it!\n", key); + __set_errno(EINVAL); + return 0; + } + _hdelete(key, htab, ep, idx); return 1; @@ -838,11 +875,9 @@ int himport_r(struct hsearch_data *htab, e.data = value; hsearch_r(e, ENTER, &rv, htab, flag); - if (rv == NULL) { + if (rv == NULL) printf("himport_r: can't insert \"%s=%s\" into hash table\n", name, value); - return 0; - } debug("INSERT: table %p, filled %d/%d rv %p ==> name=\"%s\" value=\"%s\"\n", htab, htab->filled, htab->size, @@ -873,3 +908,27 @@ int himport_r(struct hsearch_data *htab, debug("INSERT: done\n"); return 1; /* everything OK */ } + +/* + * hwalk_r() + */ + +/* + * Walk all of the entries in the hash, calling the callback for each one. + * this allows some generic operation to be performed on each element. + */ +int hwalk_r(struct hsearch_data *htab, int (*callback)(ENTRY *)) +{ + int i; + int retval; + + for (i = 1; i <= htab->size; ++i) { + if (htab->table[i].used > 0) { + retval = callback(&htab->table[i].entry); + if (retval) + return retval; + } + } + + return 0; +} -- cgit v1.2.1 From 2598090b7e17f8bdca95b22e7f27217054730e02 Mon Sep 17 00:00:00 2001 From: Joe Hershberger Date: Tue, 11 Dec 2012 22:16:31 -0600 Subject: env: Add environment variable flags Currently just validates variable types as decimal, hexidecimal, boolean, ip address, and mac address. If the entry is not found in the env ".flags", then look in the static one. This allows the env to override the static definitions, but prevents the need to have every definition in the environment distracting you. Signed-off-by: Joe Hershberger --- lib/hashtable.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'lib') diff --git a/lib/hashtable.c b/lib/hashtable.c index e9226665f3..07ebfb218f 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -55,6 +55,7 @@ #endif #include +#include #include /* @@ -412,6 +413,8 @@ int hsearch_r(ENTRY item, ACTION action, ENTRY ** retval, /* This is a new entry, so look up a possible callback */ env_callback_init(&htab->table[idx].entry); + /* Also look for flags */ + env_flags_init(&htab->table[idx].entry); /* check for permission */ if (htab->change_ok != NULL && htab->change_ok( @@ -465,6 +468,7 @@ static void _hdelete(const char *key, struct hsearch_data *htab, ENTRY *ep, free((void *)ep->key); free(ep->data); ep->callback = NULL; + ep->flags = 0; htab->table[idx].used = -1; --htab->filled; -- cgit v1.2.1