aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
Diffstat (limited to 'libbb')
-rw-r--r--libbb/appletlib.c96
-rw-r--r--libbb/bb_askpass.c2
-rw-r--r--libbb/compare_string_array.c14
-rw-r--r--libbb/dump.c2
-rw-r--r--libbb/fgets_str.c17
-rw-r--r--libbb/lineedit.c8
-rw-r--r--libbb/login.c6
-rw-r--r--libbb/print_numbered_lines.c5
-rw-r--r--libbb/procps.c45
-rw-r--r--libbb/pw_encrypt.c4
-rw-r--r--libbb/time.c6
-rw-r--r--libbb/update_passwd.c2
-rw-r--r--libbb/xfuncs_printf.c16
13 files changed, 84 insertions, 139 deletions
diff --git a/libbb/appletlib.c b/libbb/appletlib.c
index 5f59f1273..542211255 100644
--- a/libbb/appletlib.c
+++ b/libbb/appletlib.c
@@ -176,7 +176,7 @@ void FAST_FUNC bb_show_usage(void)
int FAST_FUNC find_applet_by_name(const char *name)
{
- unsigned i, max;
+ unsigned i;
int j;
const char *p;
@@ -200,105 +200,43 @@ int FAST_FUNC find_applet_by_name(const char *name)
#endif
p = applet_names;
- i = 0;
#if KNOWN_APPNAME_OFFSETS <= 0
- max = NUM_APPLETS;
+ i = 0;
#else
- max = NUM_APPLETS * KNOWN_APPNAME_OFFSETS;
+ i = NUM_APPLETS * (KNOWN_APPNAME_OFFSETS - 1);
for (j = ARRAY_SIZE(applet_nameofs)-1; j >= 0; j--) {
const char *pp = applet_names + applet_nameofs[j];
if (strcmp(name, pp) >= 0) {
//bb_error_msg("name:'%s' >= pp:'%s'", name, pp);
p = pp;
- i = max - NUM_APPLETS;
break;
}
- max -= NUM_APPLETS;
+ i -= NUM_APPLETS;
}
- max /= (unsigned)KNOWN_APPNAME_OFFSETS;
i /= (unsigned)KNOWN_APPNAME_OFFSETS;
- //bb_error_msg("name:'%s' starting from:'%s' i:%u max:%u", name, p, i, max);
+ //bb_error_msg("name:'%s' starting from:'%s' i:%u", name, p, i);
#endif
/* Open-coded linear search without strcmp/strlen calls for speed */
-
-#if 0 /*BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN*/
- /* skip "[\0" name, it's surely not it */
- if (ENABLE_TEST && LONE_CHAR(p, '['))
- i++, p += 2;
- /* All remaining applet names in p[] are at least 2 chars long */
- /* name[] is also at least 2 chars long */
-
- n32 = (name[0] << 0) | (name[1] << 8) | (name[2] << 16);
- while (i < max) {
- uint32_t p32;
- char ch;
-
- /* Quickly check match of the first 3 bytes */
- move_from_unaligned32(p32, p);
- p += 3;
- if ((p32 & 0x00ffffff) != n32) {
- /* Most likely case: 3 first bytes do not match */
- i++;
- if ((p32 & 0x00ff0000) == '\0')
- continue; // p[2] was NUL
- p++;
- if ((p32 & 0xff000000) == '\0')
- continue; // p[3] was NUL
- /* p[0..3] aren't matching and none is NUL, check the rest */
- while (*p++ != '\0')
- continue;
- continue;
- }
-
- /* Unlikely branch: first 3 bytes ([0..2]) match */
- if ((p32 & 0x00ff0000) == '\0') {
- /* name is 2-byte long, it is full match */
- //bb_error_msg("found:'%s' i:%u", name, i);
- return i;
- }
- /* Check remaining bytes [3..NUL] */
- ch = (p32 >> 24);
- j = 3;
- while (ch == name[j]) {
- if (ch == '\0') {
- //bb_error_msg("found:'%s' i:%u", name, i);
- return i;
- }
- ch = *++p;
- j++;
- }
- /* Not a match. Skip it, including NUL */
- while (ch != '\0')
- ch = *++p;
- p++;
- i++;
- }
- return -1;
-#else
- while (i < max) {
- char ch;
- j = 0;
- /* Do we see "name\0" in applet_names[p] position? */
- while ((ch = *p) == name[j]) {
- if (ch == '\0') {
+ while (*p) {
+ /* Do we see "name\0" at current position in applet_names? */
+ for (j = 0; *p == name[j]; ++j) {
+ if (*p++ == '\0') {
//bb_error_msg("found:'%s' i:%u", name, i);
return i; /* yes */
}
- p++;
- j++;
}
- /* No.
- * p => 1st non-matching char in applet_names[],
- * skip to and including NUL.
- */
- while (ch != '\0')
- ch = *++p;
- p++;
+ /* No. Have we gone too far, alphabetically? */
+ if (*p > name[j]) {
+ //bb_error_msg("break:'%s' i:%u", name, i);
+ break;
+ }
+ /* No. Move to the start of the next applet name. */
+ while (*p++ != '\0')
+ continue;
i++;
}
return -1;
-#endif
}
diff --git a/libbb/bb_askpass.c b/libbb/bb_askpass.c
index 2dcead35a..66d6a479e 100644
--- a/libbb/bb_askpass.c
+++ b/libbb/bb_askpass.c
@@ -25,7 +25,7 @@ char* FAST_FUNC bb_ask_noecho(int fd, int timeout, const char *prompt)
/* Was buggy: was printing prompt *before* flushing input,
* which was upsetting "expect" based scripts of some users.
*/
- fputs(prompt, stdout);
+ fputs_stdout(prompt);
fflush_all();
tcgetattr(fd, &oldtio);
diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c
index a06e57d3d..d8cd033a3 100644
--- a/libbb/compare_string_array.c
+++ b/libbb/compare_string_array.c
@@ -63,13 +63,19 @@ int FAST_FUNC index_in_str_array(const char *const string_array[], const char *k
int FAST_FUNC index_in_strings(const char *strings, const char *key)
{
- int idx = 0;
+ int j, idx = 0;
while (*strings) {
- if (strcmp(strings, key) == 0) {
- return idx;
+ /* Do we see "key\0" at current position in strings? */
+ for (j = 0; *strings == key[j]; ++j) {
+ if (*strings++ == '\0') {
+ //bb_error_msg("found:'%s' i:%u", key, idx);
+ return idx; /* yes */
+ }
}
- strings += strlen(strings) + 1; /* skip NUL */
+ /* No. Move to the start of the next string. */
+ while (*strings++ != '\0')
+ continue;
idx++;
}
return -1;
diff --git a/libbb/dump.c b/libbb/dump.c
index 1ba1132b3..fb7849e7d 100644
--- a/libbb/dump.c
+++ b/libbb/dump.c
@@ -560,7 +560,7 @@ static void display(priv_dumper_t* dumper)
) {
if (dumper->pub.eofstring) {
/* xxd support: requested to not pad incomplete blocks */
- fputs(dumper->pub.eofstring, stdout);
+ fputs_stdout(dumper->pub.eofstring);
return;
}
if (!(pr->flags & (F_TEXT | F_BPAD)))
diff --git a/libbb/fgets_str.c b/libbb/fgets_str.c
index 1a7f2e9e0..c884ef8af 100644
--- a/libbb/fgets_str.c
+++ b/libbb/fgets_str.c
@@ -17,7 +17,7 @@ static char *xmalloc_fgets_internal(FILE *file, const char *terminating_string,
int linebufsz = 0;
int idx = 0;
int ch;
- size_t maxsz = *maxsz_p;
+ size_t maxsz = maxsz_p ? *maxsz_p : INT_MAX - 4095;
while (1) {
ch = fgetc(file);
@@ -53,7 +53,8 @@ static char *xmalloc_fgets_internal(FILE *file, const char *terminating_string,
/* Grow/shrink *first*, then store NUL */
linebuf = xrealloc(linebuf, idx + 1);
linebuf[idx] = '\0';
- *maxsz_p = idx;
+ if (maxsz_p)
+ *maxsz_p = idx;
return linebuf;
}
@@ -63,23 +64,15 @@ static char *xmalloc_fgets_internal(FILE *file, const char *terminating_string,
* Return NULL if EOF is reached immediately. */
char* FAST_FUNC xmalloc_fgets_str(FILE *file, const char *terminating_string)
{
- size_t maxsz = INT_MAX - 4095;
- return xmalloc_fgets_internal(file, terminating_string, 0, &maxsz);
+ return xmalloc_fgets_internal(file, terminating_string, 0, NULL);
}
char* FAST_FUNC xmalloc_fgets_str_len(FILE *file, const char *terminating_string, size_t *maxsz_p)
{
- size_t maxsz;
-
- if (!maxsz_p) {
- maxsz = INT_MAX - 4095;
- maxsz_p = &maxsz;
- }
return xmalloc_fgets_internal(file, terminating_string, 0, maxsz_p);
}
char* FAST_FUNC xmalloc_fgetline_str(FILE *file, const char *terminating_string)
{
- size_t maxsz = INT_MAX - 4095;
- return xmalloc_fgets_internal(file, terminating_string, 1, &maxsz);
+ return xmalloc_fgets_internal(file, terminating_string, 1, NULL);
}
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index 75de88e77..367396b91 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -312,7 +312,7 @@ static void BB_PUTCHAR(wchar_t c)
ssize_t len = wcrtomb(buf, c, &mbst);
if (len > 0) {
buf[len] = '\0';
- fputs(buf, stdout);
+ fputs_stdout(buf);
}
} else {
/* In this case, c is always one byte */
@@ -460,7 +460,7 @@ static void beep(void)
*/
static void put_prompt_custom(bool is_full)
{
- fputs((is_full ? cmdedit_prompt : prompt_last_line), stdout);
+ fputs_stdout((is_full ? cmdedit_prompt : prompt_last_line));
cursor = 0;
cmdedit_y = cmdedit_prmt_len / cmdedit_termw; /* new quasireal y */
cmdedit_x = cmdedit_prmt_len % cmdedit_termw;
@@ -1851,7 +1851,7 @@ static void ask_terminal(void)
pfd.events = POLLIN;
if (safe_poll(&pfd, 1, 0) == 0) {
S.sent_ESC_br6n = 1;
- fputs(ESC"[6n", stdout);
+ fputs_stdout(ESC"[6n");
fflush_all(); /* make terminal see it ASAP! */
}
}
@@ -2957,7 +2957,7 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman
#undef read_line_input
int FAST_FUNC read_line_input(const char* prompt, char* command, int maxsize)
{
- fputs(prompt, stdout);
+ fputs_stdout(prompt);
fflush_all();
if (!fgets(command, maxsize, stdin))
return -1;
diff --git a/libbb/login.c b/libbb/login.c
index 7f593d80d..af860c277 100644
--- a/libbb/login.c
+++ b/libbb/login.c
@@ -120,7 +120,7 @@ void FAST_FUNC print_login_issue(const char *issue_file, const char *tty)
buf[0] = c;
}
}
- fputs(outbuf, stdout);
+ fputs_stdout(outbuf);
}
fclose(fp);
fflush_all();
@@ -130,8 +130,8 @@ void FAST_FUNC print_login_prompt(void)
{
char *hostname = safe_gethostname();
- fputs(hostname, stdout);
- fputs(LOGIN, stdout);
+ fputs_stdout(hostname);
+ fputs_stdout(LOGIN);
fflush_all();
free(hostname);
}
diff --git a/libbb/print_numbered_lines.c b/libbb/print_numbered_lines.c
index d6459d7c3..b64f85597 100644
--- a/libbb/print_numbered_lines.c
+++ b/libbb/print_numbered_lines.c
@@ -22,10 +22,11 @@ int FAST_FUNC print_numbered_lines(struct number_state *ns, const char *filename
if (ns->all
|| (ns->nonempty && line[0])
) {
- printf("%*u%s%s\n", ns->width, N, ns->sep, line);
+ printf("%*u%s", ns->width, N, ns->sep);
N += ns->inc;
} else if (ns->empty_str)
- fputs(ns->empty_str, stdout);
+ fputs_stdout(ns->empty_str);
+ puts(line);
free(line);
}
ns->start = N;
diff --git a/libbb/procps.c b/libbb/procps.c
index 75969947b..f56b71b21 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -21,40 +21,29 @@ typedef struct cache_t {
int size;
} cache_t;
-static cache_t username, groupname;
+static cache_t *cache_user_group;
-static void clear_cache(cache_t *cp)
-{
- free(cp->cache);
- cp->cache = NULL;
- cp->size = 0;
-}
void FAST_FUNC clear_username_cache(void)
{
- clear_cache(&username);
- clear_cache(&groupname);
-}
-
-#if 0 /* more generic, but we don't need that yet */
-/* Returns -N-1 if not found. */
-/* cp->cache[N] is allocated and must be filled in this case */
-static int get_cached(cache_t *cp, uid_t id)
-{
- int i;
- for (i = 0; i < cp->size; i++)
- if (cp->cache[i].id == id)
- return i;
- i = cp->size++;
- cp->cache = xrealloc_vector(cp->cache, 2, i);
- cp->cache[i++].id = id;
- return -i;
+ if (cache_user_group) {
+ free(cache_user_group[0].cache);
+ free(cache_user_group[1].cache);
+ free(cache_user_group);
+ cache_user_group = NULL;
+ }
}
-#endif
-static char* get_cached(cache_t *cp, uid_t id,
+static char* get_cached(int user_group, uid_t id,
char* FAST_FUNC x2x_utoa(uid_t id))
{
+ cache_t *cp;
int i;
+
+ if (!cache_user_group)
+ cache_user_group = xzalloc(sizeof(cache_user_group[0]) * 2);
+
+ cp = &cache_user_group[user_group];
+
for (i = 0; i < cp->size; i++)
if (cp->cache[i].id == id)
return cp->cache[i].name;
@@ -67,11 +56,11 @@ static char* get_cached(cache_t *cp, uid_t id,
}
const char* FAST_FUNC get_cached_username(uid_t uid)
{
- return get_cached(&username, uid, uid2uname_utoa);
+ return get_cached(0, uid, uid2uname_utoa);
}
const char* FAST_FUNC get_cached_groupname(gid_t gid)
{
- return get_cached(&groupname, gid, gid2group_utoa);
+ return get_cached(1, gid, gid2group_utoa);
}
diff --git a/libbb/pw_encrypt.c b/libbb/pw_encrypt.c
index a60c33c35..3463fd95b 100644
--- a/libbb/pw_encrypt.c
+++ b/libbb/pw_encrypt.c
@@ -7,7 +7,9 @@
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/
#if !ENABLE_USE_BB_CRYPT
-#include <crypt.h>
+# if !defined(__FreeBSD__)
+# include <crypt.h>
+# endif
#endif
#include "libbb.h"
diff --git a/libbb/time.c b/libbb/time.c
index 74a69eefb..cf5f2e5c8 100644
--- a/libbb/time.c
+++ b/libbb/time.c
@@ -291,19 +291,19 @@ unsigned FAST_FUNC monotonic_sec(void)
unsigned long long FAST_FUNC monotonic_ns(void)
{
struct timeval tv;
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
return tv.tv_sec * 1000000000ULL + tv.tv_usec * 1000;
}
unsigned long long FAST_FUNC monotonic_us(void)
{
struct timeval tv;
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
return tv.tv_sec * 1000000ULL + tv.tv_usec;
}
unsigned long long FAST_FUNC monotonic_ms(void)
{
struct timeval tv;
- gettimeofday(&tv, NULL);
+ xgettimeofday(&tv);
return tv.tv_sec * 1000ULL + tv.tv_usec / 1000;
}
unsigned FAST_FUNC monotonic_sec(void)
diff --git a/libbb/update_passwd.c b/libbb/update_passwd.c
index 7b67f30cd..a228075cc 100644
--- a/libbb/update_passwd.c
+++ b/libbb/update_passwd.c
@@ -48,7 +48,7 @@ static void check_selinux_update_passwd(const char *username)
bb_simple_error_msg_and_die("SELinux: access denied");
}
if (ENABLE_FEATURE_CLEAN_UP)
- freecon(context);
+ freecon(seuser);
}
#else
# define check_selinux_update_passwd(username) ((void)0)
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c
index aea995a5c..f0399ca45 100644
--- a/libbb/xfuncs_printf.c
+++ b/libbb/xfuncs_printf.c
@@ -318,6 +318,11 @@ int FAST_FUNC bb_putchar(int ch)
return putchar(ch);
}
+int FAST_FUNC fputs_stdout(const char *s)
+{
+ return fputs(s, stdout);
+}
+
/* Die with an error message if we can't copy an entire FILE* to stdout,
* then close that file. */
void FAST_FUNC xprint_and_close_file(FILE *file)
@@ -720,3 +725,14 @@ void FAST_FUNC xsettimeofday(const struct timeval *tv)
if (settimeofday(tv, NULL))
bb_simple_perror_msg_and_die("settimeofday");
}
+
+void FAST_FUNC xgettimeofday(struct timeval *tv)
+{
+#if 0
+ if (gettimeofday(tv, NULL))
+ bb_simple_perror_msg_and_die("gettimeofday");
+#else
+ /* Never fails on Linux */
+ gettimeofday(tv, NULL);
+#endif
+}