aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2017-02-08 20:09:29 +0000
committerRon Yorston <rmy@pobox.com>2017-02-08 20:09:29 +0000
commit373275a708bafb88fa4f0519de2166154f44fed9 (patch)
tree4587b4fd3f695e0f3705b2a217e199f3144df931 /libbb
parentb74b2619779b1deb903b7766261807df1e9b1f7f (diff)
parentc2b18583a3df06aeecf535c3cea6856aa1f2e205 (diff)
downloadbusybox-w32-373275a708bafb88fa4f0519de2166154f44fed9.tar.gz
busybox-w32-373275a708bafb88fa4f0519de2166154f44fed9.tar.bz2
busybox-w32-373275a708bafb88fa4f0519de2166154f44fed9.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'libbb')
-rw-r--r--libbb/Config.src17
-rw-r--r--libbb/appletlib.c6
-rw-r--r--libbb/crc32.c2
-rw-r--r--libbb/dump.c171
-rw-r--r--libbb/getopt32.c4
-rw-r--r--libbb/hash_md5_sha.c127
-rw-r--r--libbb/hash_md5prime.c3
-rw-r--r--libbb/lineedit.c2
-rw-r--r--libbb/match_fstype.c20
-rw-r--r--libbb/procps.c24
-rw-r--r--libbb/pw_encrypt.c2
-rw-r--r--libbb/pw_encrypt_sha.c18
-rw-r--r--libbb/vfork_daemon_rexec.c38
-rw-r--r--libbb/xfuncs.c37
14 files changed, 259 insertions, 212 deletions
diff --git a/libbb/Config.src b/libbb/Config.src
index 172fbcc0e..c51640305 100644
--- a/libbb/Config.src
+++ b/libbb/Config.src
@@ -70,24 +70,13 @@ config FEATURE_FAST_TOP
70 but code size is slightly bigger. 70 but code size is slightly bigger.
71 71
72config FEATURE_ETC_NETWORKS 72config FEATURE_ETC_NETWORKS
73 bool "Support for /etc/networks" 73 bool "Support /etc/networks"
74 default n 74 default n
75 help 75 help
76 Enable support for network names in /etc/networks. This is 76 Enable support for network names in /etc/networks. This is
77 a rarely used feature which allows you to use names 77 a rarely used feature which allows you to use names
78 instead of IP/mask pairs in route command. 78 instead of IP/mask pairs in route command.
79 79
80config FEATURE_USE_TERMIOS
81 bool "Use termios to manipulate the screen"
82 default y
83 depends on MORE || TOP || POWERTOP
84 help
85 This option allows utilities such as 'more' and 'top' to determine
86 the size of the screen. If you leave this disabled, your utilities
87 that display things on the screen will be especially primitive and
88 will be unable to determine the current screen size, and will be
89 unable to move the cursor.
90
91config FEATURE_EDITING 80config FEATURE_EDITING
92 bool "Command line editing" 81 bool "Command line editing"
93 default y 82 default y
@@ -147,15 +136,11 @@ config FEATURE_TAB_COMPLETION
147 bool "Tab completion" 136 bool "Tab completion"
148 default y 137 default y
149 depends on FEATURE_EDITING 138 depends on FEATURE_EDITING
150 help
151 Enable tab completion.
152 139
153config FEATURE_USERNAME_COMPLETION 140config FEATURE_USERNAME_COMPLETION
154 bool "Username completion" 141 bool "Username completion"
155 default y 142 default y
156 depends on FEATURE_TAB_COMPLETION 143 depends on FEATURE_TAB_COMPLETION
157 help
158 Enable username completion.
159 144
160config FEATURE_EDITING_FANCY_PROMPT 145config FEATURE_EDITING_FANCY_PROMPT
161 bool "Fancy shell prompts" 146 bool "Fancy shell prompts"
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 6732f89a9..a31a73e90 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -777,11 +777,7 @@ static int busybox_main(char **argv)
777 int col; 777 int col;
778 unsigned output_width; 778 unsigned output_width;
779 help: 779 help:
780 output_width = 80; 780 output_width = get_terminal_width(2);
781 if (ENABLE_FEATURE_AUTOWIDTH) {
782 /* Obtain the terminal width */
783 output_width = get_terminal_width(2);
784 }
785 781
786 dup2(1, 2); 782 dup2(1, 2);
787 full_write2_str(bb_banner); /* reuse const string */ 783 full_write2_str(bb_banner); /* reuse const string */
diff --git a/libbb/crc32.c b/libbb/crc32.c
index ac9836cc9..0711ca84e 100644
--- a/libbb/crc32.c
+++ b/libbb/crc32.c
@@ -24,7 +24,7 @@ uint32_t* FAST_FUNC crc32_filltable(uint32_t *crc_table, int endian)
24{ 24{
25 uint32_t polynomial = endian ? 0x04c11db7 : 0xedb88320; 25 uint32_t polynomial = endian ? 0x04c11db7 : 0xedb88320;
26 uint32_t c; 26 uint32_t c;
27 int i, j; 27 unsigned i, j;
28 28
29 if (!crc_table) 29 if (!crc_table)
30 crc_table = xmalloc(256 * sizeof(uint32_t)); 30 crc_table = xmalloc(256 * sizeof(uint32_t));
diff --git a/libbb/dump.c b/libbb/dump.c
index 154be5d80..87c1dce13 100644
--- a/libbb/dump.c
+++ b/libbb/dump.c
@@ -14,12 +14,12 @@
14#include "libbb.h" 14#include "libbb.h"
15#include "dump.h" 15#include "dump.h"
16 16
17static const char index_str[] ALIGN1 = ".#-+ 0123456789"; 17static const char dot_flags_width_chars[] ALIGN1 = ".#-+ 0123456789";
18 18
19static const char size_conv_str[] ALIGN1 = 19static const char size_conv_str[] ALIGN1 =
20"\x1\x4\x4\x4\x4\x4\x4\x8\x8\x8\x8\010cdiouxXeEfgG"; 20"\x1\x4\x4\x4\x4\x4\x4\x8\x8\x8\x8\010cdiouxXeEfgG";
21 21
22static const char lcc[] ALIGN1 = "diouxX"; 22static const char int_convs[] ALIGN1 = "diouxX";
23 23
24 24
25typedef struct priv_dumper_t { 25typedef struct priv_dumper_t {
@@ -71,7 +71,7 @@ static NOINLINE int bb_dump_size(FS *fs)
71 * skip any special chars -- save precision in 71 * skip any special chars -- save precision in
72 * case it's a %s format. 72 * case it's a %s format.
73 */ 73 */
74 while (strchr(index_str + 1, *++fmt)) 74 while (strchr(dot_flags_width_chars + 1, *++fmt))
75 continue; 75 continue;
76 if (*fmt == '.' && isdigit(*++fmt)) { 76 if (*fmt == '.' && isdigit(*++fmt)) {
77 prec = atoi(fmt); 77 prec = atoi(fmt);
@@ -82,14 +82,15 @@ static NOINLINE int bb_dump_size(FS *fs)
82 if (!p) { 82 if (!p) {
83 if (*fmt == 's') { 83 if (*fmt == 's') {
84 bcnt += prec; 84 bcnt += prec;
85 } else if (*fmt == '_') { 85 }
86 if (*fmt == '_') {
86 ++fmt; 87 ++fmt;
87 if ((*fmt == 'c') || (*fmt == 'p') || (*fmt == 'u')) { 88 if ((*fmt == 'c') || (*fmt == 'p') || (*fmt == 'u')) {
88 bcnt += 1; 89 bcnt += 1;
89 } 90 }
90 } 91 }
91 } else { 92 } else {
92 bcnt += size_conv_str[p - (size_conv_str + 12)]; 93 bcnt += p[-12];
93 } 94 }
94 } 95 }
95 cur_size += bcnt * fu->reps; 96 cur_size += bcnt * fu->reps;
@@ -99,32 +100,30 @@ static NOINLINE int bb_dump_size(FS *fs)
99 100
100static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) 101static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs)
101{ 102{
102 enum { NOTOKAY, USEBCNT, USEPREC } sokay;
103 FU *fu; 103 FU *fu;
104 PR *pr;
105 char *p1, *p2, *p3;
106 char savech, *fmtp;
107 const char *byte_count_str;
108 int nconv, prec = 0;
109 104
110 for (fu = fs->nextfu; fu; fu = fu->nextfu) { 105 for (fu = fs->nextfu; fu; fu = fu->nextfu) {
106 PR *pr;
107 char *p1, *p2, *p3;
108 char *fmtp;
109 int nconv = 0;
111 /* 110 /*
112 * break each format unit into print units; each 111 * break each format unit into print units; each
113 * conversion character gets its own. 112 * conversion character gets its own.
114 */ 113 */
115 for (nconv = 0, fmtp = fu->fmt; *fmtp; ) { 114 for (fmtp = fu->fmt; *fmtp; ) {
116 /* NOSTRICT */ 115 unsigned len;
117 /* DBU:[dvae@cray.com] zalloc so that forward ptrs start out NULL*/ 116 const char *prec;
118 pr = xzalloc(sizeof(PR)); 117 const char *byte_count_str;
118
119 /* DBU:[dvae@cray.com] zalloc so that forward ptrs start out NULL */
120 pr = xzalloc(sizeof(*pr));
119 if (!fu->nextpr) 121 if (!fu->nextpr)
120 fu->nextpr = pr; 122 fu->nextpr = pr;
121 123
122 /* skip preceding text and up to the next % sign */ 124 /* skip preceding text and up to the next % sign */
123 for (p1 = fmtp; *p1 && *p1 != '%'; ++p1) 125 p1 = strchr(fmtp, '%');
124 continue; 126 if (!p1) { /* only text in the string */
125
126 /* only text in the string */
127 if (!*p1) {
128 pr->fmt = fmtp; 127 pr->fmt = fmtp;
129 pr->flags = F_TEXT; 128 pr->flags = F_TEXT;
130 break; 129 break;
@@ -134,22 +133,20 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs)
134 * get precision for %s -- if have a byte count, don't 133 * get precision for %s -- if have a byte count, don't
135 * need it. 134 * need it.
136 */ 135 */
136 prec = NULL;
137 if (fu->bcnt) { 137 if (fu->bcnt) {
138 sokay = USEBCNT;
139 /* skip to conversion character */ 138 /* skip to conversion character */
140 for (++p1; strchr(index_str, *p1); ++p1) 139 while (strchr(dot_flags_width_chars, *++p1))
141 continue; 140 continue;
142 } else { 141 } else {
143 /* skip any special chars, field width */ 142 /* skip any special chars, field width */
144 while (strchr(index_str + 1, *++p1)) 143 while (strchr(dot_flags_width_chars + 1, *++p1))
145 continue; 144 continue;
146 if (*p1 == '.' && isdigit(*++p1)) { 145 if (*p1 == '.' && isdigit(*++p1)) {
147 sokay = USEPREC; 146 prec = p1;
148 prec = atoi(p1);
149 while (isdigit(*++p1)) 147 while (isdigit(*++p1))
150 continue; 148 continue;
151 } else 149 }
152 sokay = NOTOKAY;
153 } 150 }
154 151
155 p2 = p1 + 1; /* set end pointer */ 152 p2 = p1 + 1; /* set end pointer */
@@ -165,74 +162,72 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs)
165 byte_count_str = "\001"; 162 byte_count_str = "\001";
166 DO_BYTE_COUNT: 163 DO_BYTE_COUNT:
167 if (fu->bcnt) { 164 if (fu->bcnt) {
168 do { 165 for (;;) {
169 if (fu->bcnt == *byte_count_str) { 166 if (fu->bcnt == *byte_count_str)
170 break; 167 break;
171 } 168 if (*++byte_count_str == 0)
172 } while (*++byte_count_str); 169 bb_error_msg_and_die("bad byte count for conversion character %s", p1);
170 }
173 } 171 }
174 /* Unlike the original, output the remainder of the format string. */ 172 /* Unlike the original, output the remainder of the format string. */
175 if (!*byte_count_str) {
176 bb_error_msg_and_die("bad byte count for conversion character %s", p1);
177 }
178 pr->bcnt = *byte_count_str; 173 pr->bcnt = *byte_count_str;
179 } else if (*p1 == 'l') { 174 } else
175 if (*p1 == 'l') { /* %ld etc */
176 const char *e;
177
180 ++p2; 178 ++p2;
181 ++p1; 179 ++p1;
182 DO_INT_CONV: 180 DO_INT_CONV:
183 { 181 e = strchr(int_convs, *p1); /* "diouxX"? */
184 const char *e; 182 if (!e)
185 e = strchr(lcc, *p1); 183 goto DO_BAD_CONV_CHAR;
186 if (!e) { 184 pr->flags = F_INT;
187 goto DO_BAD_CONV_CHAR; 185 if (e > int_convs + 1) /* not d or i? */
188 } 186 pr->flags = F_UINT;
189 pr->flags = F_INT; 187 byte_count_str = "\004\002\001";
190 if (e > lcc + 1) { 188 goto DO_BYTE_COUNT;
191 pr->flags = F_UINT; 189 } else
192 } 190 if (strchr(int_convs, *p1)) { /* %d etc */
193 byte_count_str = "\004\002\001";
194 goto DO_BYTE_COUNT;
195 }
196 /* NOTREACHED */
197 } else if (strchr(lcc, *p1)) {
198 goto DO_INT_CONV; 191 goto DO_INT_CONV;
199 } else if (strchr("eEfgG", *p1)) { 192 } else
193 if (strchr("eEfgG", *p1)) { /* floating point */
200 pr->flags = F_DBL; 194 pr->flags = F_DBL;
201 byte_count_str = "\010\004"; 195 byte_count_str = "\010\004";
202 goto DO_BYTE_COUNT; 196 goto DO_BYTE_COUNT;
203 } else if (*p1 == 's') { 197 } else
198 if (*p1 == 's') {
204 pr->flags = F_STR; 199 pr->flags = F_STR;
205 if (sokay == USEBCNT) { 200 pr->bcnt = fu->bcnt;
206 pr->bcnt = fu->bcnt; 201 if (fu->bcnt == 0) {
207 } else if (sokay == USEPREC) { 202 if (!prec)
208 pr->bcnt = prec; 203 bb_error_msg_and_die("%%s needs precision or byte count");
209 } else { /* NOTOKAY */ 204 pr->bcnt = atoi(prec);
210 bb_error_msg_and_die("%%s requires a precision or a byte count");
211 } 205 }
212 } else if (*p1 == '_') { 206 } else
213 ++p2; 207 if (*p1 == '_') {
208 p2++; /* move past a in "%_a" */
214 switch (p1[1]) { 209 switch (p1[1]) {
215 case 'A': 210 case 'A': /* %_A[dox]: print address and the end */
216 dumper->endfu = fu; 211 dumper->endfu = fu;
217 fu->flags |= F_IGNORE; 212 fu->flags |= F_IGNORE;
218 /* FALLTHROUGH */ 213 /* FALLTHROUGH */
219 case 'a': 214 case 'a': /* %_a[dox]: current address */
220 pr->flags = F_ADDRESS; 215 pr->flags = F_ADDRESS;
221 ++p2; 216 p2++; /* move past x in "%_ax" */
222 if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) { 217 if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) {
223 goto DO_BAD_CONV_CHAR; 218 goto DO_BAD_CONV_CHAR;
224 } 219 }
225 *p1 = p1[2]; 220 *p1 = p1[2];
226 break; 221 break;
227 case 'c': 222 case 'c': /* %_c: chars, \ooo, \n \r \t etc */
228 pr->flags = F_C; 223 pr->flags = F_C;
229 /* *p1 = 'c'; set in conv_c */ 224 /* *p1 = 'c'; set in conv_c */
230 goto DO_BYTE_COUNT_1; 225 goto DO_BYTE_COUNT_1;
231 case 'p': 226 case 'p': /* %_p: chars, dots for nonprintable */
232 pr->flags = F_P; 227 pr->flags = F_P;
233 *p1 = 'c'; 228 *p1 = 'c';
234 goto DO_BYTE_COUNT_1; 229 goto DO_BYTE_COUNT_1;
235 case 'u': 230 case 'u': /* %_p: chars, 'nul', 'esc' etc for nonprintable */
236 pr->flags = F_U; 231 pr->flags = F_U;
237 /* *p1 = 'c'; set in conv_u */ 232 /* *p1 = 'c'; set in conv_u */
238 goto DO_BYTE_COUNT_1; 233 goto DO_BYTE_COUNT_1;
@@ -248,13 +243,8 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs)
248 * copy to PR format string, set conversion character 243 * copy to PR format string, set conversion character
249 * pointer, update original. 244 * pointer, update original.
250 */ 245 */
251 savech = *p2; 246 len = (p1 - fmtp) + 1;
252 p1[1] = '\0'; 247 pr->fmt = xstrndup(fmtp, len);
253 pr->fmt = xstrdup(fmtp);
254 *p2 = savech;
255 //Too early! xrealloc can move pr->fmt!
256 //pr->cchar = pr->fmt + (p1 - fmtp);
257
258 /* DBU:[dave@cray.com] w/o this, trailing fmt text, space is lost. 248 /* DBU:[dave@cray.com] w/o this, trailing fmt text, space is lost.
259 * Skip subsequent text and up to the next % sign and tack the 249 * Skip subsequent text and up to the next % sign and tack the
260 * additional text onto fmt: eg. if fmt is "%x is a HEX number", 250 * additional text onto fmt: eg. if fmt is "%x is a HEX number",
@@ -262,16 +252,17 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs)
262 */ 252 */
263 for (p3 = p2; *p3 && *p3 != '%'; p3++) 253 for (p3 = p2; *p3 && *p3 != '%'; p3++)
264 continue; 254 continue;
265 if (p3 > p2) { 255 if ((p3 - p2) != 0) {
266 savech = *p3; 256 char *d;
267 *p3 = '\0'; 257 pr->fmt = d = xrealloc(pr->fmt, len + (p3 - p2) + 1);
268 pr->fmt = xrealloc(pr->fmt, strlen(pr->fmt) + (p3-p2) + 1); 258 d += len;
269 strcat(pr->fmt, p2); 259 do {
270 *p3 = savech; 260 *d++ = *p2++;
271 p2 = p3; 261 } while (p2 != p3);
262 *d = '\0';
263 /* now p2 = p3 */
272 } 264 }
273 265 pr->cchar = pr->fmt + len - 1; /* must be after realloc! */
274 pr->cchar = pr->fmt + (p1 - fmtp);
275 fmtp = p2; 266 fmtp = p2;
276 267
277 /* only one conversion character if byte count */ 268 /* only one conversion character if byte count */
@@ -283,7 +274,7 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs)
283 * if format unit byte count not specified, figure it out 274 * if format unit byte count not specified, figure it out
284 * so can adjust rep count later. 275 * so can adjust rep count later.
285 */ 276 */
286 if (!fu->bcnt) 277 if (fu->bcnt == 0)
287 for (pr = fu->nextpr; pr; pr = pr->nextpr) 278 for (pr = fu->nextpr; pr; pr = pr->nextpr)
288 fu->bcnt += pr->bcnt; 279 fu->bcnt += pr->bcnt;
289 } 280 }
@@ -305,16 +296,18 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs)
305 fu->reps += (dumper->blocksize - fs->bcnt) / fu->bcnt; 296 fu->reps += (dumper->blocksize - fs->bcnt) / fu->bcnt;
306 } 297 }
307 if (fu->reps > 1 && fu->nextpr) { 298 if (fu->reps > 1 && fu->nextpr) {
299 PR *pr;
300 char *p1, *p2;
301
308 for (pr = fu->nextpr;; pr = pr->nextpr) 302 for (pr = fu->nextpr;; pr = pr->nextpr)
309 if (!pr->nextpr) 303 if (!pr->nextpr)
310 break; 304 break;
311 for (p1 = pr->fmt, p2 = NULL; *p1; ++p1) 305 p2 = NULL;
306 for (p1 = pr->fmt; *p1; ++p1)
312 p2 = isspace(*p1) ? p1 : NULL; 307 p2 = isspace(*p1) ? p1 : NULL;
313 if (p2) 308 if (p2)
314 pr->nospace = p2; 309 pr->nospace = p2;
315 } 310 }
316 if (!fu->nextfu)
317 break;
318 } 311 }
319} 312}
320 313
@@ -358,6 +351,7 @@ static NOINLINE int next(priv_dumper_t *dumper)
358 if (dumper->next__done) 351 if (dumper->next__done)
359 return 0; /* no next file */ 352 return 0; /* no next file */
360 dumper->next__done = 1; 353 dumper->next__done = 1;
354//why stat of stdin is specially prohibited?
361 statok = 0; 355 statok = 0;
362 } 356 }
363 if (dumper->pub.dump_skip) 357 if (dumper->pub.dump_skip)
@@ -762,6 +756,11 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt)
762 if (!isspace(*p)) { 756 if (!isspace(*p)) {
763 bb_error_msg_and_die("bad format {%s}", fmt); 757 bb_error_msg_and_die("bad format {%s}", fmt);
764 } 758 }
759// Above check prohibits formats such as '/1"%02x"' - it requires space after 1.
760// Other than this, formats can be pretty much jammed together:
761// "%07_ax:"8/2 "%04x|""\n"
762// but this space is required. The check *can* be removed, but
763// keeping it to stay compat with util-linux hexdump.
765 tfu->bcnt = atoi(savep); 764 tfu->bcnt = atoi(savep);
766 /* skip trailing white space */ 765 /* skip trailing white space */
767 p = skip_whitespace(p + 1); 766 p = skip_whitespace(p + 1);
diff --git a/libbb/getopt32.c b/libbb/getopt32.c
index ed9352191..03fca3493 100644
--- a/libbb/getopt32.c
+++ b/libbb/getopt32.c
@@ -404,7 +404,7 @@ getopt32(char **argv, const char *applet_opts, ...)
404 if (c >= 32) 404 if (c >= 32)
405 break; 405 break;
406 on_off->opt_char = *s; 406 on_off->opt_char = *s;
407 on_off->switch_on = (1 << c); 407 on_off->switch_on = (1U << c);
408 if (*++s == ':') { 408 if (*++s == ':') {
409 on_off->optarg = va_arg(p, void **); 409 on_off->optarg = va_arg(p, void **);
410 if (s[1] == '+' || s[1] == '*') { 410 if (s[1] == '+' || s[1] == '*') {
@@ -454,7 +454,7 @@ getopt32(char **argv, const char *applet_opts, ...)
454 if (c >= 32) 454 if (c >= 32)
455 break; 455 break;
456 on_off->opt_char = l_o->val; 456 on_off->opt_char = l_o->val;
457 on_off->switch_on = (1 << c); 457 on_off->switch_on = (1U << c);
458 if (l_o->has_arg != no_argument) 458 if (l_o->has_arg != no_argument)
459 on_off->optarg = va_arg(p, void **); 459 on_off->optarg = va_arg(p, void **);
460 c++; 460 c++;
diff --git a/libbb/hash_md5_sha.c b/libbb/hash_md5_sha.c
index 7e7d8da2f..2a7247430 100644
--- a/libbb/hash_md5_sha.c
+++ b/libbb/hash_md5_sha.c
@@ -9,6 +9,8 @@
9 9
10#include "libbb.h" 10#include "libbb.h"
11 11
12#define NEED_SHA512 (ENABLE_SHA512SUM || ENABLE_USE_BB_CRYPT_SHA)
13
12/* gcc 4.2.1 optimizes rotr64 better with inline than with macro 14/* gcc 4.2.1 optimizes rotr64 better with inline than with macro
13 * (for rotX32, there is no difference). Why? My guess is that 15 * (for rotX32, there is no difference). Why? My guess is that
14 * macro requires clever common subexpression elimination heuristics 16 * macro requires clever common subexpression elimination heuristics
@@ -456,7 +458,7 @@ void FAST_FUNC md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len)
456 * endian byte order, so that a byte-wise output yields to the wanted 458 * endian byte order, so that a byte-wise output yields to the wanted
457 * ASCII representation of the message digest. 459 * ASCII representation of the message digest.
458 */ 460 */
459void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) 461unsigned FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf)
460{ 462{
461 /* MD5 stores total in LE, need to swap on BE arches: */ 463 /* MD5 stores total in LE, need to swap on BE arches: */
462 common64_end(ctx, /*swap_needed:*/ BB_BIG_ENDIAN); 464 common64_end(ctx, /*swap_needed:*/ BB_BIG_ENDIAN);
@@ -470,6 +472,7 @@ void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf)
470 } 472 }
471 473
472 memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4); 474 memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4);
475 return sizeof(ctx->hash[0]) * 4;
473} 476}
474 477
475 478
@@ -564,48 +567,59 @@ static void FAST_FUNC sha1_process_block64(sha1_ctx_t *ctx)
564 * are the most significant half of first 64 elements 567 * are the most significant half of first 64 elements
565 * of the same array. 568 * of the same array.
566 */ 569 */
567static const uint64_t sha_K[80] = { 570#undef K
568 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 571#if NEED_SHA512
569 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, 572typedef uint64_t sha_K_int;
570 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 573# define K(v) v
571 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, 574#else
572 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 575typedef uint32_t sha_K_int;
573 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, 576# define K(v) (uint32_t)(v >> 32)
574 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 577#endif
575 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, 578static const sha_K_int sha_K[] = {
576 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 579 K(0x428a2f98d728ae22ULL), K(0x7137449123ef65cdULL),
577 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, 580 K(0xb5c0fbcfec4d3b2fULL), K(0xe9b5dba58189dbbcULL),
578 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 581 K(0x3956c25bf348b538ULL), K(0x59f111f1b605d019ULL),
579 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, 582 K(0x923f82a4af194f9bULL), K(0xab1c5ed5da6d8118ULL),
580 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 583 K(0xd807aa98a3030242ULL), K(0x12835b0145706fbeULL),
581 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, 584 K(0x243185be4ee4b28cULL), K(0x550c7dc3d5ffb4e2ULL),
582 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 585 K(0x72be5d74f27b896fULL), K(0x80deb1fe3b1696b1ULL),
583 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, 586 K(0x9bdc06a725c71235ULL), K(0xc19bf174cf692694ULL),
584 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 587 K(0xe49b69c19ef14ad2ULL), K(0xefbe4786384f25e3ULL),
585 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, 588 K(0x0fc19dc68b8cd5b5ULL), K(0x240ca1cc77ac9c65ULL),
586 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 589 K(0x2de92c6f592b0275ULL), K(0x4a7484aa6ea6e483ULL),
587 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, 590 K(0x5cb0a9dcbd41fbd4ULL), K(0x76f988da831153b5ULL),
588 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 591 K(0x983e5152ee66dfabULL), K(0xa831c66d2db43210ULL),
589 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, 592 K(0xb00327c898fb213fULL), K(0xbf597fc7beef0ee4ULL),
590 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 593 K(0xc6e00bf33da88fc2ULL), K(0xd5a79147930aa725ULL),
591 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, 594 K(0x06ca6351e003826fULL), K(0x142929670a0e6e70ULL),
592 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 595 K(0x27b70a8546d22ffcULL), K(0x2e1b21385c26c926ULL),
593 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, 596 K(0x4d2c6dfc5ac42aedULL), K(0x53380d139d95b3dfULL),
594 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 597 K(0x650a73548baf63deULL), K(0x766a0abb3c77b2a8ULL),
595 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, 598 K(0x81c2c92e47edaee6ULL), K(0x92722c851482353bULL),
596 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 599 K(0xa2bfe8a14cf10364ULL), K(0xa81a664bbc423001ULL),
597 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, 600 K(0xc24b8b70d0f89791ULL), K(0xc76c51a30654be30ULL),
598 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 601 K(0xd192e819d6ef5218ULL), K(0xd69906245565a910ULL),
599 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, 602 K(0xf40e35855771202aULL), K(0x106aa07032bbd1b8ULL),
600 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, /* [64]+ are used for sha512 only */ 603 K(0x19a4c116b8d2d0c8ULL), K(0x1e376c085141ab53ULL),
601 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, 604 K(0x2748774cdf8eeb99ULL), K(0x34b0bcb5e19b48a8ULL),
602 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 605 K(0x391c0cb3c5c95a63ULL), K(0x4ed8aa4ae3418acbULL),
603 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, 606 K(0x5b9cca4f7763e373ULL), K(0x682e6ff3d6b2b8a3ULL),
604 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 607 K(0x748f82ee5defb2fcULL), K(0x78a5636f43172f60ULL),
605 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, 608 K(0x84c87814a1f0ab72ULL), K(0x8cc702081a6439ecULL),
606 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 609 K(0x90befffa23631e28ULL), K(0xa4506cebde82bde9ULL),
607 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL 610 K(0xbef9a3f7b2c67915ULL), K(0xc67178f2e372532bULL),
611#if NEED_SHA512 /* [64]+ are used for sha512 only */
612 K(0xca273eceea26619cULL), K(0xd186b8c721c0c207ULL),
613 K(0xeada7dd6cde0eb1eULL), K(0xf57d4f7fee6ed178ULL),
614 K(0x06f067aa72176fbaULL), K(0x0a637dc5a2c898a6ULL),
615 K(0x113f9804bef90daeULL), K(0x1b710b35131c471bULL),
616 K(0x28db77f523047d84ULL), K(0x32caab7b40c72493ULL),
617 K(0x3c9ebe0a15c9bebcULL), K(0x431d67c49c100d4cULL),
618 K(0x4cc5d4becb3e42b6ULL), K(0x597f299cfc657e2aULL),
619 K(0x5fcb6fab3ad6faecULL), K(0x6c44198c4a475817ULL),
620#endif
608}; 621};
622#undef K
609 623
610#undef Ch 624#undef Ch
611#undef Maj 625#undef Maj
@@ -649,7 +663,7 @@ static void FAST_FUNC sha256_process_block64(sha256_ctx_t *ctx)
649 * (I hope compiler is clever enough to just fetch 663 * (I hope compiler is clever enough to just fetch
650 * upper half) 664 * upper half)
651 */ 665 */
652 uint32_t K_t = sha_K[t] >> 32; 666 uint32_t K_t = NEED_SHA512 ? (sha_K[t] >> 32) : sha_K[t];
653 uint32_t T1 = h + S1(e) + Ch(e, f, g) + K_t + W[t]; 667 uint32_t T1 = h + S1(e) + Ch(e, f, g) + K_t + W[t];
654 uint32_t T2 = S0(a) + Maj(a, b, c); 668 uint32_t T2 = S0(a) + Maj(a, b, c);
655 h = g; 669 h = g;
@@ -679,6 +693,7 @@ static void FAST_FUNC sha256_process_block64(sha256_ctx_t *ctx)
679 ctx->hash[7] += h; 693 ctx->hash[7] += h;
680} 694}
681 695
696#if NEED_SHA512
682static void FAST_FUNC sha512_process_block128(sha512_ctx_t *ctx) 697static void FAST_FUNC sha512_process_block128(sha512_ctx_t *ctx)
683{ 698{
684 unsigned t; 699 unsigned t;
@@ -740,7 +755,7 @@ static void FAST_FUNC sha512_process_block128(sha512_ctx_t *ctx)
740 ctx->hash[6] += g; 755 ctx->hash[6] += g;
741 ctx->hash[7] += h; 756 ctx->hash[7] += h;
742} 757}
743 758#endif /* NEED_SHA512 */
744 759
745void FAST_FUNC sha1_begin(sha1_ctx_t *ctx) 760void FAST_FUNC sha1_begin(sha1_ctx_t *ctx)
746{ 761{
@@ -765,6 +780,7 @@ static const uint32_t init256[] = {
765 0x1f83d9ab, 780 0x1f83d9ab,
766 0x5be0cd19, 781 0x5be0cd19,
767}; 782};
783#if NEED_SHA512
768static const uint32_t init512_lo[] = { 784static const uint32_t init512_lo[] = {
769 0, 785 0,
770 0, 786 0,
@@ -777,6 +793,7 @@ static const uint32_t init512_lo[] = {
777 0xfb41bd6b, 793 0xfb41bd6b,
778 0x137e2179, 794 0x137e2179,
779}; 795};
796#endif /* NEED_SHA512 */
780 797
781/* Initialize structure containing state of computation. 798/* Initialize structure containing state of computation.
782 (FIPS 180-2:5.3.2) */ 799 (FIPS 180-2:5.3.2) */
@@ -787,6 +804,7 @@ void FAST_FUNC sha256_begin(sha256_ctx_t *ctx)
787 ctx->process_block = sha256_process_block64; 804 ctx->process_block = sha256_process_block64;
788} 805}
789 806
807#if NEED_SHA512
790/* Initialize structure containing state of computation. 808/* Initialize structure containing state of computation.
791 (FIPS 180-2:5.3.3) */ 809 (FIPS 180-2:5.3.3) */
792void FAST_FUNC sha512_begin(sha512_ctx_t *ctx) 810void FAST_FUNC sha512_begin(sha512_ctx_t *ctx)
@@ -810,7 +828,7 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len)
810 ctx->total64[0] += len; 828 ctx->total64[0] += len;
811 if (ctx->total64[0] < len) 829 if (ctx->total64[0] < len)
812 ctx->total64[1]++; 830 ctx->total64[1]++;
813#if 0 831# if 0
814 remaining = 128 - bufpos; 832 remaining = 128 - bufpos;
815 833
816 /* Hash whole blocks */ 834 /* Hash whole blocks */
@@ -825,7 +843,7 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len)
825 843
826 /* Save last, partial blosk */ 844 /* Save last, partial blosk */
827 memcpy(ctx->wbuffer + bufpos, buffer, len); 845 memcpy(ctx->wbuffer + bufpos, buffer, len);
828#else 846# else
829 while (1) { 847 while (1) {
830 remaining = 128 - bufpos; 848 remaining = 128 - bufpos;
831 if (remaining > len) 849 if (remaining > len)
@@ -843,11 +861,12 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len)
843 sha512_process_block128(ctx); 861 sha512_process_block128(ctx);
844 /*bufpos = 0; - already is */ 862 /*bufpos = 0; - already is */
845 } 863 }
846#endif 864# endif
847} 865}
866#endif /* NEED_SHA512 */
848 867
849/* Used also for sha256 */ 868/* Used also for sha256 */
850void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf) 869unsigned FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf)
851{ 870{
852 unsigned hash_size; 871 unsigned hash_size;
853 872
@@ -861,10 +880,13 @@ void FAST_FUNC sha1_end(sha1_ctx_t *ctx, void *resbuf)
861 for (i = 0; i < hash_size; ++i) 880 for (i = 0; i < hash_size; ++i)
862 ctx->hash[i] = SWAP_BE32(ctx->hash[i]); 881 ctx->hash[i] = SWAP_BE32(ctx->hash[i]);
863 } 882 }
864 memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * hash_size); 883 hash_size *= sizeof(ctx->hash[0]);
884 memcpy(resbuf, ctx->hash, hash_size);
885 return hash_size;
865} 886}
866 887
867void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) 888#if NEED_SHA512
889unsigned FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf)
868{ 890{
869 unsigned bufpos = ctx->total64[0] & 127; 891 unsigned bufpos = ctx->total64[0] & 127;
870 892
@@ -896,7 +918,9 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf)
896 ctx->hash[i] = SWAP_BE64(ctx->hash[i]); 918 ctx->hash[i] = SWAP_BE64(ctx->hash[i]);
897 } 919 }
898 memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); 920 memcpy(resbuf, ctx->hash, sizeof(ctx->hash));
921 return sizeof(ctx->hash);
899} 922}
923#endif /* NEED_SHA512 */
900 924
901 925
902/* 926/*
@@ -1430,7 +1454,7 @@ void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len)
1430#endif 1454#endif
1431} 1455}
1432 1456
1433void FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) 1457unsigned FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf)
1434{ 1458{
1435 /* Padding */ 1459 /* Padding */
1436 uint8_t *buf = (uint8_t*)ctx->state; 1460 uint8_t *buf = (uint8_t*)ctx->state;
@@ -1455,4 +1479,5 @@ void FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf)
1455 1479
1456 /* Output */ 1480 /* Output */
1457 memcpy(resbuf, ctx->state, 64); 1481 memcpy(resbuf, ctx->state, 64);
1482 return 64;
1458} 1483}
diff --git a/libbb/hash_md5prime.c b/libbb/hash_md5prime.c
index e089a15f5..4b58d37ff 100644
--- a/libbb/hash_md5prime.c
+++ b/libbb/hash_md5prime.c
@@ -437,7 +437,7 @@ void FAST_FUNC md5_hash(const void *buffer, size_t inputLen, md5_ctx_t *context)
437 * MD5 finalization. Ends an MD5 message-digest operation, 437 * MD5 finalization. Ends an MD5 message-digest operation,
438 * writing the message digest. 438 * writing the message digest.
439 */ 439 */
440void FAST_FUNC md5_end(void *digest, md5_ctx_t *context) 440unsigned FAST_FUNC md5_end(void *digest, md5_ctx_t *context)
441{ 441{
442 unsigned idx, padLen; 442 unsigned idx, padLen;
443 unsigned char bits[8]; 443 unsigned char bits[8];
@@ -457,4 +457,5 @@ void FAST_FUNC md5_end(void *digest, md5_ctx_t *context)
457 457
458 /* Store state in digest */ 458 /* Store state in digest */
459 memcpy32_cpu2le(digest, context->state, 16); 459 memcpy32_cpu2le(digest, context->state, 16);
460 return 16;
460} 461}
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 5d9080131..670a1b194 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -2402,7 +2402,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
2402 /* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */ 2402 /* ~ECHO, ~ECHONL: turn off echoing, including newline echoing */
2403 /* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */ 2403 /* ~ISIG: turn off INTR (ctrl-C), QUIT, SUSP */
2404 new_settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG); 2404 new_settings.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG);
2405 /* reads would block only if < 1 char is available */ 2405 /* reads will block only if < 1 char is available */
2406 new_settings.c_cc[VMIN] = 1; 2406 new_settings.c_cc[VMIN] = 1;
2407 /* no timeout (reads block forever) */ 2407 /* no timeout (reads block forever) */
2408 new_settings.c_cc[VTIME] = 0; 2408 new_settings.c_cc[VTIME] = 0;
diff --git a/libbb/match_fstype.c b/libbb/match_fstype.c
index b066b4211..6046bc6db 100644
--- a/libbb/match_fstype.c
+++ b/libbb/match_fstype.c
@@ -12,34 +12,30 @@
12 12
13#include "libbb.h" 13#include "libbb.h"
14 14
15#ifdef HAVE_MNTENT_H 15int FAST_FUNC fstype_matches(const char *fstype, const char *comma_list)
16
17int FAST_FUNC match_fstype(const struct mntent *mt, const char *t_fstype)
18{ 16{
19 int match = 1; 17 int match = 1;
20 18
21 if (!t_fstype) 19 if (!comma_list)
22 return match; 20 return match;
23 21
24 if (t_fstype[0] == 'n' && t_fstype[1] == 'o') { 22 if (comma_list[0] == 'n' && comma_list[1] == 'o') {
25 match--; 23 match--;
26 t_fstype += 2; 24 comma_list += 2;
27 } 25 }
28 26
29 while (1) { 27 while (1) {
30 char *after_mnt_type = is_prefixed_with(t_fstype, mt->mnt_type); 28 char *after_mnt_type = is_prefixed_with(comma_list, fstype);
31 if (after_mnt_type 29 if (after_mnt_type
32 && (*after_mnt_type == '\0' || *after_mnt_type == ',') 30 && (*after_mnt_type == '\0' || *after_mnt_type == ',')
33 ) { 31 ) {
34 return match; 32 return match;
35 } 33 }
36 t_fstype = strchr(t_fstype, ','); 34 comma_list = strchr(comma_list, ',');
37 if (!t_fstype) 35 if (!comma_list)
38 break; 36 break;
39 t_fstype++; 37 comma_list++;
40 } 38 }
41 39
42 return !match; 40 return !match;
43} 41}
44
45#endif /* HAVE_MNTENT_H */
diff --git a/libbb/procps.c b/libbb/procps.c
index 452b50b82..6f971a116 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -371,6 +371,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
371 | PSSCAN_TTY | PSSCAN_NICE 371 | PSSCAN_TTY | PSSCAN_NICE
372 | PSSCAN_CPU) 372 | PSSCAN_CPU)
373 ) { 373 ) {
374 int s_idx;
374 char *cp, *comm1; 375 char *cp, *comm1;
375 int tty; 376 int tty;
376#if !ENABLE_FEATURE_FAST_TOP 377#if !ENABLE_FEATURE_FAST_TOP
@@ -469,17 +470,20 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags)
469#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS 470#if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS
470 sp->niceness = tasknice; 471 sp->niceness = tasknice;
471#endif 472#endif
472 473 sp->state[1] = ' ';
473 if (sp->vsz == 0 && sp->state[0] != 'Z') 474 sp->state[2] = ' ';
475 s_idx = 1;
476 if (sp->vsz == 0 && sp->state[0] != 'Z') {
477 /* not sure what the purpose of this flag */
474 sp->state[1] = 'W'; 478 sp->state[1] = 'W';
475 else 479 s_idx = 2;
476 sp->state[1] = ' '; 480 }
477 if (tasknice < 0) 481 if (tasknice != 0) {
478 sp->state[2] = '<'; 482 if (tasknice < 0)
479 else if (tasknice) /* > 0 */ 483 sp->state[s_idx] = '<';
480 sp->state[2] = 'N'; 484 else /* > 0 */
481 else 485 sp->state[s_idx] = 'N';
482 sp->state[2] = ' '; 486 }
483 } 487 }
484 488
485#if ENABLE_FEATURE_TOPMEM 489#if ENABLE_FEATURE_TOPMEM
diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c
index 4cdc2de76..fe06a8fe6 100644
--- a/libbb/pw_encrypt.c
+++ b/libbb/pw_encrypt.c
@@ -30,7 +30,7 @@ static int i64c(int i)
30int FAST_FUNC crypt_make_salt(char *p, int cnt /*, int x */) 30int FAST_FUNC crypt_make_salt(char *p, int cnt /*, int x */)
31{ 31{
32 /* was: x += ... */ 32 /* was: x += ... */
33 int x = getpid() + monotonic_us(); 33 unsigned x = getpid() + monotonic_us();
34 do { 34 do {
35 /* x = (x*1664525 + 1013904223) % 2^32 generator is lame 35 /* x = (x*1664525 + 1013904223) % 2^32 generator is lame
36 * (low-order bit is not "random", etc...), 36 * (low-order bit is not "random", etc...),
diff --git a/libbb/pw_encrypt_sha.c b/libbb/pw_encrypt_sha.c
index 8aeaacad6..5457d7ab6 100644
--- a/libbb/pw_encrypt_sha.c
+++ b/libbb/pw_encrypt_sha.c
@@ -18,9 +18,10 @@ static char *
18NOINLINE 18NOINLINE
19sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data) 19sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data)
20{ 20{
21#undef sha_end
21 void (*sha_begin)(void *ctx) FAST_FUNC; 22 void (*sha_begin)(void *ctx) FAST_FUNC;
22 void (*sha_hash)(void *ctx, const void *buffer, size_t len) FAST_FUNC; 23 void (*sha_hash)(void *ctx, const void *buffer, size_t len) FAST_FUNC;
23 void (*sha_end)(void *ctx, void *resbuf) FAST_FUNC; 24 unsigned (*sha_end)(void *ctx, void *resbuf) FAST_FUNC;
24 int _32or64; 25 int _32or64;
25 26
26 char *result, *resptr; 27 char *result, *resptr;
@@ -47,16 +48,17 @@ sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data)
47 unsigned cnt; 48 unsigned cnt;
48 unsigned rounds; 49 unsigned rounds;
49 char *cp; 50 char *cp;
50 char is_sha512;
51 51
52 /* Analyze salt, construct already known part of result */ 52 /* Analyze salt, construct already known part of result */
53 cnt = strlen(salt_data) + 1 + 43 + 1; 53 cnt = strlen(salt_data) + 1 + 43 + 1;
54 is_sha512 = salt_data[1]; 54 _32or64 = 32;
55 if (is_sha512 == '6') 55 if (salt_data[1] == '6') { /* sha512 */
56 _32or64 *= 2; /*64*/
56 cnt += 43; 57 cnt += 43;
58 }
57 result = resptr = xzalloc(cnt); /* will provide NUL terminator */ 59 result = resptr = xzalloc(cnt); /* will provide NUL terminator */
58 *resptr++ = '$'; 60 *resptr++ = '$';
59 *resptr++ = is_sha512; 61 *resptr++ = salt_data[1];
60 *resptr++ = '$'; 62 *resptr++ = '$';
61 rounds = ROUNDS_DEFAULT; 63 rounds = ROUNDS_DEFAULT;
62 salt_data += 3; 64 salt_data += 3;
@@ -93,12 +95,10 @@ sha_crypt(/*const*/ char *key_data, /*const*/ char *salt_data)
93 sha_begin = (void*)sha256_begin; 95 sha_begin = (void*)sha256_begin;
94 sha_hash = (void*)sha256_hash; 96 sha_hash = (void*)sha256_hash;
95 sha_end = (void*)sha256_end; 97 sha_end = (void*)sha256_end;
96 _32or64 = 32; 98 if (_32or64 != 32) {
97 if (is_sha512 == '6') {
98 sha_begin = (void*)sha512_begin; 99 sha_begin = (void*)sha512_begin;
99 sha_hash = (void*)sha512_hash; 100 sha_hash = (void*)sha512_hash;
100 sha_end = (void*)sha512_end; 101 sha_end = (void*)sha512_end;
101 _32or64 = 64;
102 } 102 }
103 103
104 /* Add KEY, SALT. */ 104 /* Add KEY, SALT. */
@@ -200,7 +200,7 @@ do { \
200 unsigned w = ((B2) << 16) | ((B1) << 8) | (B0); \ 200 unsigned w = ((B2) << 16) | ((B1) << 8) | (B0); \
201 resptr = to64(resptr, w, N); \ 201 resptr = to64(resptr, w, N); \
202} while (0) 202} while (0)
203 if (is_sha512 == '5') { 203 if (_32or64 == 32) { /* sha256 */
204 unsigned i = 0; 204 unsigned i = 0;
205 while (1) { 205 while (1) {
206 unsigned j = i + 10; 206 unsigned j = i + 10;
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c
index 766a89e5f..a6d260a40 100644
--- a/libbb/vfork_daemon_rexec.c
+++ b/libbb/vfork_daemon_rexec.c
@@ -185,26 +185,30 @@ int FAST_FUNC spawn_and_wait(char **argv)
185#if ENABLE_FEATURE_PREFER_APPLETS 185#if ENABLE_FEATURE_PREFER_APPLETS
186 int a = find_applet_by_name(argv[0]); 186 int a = find_applet_by_name(argv[0]);
187 187
188 if (a >= 0 && (APPLET_IS_NOFORK(a) 188 if (a >= 0) {
189# if BB_MMU
190 || APPLET_IS_NOEXEC(a) /* NOEXEC trick needs fork() */
191# endif
192 )) {
193# if BB_MMU
194 if (APPLET_IS_NOFORK(a)) 189 if (APPLET_IS_NOFORK(a))
195# endif
196 {
197 return run_nofork_applet(a, argv); 190 return run_nofork_applet(a, argv);
191# if BB_MMU /* NOEXEC needs fork(), thus this is done only on MMU machines: */
192# if !ENABLE_PLATFORM_MINGW32 /* and then only if not on Microsoft Windows */
193 if (APPLET_IS_NOEXEC(a)) {
194 fflush_all();
195 rc = fork();
196 if (rc) /* parent or error */
197 return wait4pid(rc);
198
199 /* child */
200 /* reset some state and run without execing */
201
202 /* msg_eol = "\n"; - no caller needs this reinited yet */
203 logmode = LOGMODE_STDIO;
204 /* die_func = NULL; - needed if the caller is a shell,
205 * init, or a NOFORK applet. But none of those call us
206 * as of yet (and that should probably always stay true).
207 */
208 /* xfunc_error_retval and applet_name are init by: */
209 run_applet_no_and_exit(a, argv);
198 } 210 }
199# if BB_MMU && !ENABLE_PLATFORM_MINGW32 211# endif
200 /* MMU only */
201 /* a->noexec is true */
202 rc = fork();
203 if (rc) /* parent or error */
204 return wait4pid(rc);
205 /* child */
206 xfunc_error_retval = EXIT_FAILURE;
207 run_applet_no_and_exit(a, argv);
208# endif 212# endif
209 } 213 }
210#endif /* FEATURE_PREFER_APPLETS */ 214#endif /* FEATURE_PREFER_APPLETS */
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index 45650edba..98d3531d6 100644
--- a/libbb/xfuncs.c
+++ b/libbb/xfuncs.c
@@ -311,6 +311,43 @@ int FAST_FUNC tcsetattr_stdin_TCSANOW(const struct termios *tp)
311 return tcsetattr(STDIN_FILENO, TCSANOW, tp); 311 return tcsetattr(STDIN_FILENO, TCSANOW, tp);
312} 312}
313 313
314int FAST_FUNC set_termios_to_raw(int fd, struct termios *oldterm, int flags)
315{
316//TODO: lineedit, microcom and less might be adapted to use this too:
317// grep for "tcsetattr"
318
319 struct termios newterm;
320
321 tcgetattr(fd, oldterm);
322 newterm = *oldterm;
323
324 /* Turn off buffered input (ICANON)
325 * Turn off echoing (ECHO)
326 * and separate echoing of newline (ECHONL, normally off anyway)
327 */
328 newterm.c_lflag &= ~(ICANON | ECHO | ECHONL);
329 if (flags & TERMIOS_CLEAR_ISIG) {
330 /* dont recognize INT/QUIT/SUSP chars */
331 newterm.c_lflag &= ~ISIG;
332 }
333 /* reads will block only if < 1 char is available */
334 newterm.c_cc[VMIN] = 1;
335 /* no timeout (reads block forever) */
336 newterm.c_cc[VTIME] = 0;
337 if (flags & TERMIOS_RAW_CRNL) {
338 /* dont convert CR to NL on input */
339 newterm.c_iflag &= ~(IXON | ICRNL);
340 /* dont convert NL to CR on output */
341 newterm.c_oflag &= ~(ONLCR);
342 }
343 if (flags & TERMIOS_RAW_INPUT) {
344 /* dont convert anything on input */
345 newterm.c_iflag &= ~(BRKINT|INLCR|ICRNL|IXON|IXOFF|IUCLC|IXANY|IMAXBEL);
346 }
347
348 return tcsetattr(fd, TCSANOW, &newterm);
349}
350
314pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options) 351pid_t FAST_FUNC safe_waitpid(pid_t pid, int *wstat, int options)
315{ 352{
316 pid_t r; 353 pid_t r;