aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2018-11-02 14:14:31 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2018-11-02 14:14:51 +0100
commitc339c7f7b393fbcd51b0f96df837baa1edad7fd8 (patch)
tree3fa49732a3426e0666ba732da7e4182db7dc66ca
parent0df289f427da6279e3ca198d14e90015c079af44 (diff)
downloadbusybox-w32-c339c7f7b393fbcd51b0f96df837baa1edad7fd8.tar.gz
busybox-w32-c339c7f7b393fbcd51b0f96df837baa1edad7fd8.tar.bz2
busybox-w32-c339c7f7b393fbcd51b0f96df837baa1edad7fd8.zip
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>
-rw-r--r--archival/libarchive/decompress_bunzip2.c38
-rw-r--r--include/bb_archive.h7
-rw-r--r--libbb/appletlib.c81
-rw-r--r--miscutils/bbconfig.c27
4 files changed, 54 insertions, 99 deletions
diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c
index 7ef4e035f..6f2c49fbc 100644
--- a/archival/libarchive/decompress_bunzip2.c
+++ b/archival/libarchive/decompress_bunzip2.c
@@ -107,7 +107,7 @@ struct bunzip_data {
107 uint8_t selectors[32768]; /* nSelectors=15 bits */ 107 uint8_t selectors[32768]; /* nSelectors=15 bits */
108 struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */ 108 struct group_data groups[MAX_GROUPS]; /* Huffman coding tables */
109}; 109};
110/* typedef struct bunzip_data bunzip_data; -- done in .h file */ 110typedef struct bunzip_data bunzip_data;
111 111
112 112
113/* Return the next nnn bits of input. All reads from the compressed input 113/* 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)
575 in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0. 575 in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0.
576 (Why? This allows to get rid of one local variable) 576 (Why? This allows to get rid of one local variable)
577*/ 577*/
578int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len) 578static int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len)
579{ 579{
580 const uint32_t *dbuf; 580 const uint32_t *dbuf;
581 int pos, current, previous; 581 int pos, current, previous;
@@ -699,7 +699,7 @@ int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len)
699/* Because bunzip2 is used for help text unpacking, and because bb_show_usage() 699/* Because bunzip2 is used for help text unpacking, and because bb_show_usage()
700 should work for NOFORK applets too, we must be extremely careful to not leak 700 should work for NOFORK applets too, we must be extremely careful to not leak
701 any allocations! */ 701 any allocations! */
702int FAST_FUNC start_bunzip( 702static int FAST_FUNC start_bunzip(
703 void *jmpbuf, 703 void *jmpbuf,
704 bunzip_data **bdp, 704 bunzip_data **bdp,
705 int in_fd, 705 int in_fd,
@@ -759,7 +759,7 @@ int FAST_FUNC start_bunzip(
759 return RETVAL_OK; 759 return RETVAL_OK;
760} 760}
761 761
762void FAST_FUNC dealloc_bunzip(bunzip_data *bd) 762static void FAST_FUNC dealloc_bunzip(bunzip_data *bd)
763{ 763{
764 free(bd->dbuf); 764 free(bd->dbuf);
765 free(bd); 765 free(bd);
@@ -847,6 +847,36 @@ unpack_bz2_stream(transformer_state_t *xstate)
847 return i ? i : IF_DESKTOP(total_written) + 0; 847 return i ? i : IF_DESKTOP(total_written) + 0;
848} 848}
849 849
850char* FAST_FUNC
851unpack_bz2_data(const char *packed, int packed_len, int unpacked_len)
852{
853 char *outbuf = NULL;
854 bunzip_data *bd;
855 int i;
856 jmp_buf jmpbuf;
857
858 /* Setup for I/O error handling via longjmp */
859 i = setjmp(jmpbuf);
860 if (i == 0) {
861 i = start_bunzip(&jmpbuf,
862 &bd,
863 /* src_fd: */ -1,
864 /* inbuf: */ packed,
865 /* len: */ packed_len
866 );
867 }
868 /* read_bunzip can longjmp and end up here with i != 0
869 * on read data errors! Not trivial */
870 if (i == 0) {
871 /* Cannot use xmalloc: will leak bd in NOFORK case! */
872 outbuf = malloc_or_warn(unpacked_len);
873 if (outbuf)
874 read_bunzip(bd, outbuf, unpacked_len);
875 }
876 dealloc_bunzip(bd);
877 return outbuf;
878}
879
850#ifdef TESTING 880#ifdef TESTING
851 881
852static char *const bunzip_errors[] = { 882static char *const bunzip_errors[] = {
diff --git a/include/bb_archive.h b/include/bb_archive.h
index d2022336b..561dd0c9d 100644
--- a/include/bb_archive.h
+++ b/include/bb_archive.h
@@ -214,12 +214,7 @@ const llist_t *find_list_entry(const llist_t *list, const char *filename) FAST_F
214const llist_t *find_list_entry2(const llist_t *list, const char *filename) FAST_FUNC; 214const llist_t *find_list_entry2(const llist_t *list, const char *filename) FAST_FUNC;
215 215
216/* A bit of bunzip2 internals are exposed for compressed help support: */ 216/* A bit of bunzip2 internals are exposed for compressed help support: */
217typedef struct bunzip_data bunzip_data; 217char *unpack_bz2_data(const char *packed, int packed_len, int unpacked_len) FAST_FUNC;
218int start_bunzip(void *, bunzip_data **bdp, int in_fd, const void *inbuf, int len) FAST_FUNC;
219/* NB: read_bunzip returns < 0 on error, or the number of *unfilled* bytes
220 * in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0: */
221int read_bunzip(bunzip_data *bd, char *outbuf, int len) FAST_FUNC;
222void dealloc_bunzip(bunzip_data *bd) FAST_FUNC;
223 218
224/* Meaning and direction (input/output) of the fields are transformer-specific */ 219/* Meaning and direction (input/output) of the fields are transformer-specific */
225typedef struct transformer_state_t { 220typedef struct transformer_state_t {
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index d48b2ea60..6dfaf1f41 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -107,34 +107,8 @@ static const char usage_messages[] ALIGN1 = UNPACKED_USAGE;
107 107
108static const char packed_usage[] ALIGN1 = { PACKED_USAGE }; 108static const char packed_usage[] ALIGN1 = { PACKED_USAGE };
109# include "bb_archive.h" 109# include "bb_archive.h"
110static const char *unpack_usage_messages(void) 110# define unpack_usage_messages() \
111{ 111 unpack_bz2_data(packed_usage, sizeof(packed_usage), sizeof(UNPACKED_USAGE))
112 char *outbuf = NULL;
113 bunzip_data *bd;
114 int i;
115 jmp_buf jmpbuf;
116
117 /* Setup for I/O error handling via longjmp */
118 i = setjmp(jmpbuf);
119 if (i == 0) {
120 i = start_bunzip(&jmpbuf,
121 &bd,
122 /* src_fd: */ -1,
123 /* inbuf: */ packed_usage,
124 /* len: */ sizeof(packed_usage)
125 );
126 }
127 /* read_bunzip can longjmp and end up here with i != 0
128 * on read data errors! Not trivial */
129 if (i == 0) {
130 /* Cannot use xmalloc: will leak bd in NOFORK case! */
131 outbuf = malloc_or_warn(sizeof(UNPACKED_USAGE));
132 if (outbuf)
133 read_bunzip(bd, outbuf, sizeof(UNPACKED_USAGE));
134 }
135 dealloc_bunzip(bd);
136 return outbuf;
137}
138# define dealloc_usage_messages(s) free(s) 112# define dealloc_usage_messages(s) free(s)
139 113
140#else 114#else
@@ -152,21 +126,23 @@ void FAST_FUNC bb_show_usage(void)
152 /* Imagine that this applet is "true". Dont suck in printf! */ 126 /* Imagine that this applet is "true". Dont suck in printf! */
153 const char *usage_string = unpack_usage_messages(); 127 const char *usage_string = unpack_usage_messages();
154 128
155 if (*usage_string == '\b') { 129 if (usage_string) {
156 full_write2_str("No help available.\n\n"); 130 if (*usage_string == '\b') {
157 } else { 131 full_write2_str("No help available.\n\n");
158 full_write2_str("Usage: "SINGLE_APPLET_STR" "); 132 } else {
159 full_write2_str(usage_string); 133 full_write2_str("Usage: "SINGLE_APPLET_STR" ");
160 full_write2_str("\n\n"); 134 full_write2_str(usage_string);
135 full_write2_str("\n\n");
136 }
137 if (ENABLE_FEATURE_CLEAN_UP)
138 dealloc_usage_messages((char*)usage_string);
161 } 139 }
162 if (ENABLE_FEATURE_CLEAN_UP)
163 dealloc_usage_messages((char*)usage_string);
164#else 140#else
165 const char *p; 141 const char *p;
166 const char *usage_string = p = unpack_usage_messages(); 142 const char *usage_string = p = unpack_usage_messages();
167 int ap = find_applet_by_name(applet_name); 143 int ap = find_applet_by_name(applet_name);
168 144
169 if (ap < 0) /* never happens, paranoia */ 145 if (ap < 0 || usage_string == NULL)
170 xfunc_die(); 146 xfunc_die();
171 while (ap) { 147 while (ap) {
172 while (*p++) continue; 148 while (*p++) continue;
@@ -986,38 +962,11 @@ find_script_by_name(const char *name)
986 return -0x10000; /* make it so that NUM_APPLETS + <error> is still < 0 */ 962 return -0x10000; /* make it so that NUM_APPLETS + <error> is still < 0 */
987} 963}
988 964
989static char *
990unpack_scripts(void)
991{
992 char *outbuf = NULL;
993 bunzip_data *bd;
994 int i;
995 jmp_buf jmpbuf;
996
997 /* Setup for I/O error handling via longjmp */
998 i = setjmp(jmpbuf);
999 if (i == 0) {
1000 i = start_bunzip(&jmpbuf,
1001 &bd,
1002 /* src_fd: */ -1,
1003 /* inbuf: */ packed_scripts,
1004 /* len: */ sizeof(packed_scripts)
1005 );
1006 }
1007 /* read_bunzip can longjmp and end up here with i != 0
1008 * on read data errors! Not trivial */
1009 if (i == 0) {
1010 outbuf = xmalloc(UNPACKED_SCRIPTS_LENGTH);
1011 read_bunzip(bd, outbuf, UNPACKED_SCRIPTS_LENGTH);
1012 }
1013 dealloc_bunzip(bd);
1014 return outbuf;
1015}
1016
1017char* FAST_FUNC 965char* FAST_FUNC
1018get_script_content(unsigned n) 966get_script_content(unsigned n)
1019{ 967{
1020 char *t = unpack_scripts(); 968 char *t = unpack_bz2_data(packed_scripts, sizeof(packed_scripts),
969 UNPACKED_SCRIPTS_LENGTH);
1021 if (t) { 970 if (t) {
1022 while (n != 0) { 971 while (n != 0) {
1023 while (*t++ != '\0') 972 while (*t++ != '\0')
diff --git a/miscutils/bbconfig.c b/miscutils/bbconfig.c
index 501349548..fe02516a8 100644
--- a/miscutils/bbconfig.c
+++ b/miscutils/bbconfig.c
@@ -43,29 +43,10 @@ int bbconfig_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
43int bbconfig_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) 43int bbconfig_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM)
44{ 44{
45#if ENABLE_FEATURE_COMPRESS_BBCONFIG 45#if ENABLE_FEATURE_COMPRESS_BBCONFIG
46 bunzip_data *bd; 46 const char *outbuf = unpack_bz2_data(bbconfig_config_bz2,
47 int i; 47 sizeof(bbconfig_config_bz2), sizeof(bbconfig_config));
48 jmp_buf jmpbuf; 48 if (outbuf) {
49 49 full_write1_str(outbuf);
50 /* Setup for I/O error handling via longjmp */
51 i = setjmp(jmpbuf);
52 if (i == 0) {
53 i = start_bunzip(&jmpbuf,
54 &bd,
55 /* src_fd: */ -1,
56 /* inbuf: */ bbconfig_config_bz2,
57 /* len: */ sizeof(bbconfig_config_bz2)
58 );
59 }
60 /* read_bunzip can longjmp and end up here with i != 0
61 * on read data errors! Not trivial */
62 if (i == 0) {
63 /* Cannot use xmalloc: will leak bd in NOFORK case! */
64 char *outbuf = malloc_or_warn(sizeof(bbconfig_config));
65 if (outbuf) {
66 read_bunzip(bd, outbuf, sizeof(bbconfig_config));
67 full_write1_str(outbuf);
68 }
69 } 50 }
70#else 51#else
71 full_write1_str(bbconfig_config); 52 full_write1_str(bbconfig_config);