libarchive: add a function to unpack embedded data
Similar code to unpack embedded data is used to decompress usage messages, embedded scripts and the config file (in the non-default bbconfig applet). Moving this code to a common function reduces the size of the default build and hides more of the internals of libarchive. function old new delta unpack_bz2_data - 135 +135 bb_show_usage 137 157 +20 get_script_content 32 47 +15 unpack_scripts 119 - -119 unpack_usage_messages 124 - -124 ------------------------------------------------------------------------------ (add/remove: 1/2 grow/shrink: 2/0 up/down: 170/-243) Total: -73 bytes Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
parent
0df289f427
commit
c339c7f7b3
@ -107,7 +107,7 @@ struct bunzip_data {
|
|||||||
uint8_t selectors[32768]; /* nSelectors=15 bits */
|
uint8_t selectors[32768]; /* nSelectors=15 bits */
|
||||||
struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */
|
struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */
|
||||||
};
|
};
|
||||||
/* typedef struct bunzip_data bunzip_data; -- done in .h file */
|
typedef struct bunzip_data bunzip_data;
|
||||||
|
|
||||||
|
|
||||||
/* Return the next nnn bits of input. All reads from the compressed input
|
/* Return the next nnn bits of input. All reads from the compressed input
|
||||||
@ -575,7 +575,7 @@ static int get_next_block(bunzip_data *bd)
|
|||||||
in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0.
|
in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0.
|
||||||
(Why? This allows to get rid of one local variable)
|
(Why? This allows to get rid of one local variable)
|
||||||
*/
|
*/
|
||||||
int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len)
|
static int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len)
|
||||||
{
|
{
|
||||||
const uint32_t *dbuf;
|
const uint32_t *dbuf;
|
||||||
int pos, current, previous;
|
int pos, current, previous;
|
||||||
@ -699,7 +699,7 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len)
|
|||||||
/* Because bunzip2 is used for help text unpacking, and because bb_show_usage()
|
/* Because bunzip2 is used for help text unpacking, and because bb_show_usage()
|
||||||
should work for NOFORK applets too, we must be extremely careful to not leak
|
should work for NOFORK applets too, we must be extremely careful to not leak
|
||||||
any allocations! */
|
any allocations! */
|
||||||
int FAST_FUNC start_bunzip(
|
static int FAST_FUNC start_bunzip(
|
||||||
void *jmpbuf,
|
void *jmpbuf,
|
||||||
bunzip_data **bdp,
|
bunzip_data **bdp,
|
||||||
int in_fd,
|
int in_fd,
|
||||||
@ -759,7 +759,7 @@ int FAST_FUNC start_bunzip(
|
|||||||
return RETVAL_OK;
|
return RETVAL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FAST_FUNC dealloc_bunzip(bunzip_data *bd)
|
static void FAST_FUNC dealloc_bunzip(bunzip_data *bd)
|
||||||
{
|
{
|
||||||
free(bd->dbuf);
|
free(bd->dbuf);
|
||||||
free(bd);
|
free(bd);
|
||||||
@ -847,6 +847,36 @@ unpack_bz2_stream(transformer_state_t *xstate)
|
|||||||
return i ? i : IF_DESKTOP(total_written) + 0;
|
return i ? i : IF_DESKTOP(total_written) + 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* FAST_FUNC
|
||||||
|
unpack_bz2_data(const char *packed, int packed_len, int unpacked_len)
|
||||||
|
{
|
||||||
|
char *outbuf = NULL;
|
||||||
|
bunzip_data *bd;
|
||||||
|
int i;
|
||||||
|
jmp_buf jmpbuf;
|
||||||
|
|
||||||
|
/* Setup for I/O error handling via longjmp */
|
||||||
|
i = setjmp(jmpbuf);
|
||||||
|
if (i == 0) {
|
||||||
|
i = start_bunzip(&jmpbuf,
|
||||||
|
&bd,
|
||||||
|
/* src_fd: */ -1,
|
||||||
|
/* inbuf: */ packed,
|
||||||
|
/* len: */ packed_len
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/* read_bunzip can longjmp and end up here with i != 0
|
||||||
|
* on read data errors! Not trivial */
|
||||||
|
if (i == 0) {
|
||||||
|
/* Cannot use xmalloc: will leak bd in NOFORK case! */
|
||||||
|
outbuf = malloc_or_warn(unpacked_len);
|
||||||
|
if (outbuf)
|
||||||
|
read_bunzip(bd, outbuf, unpacked_len);
|
||||||
|
}
|
||||||
|
dealloc_bunzip(bd);
|
||||||
|
return outbuf;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TESTING
|
#ifdef TESTING
|
||||||
|
|
||||||
static char *const bunzip_errors[] = {
|
static char *const bunzip_errors[] = {
|
||||||
|
@ -214,12 +214,7 @@ const llist_t *find_list_entry(const llist_t *list, const char *filename) FAST_F
|
|||||||
const llist_t *find_list_entry2(const llist_t *list, const char *filename) FAST_FUNC;
|
const llist_t *find_list_entry2(const llist_t *list, const char *filename) FAST_FUNC;
|
||||||
|
|
||||||
/* A bit of bunzip2 internals are exposed for compressed help support: */
|
/* A bit of bunzip2 internals are exposed for compressed help support: */
|
||||||
typedef struct bunzip_data bunzip_data;
|
char *unpack_bz2_data(const char *packed, int packed_len, int unpacked_len) FAST_FUNC;
|
||||||
int start_bunzip(void *, bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_FUNC;
|
|
||||||
/* NB: read_bunzip returns < 0 on error, or the number of *unfilled* bytes
|
|
||||||
* in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0: */
|
|
||||||
int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC;
|
|
||||||
void dealloc_bunzip(bunzip_data *bd) FAST_FUNC;
|
|
||||||
|
|
||||||
/* Meaning and direction (input/output) of the fields are transformer-specific */
|
/* Meaning and direction (input/output) of the fields are transformer-specific */
|
||||||
typedef struct transformer_state_t {
|
typedef struct transformer_state_t {
|
||||||
|
@ -107,34 +107,8 @@ static const char usage_messages[] ALIGN1 = UNPACKED_USAGE;
|
|||||||
|
|
||||||
static const char packed_usage[] ALIGN1 = { PACKED_USAGE };
|
static const char packed_usage[] ALIGN1 = { PACKED_USAGE };
|
||||||
# include "bb_archive.h"
|
# include "bb_archive.h"
|
||||||
static const char *unpack_usage_messages(void)
|
# define unpack_usage_messages() \
|
||||||
{
|
unpack_bz2_data(packed_usage, sizeof(packed_usage), sizeof(UNPACKED_USAGE))
|
||||||
char *outbuf = NULL;
|
|
||||||
bunzip_data *bd;
|
|
||||||
int i;
|
|
||||||
jmp_buf jmpbuf;
|
|
||||||
|
|
||||||
/* Setup for I/O error handling via longjmp */
|
|
||||||
i = setjmp(jmpbuf);
|
|
||||||
if (i == 0) {
|
|
||||||
i = start_bunzip(&jmpbuf,
|
|
||||||
&bd,
|
|
||||||
/* src_fd: */ -1,
|
|
||||||
/* inbuf: */ packed_usage,
|
|
||||||
/* len: */ sizeof(packed_usage)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
/* read_bunzip can longjmp and end up here with i != 0
|
|
||||||
* on read data errors! Not trivial */
|
|
||||||
if (i == 0) {
|
|
||||||
/* Cannot use xmalloc: will leak bd in NOFORK case! */
|
|
||||||
outbuf = malloc_or_warn(sizeof(UNPACKED_USAGE));
|
|
||||||
if (outbuf)
|
|
||||||
read_bunzip(bd, outbuf, sizeof(UNPACKED_USAGE));
|
|
||||||
}
|
|
||||||
dealloc_bunzip(bd);
|
|
||||||
return outbuf;
|
|
||||||
}
|
|
||||||
# define dealloc_usage_messages(s) free(s)
|
# define dealloc_usage_messages(s) free(s)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -152,21 +126,23 @@ void FAST_FUNC bb_show_usage(void)
|
|||||||
/* Imagine that this applet is "true". Dont suck in printf! */
|
/* Imagine that this applet is "true". Dont suck in printf! */
|
||||||
const char *usage_string = unpack_usage_messages();
|
const char *usage_string = unpack_usage_messages();
|
||||||
|
|
||||||
if (*usage_string == '\b') {
|
if (usage_string) {
|
||||||
full_write2_str("No help available.\n\n");
|
if (*usage_string == '\b') {
|
||||||
} else {
|
full_write2_str("No help available.\n\n");
|
||||||
full_write2_str("Usage: "SINGLE_APPLET_STR" ");
|
} else {
|
||||||
full_write2_str(usage_string);
|
full_write2_str("Usage: "SINGLE_APPLET_STR" ");
|
||||||
full_write2_str("\n\n");
|
full_write2_str(usage_string);
|
||||||
|
full_write2_str("\n\n");
|
||||||
|
}
|
||||||
|
if (ENABLE_FEATURE_CLEAN_UP)
|
||||||
|
dealloc_usage_messages((char*)usage_string);
|
||||||
}
|
}
|
||||||
if (ENABLE_FEATURE_CLEAN_UP)
|
|
||||||
dealloc_usage_messages((char*)usage_string);
|
|
||||||
#else
|
#else
|
||||||
const char *p;
|
const char *p;
|
||||||
const char *usage_string = p = unpack_usage_messages();
|
const char *usage_string = p = unpack_usage_messages();
|
||||||
int ap = find_applet_by_name(applet_name);
|
int ap = find_applet_by_name(applet_name);
|
||||||
|
|
||||||
if (ap < 0) /* never happens, paranoia */
|
if (ap < 0 || usage_string == NULL)
|
||||||
xfunc_die();
|
xfunc_die();
|
||||||
while (ap) {
|
while (ap) {
|
||||||
while (*p++) continue;
|
while (*p++) continue;
|
||||||
@ -986,38 +962,11 @@ find_script_by_name(const char *name)
|
|||||||
return -0x10000; /* make it so that NUM_APPLETS + <error> is still < 0 */
|
return -0x10000; /* make it so that NUM_APPLETS + <error> is still < 0 */
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
|
||||||
unpack_scripts(void)
|
|
||||||
{
|
|
||||||
char *outbuf = NULL;
|
|
||||||
bunzip_data *bd;
|
|
||||||
int i;
|
|
||||||
jmp_buf jmpbuf;
|
|
||||||
|
|
||||||
/* Setup for I/O error handling via longjmp */
|
|
||||||
i = setjmp(jmpbuf);
|
|
||||||
if (i == 0) {
|
|
||||||
i = start_bunzip(&jmpbuf,
|
|
||||||
&bd,
|
|
||||||
/* src_fd: */ -1,
|
|
||||||
/* inbuf: */ packed_scripts,
|
|
||||||
/* len: */ sizeof(packed_scripts)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
/* read_bunzip can longjmp and end up here with i != 0
|
|
||||||
* on read data errors! Not trivial */
|
|
||||||
if (i == 0) {
|
|
||||||
outbuf = xmalloc(UNPACKED_SCRIPTS_LENGTH);
|
|
||||||
read_bunzip(bd, outbuf, UNPACKED_SCRIPTS_LENGTH);
|
|
||||||
}
|
|
||||||
dealloc_bunzip(bd);
|
|
||||||
return outbuf;
|
|
||||||
}
|
|
||||||
|
|
||||||
char* FAST_FUNC
|
char* FAST_FUNC
|
||||||
get_script_content(unsigned n)
|
get_script_content(unsigned n)
|
||||||
{
|
{
|
||||||
char *t = unpack_scripts();
|
char *t = unpack_bz2_data(packed_scripts, sizeof(packed_scripts),
|
||||||
|
UNPACKED_SCRIPTS_LENGTH);
|
||||||
if (t) {
|
if (t) {
|
||||||
while (n != 0) {
|
while (n != 0) {
|
||||||
while (*t++ != '\0')
|
while (*t++ != '\0')
|
||||||
|
@ -43,29 +43,10 @@ int bbconfig_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
|
|||||||
int bbconfig_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
int bbconfig_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
|
||||||
{
|
{
|
||||||
#if ENABLE_FEATURE_COMPRESS_BBCONFIG
|
#if ENABLE_FEATURE_COMPRESS_BBCONFIG
|
||||||
bunzip_data *bd;
|
const char *outbuf = unpack_bz2_data(bbconfig_config_bz2,
|
||||||
int i;
|
sizeof(bbconfig_config_bz2), sizeof(bbconfig_config));
|
||||||
jmp_buf jmpbuf;
|
if (outbuf) {
|
||||||
|
full_write1_str(outbuf);
|
||||||
/* Setup for I/O error handling via longjmp */
|
|
||||||
i = setjmp(jmpbuf);
|
|
||||||
if (i == 0) {
|
|
||||||
i = start_bunzip(&jmpbuf,
|
|
||||||
&bd,
|
|
||||||
/* src_fd: */ -1,
|
|
||||||
/* inbuf: */ bbconfig_config_bz2,
|
|
||||||
/* len: */ sizeof(bbconfig_config_bz2)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
/* read_bunzip can longjmp and end up here with i != 0
|
|
||||||
* on read data errors! Not trivial */
|
|
||||||
if (i == 0) {
|
|
||||||
/* Cannot use xmalloc: will leak bd in NOFORK case! */
|
|
||||||
char *outbuf = malloc_or_warn(sizeof(bbconfig_config));
|
|
||||||
if (outbuf) {
|
|
||||||
read_bunzip(bd, outbuf, sizeof(bbconfig_config));
|
|
||||||
full_write1_str(outbuf);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
full_write1_str(bbconfig_config);
|
full_write1_str(bbconfig_config);
|
||||||
|
Loading…
Reference in New Issue
Block a user