aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
authorManuel Novoa III <mjn3@codepoet.org>2003-03-19 09:13:01 +0000
committerManuel Novoa III <mjn3@codepoet.org>2003-03-19 09:13:01 +0000
commitcad5364599eb5062d59e0c397ed638ddd61a8d5d (patch)
treea318d0f03aa076c74b576ea45dc543a5669e8e91 /libbb
parente01f9662a5bd5d91be4f6b3941b57fff73cd5af1 (diff)
downloadbusybox-cad5364599eb5062d59e0c397ed638ddd61a8d5d.tar.gz
Major coreutils update.
Diffstat (limited to 'libbb')
-rw-r--r--libbb/Makefile.in59
-rw-r--r--libbb/ask_confirmation.c50
-rw-r--r--libbb/bb_asprintf.c19
-rw-r--r--libbb/change_identity.c6
-rw-r--r--libbb/compare_string_array.c3
-rw-r--r--libbb/concat_path_file.c2
-rw-r--r--libbb/copy_file.c54
-rw-r--r--libbb/copy_file_chunk.c70
-rw-r--r--libbb/copyfd.c76
-rw-r--r--libbb/correct_password.c4
-rw-r--r--libbb/create_icmp6_socket.c4
-rw-r--r--libbb/create_icmp_socket.c4
-rw-r--r--libbb/default_error_retval.c32
-rw-r--r--libbb/dirname.c60
-rw-r--r--libbb/dump.c517
-rw-r--r--libbb/error_msg.c4
-rw-r--r--libbb/error_msg_and_die.c6
-rw-r--r--libbb/fclose_nonstdin.c37
-rw-r--r--libbb/fflush_stdout_and_exit.c37
-rw-r--r--libbb/find_root_device.c6
-rw-r--r--libbb/full_read.c11
-rw-r--r--libbb/full_write.c10
-rw-r--r--libbb/get_console.c2
-rw-r--r--libbb/get_last_path_component.c6
-rw-r--r--libbb/get_line_from_file.c48
-rw-r--r--libbb/getopt_ulflags.c (renamed from libbb/time_string.c)51
-rw-r--r--libbb/herror_msg.c4
-rw-r--r--libbb/herror_msg_and_die.c6
-rw-r--r--libbb/inet_common.c26
-rw-r--r--libbb/interface.c30
-rw-r--r--libbb/kernel_version.c2
-rw-r--r--libbb/loop.c12
-rw-r--r--libbb/make_directory.c118
-rw-r--r--libbb/messages.c59
-rw-r--r--libbb/mode_string.c150
-rw-r--r--libbb/module_syscalls.c2
-rw-r--r--libbb/mtab.c13
-rw-r--r--libbb/mtab_file.c4
-rw-r--r--libbb/my_getgrnam.c2
-rw-r--r--libbb/my_getpwnam.c2
-rw-r--r--libbb/my_getpwnamegid.c4
-rw-r--r--libbb/obscure.c6
-rw-r--r--libbb/parse_mode.c215
-rw-r--r--libbb/parse_number.c84
-rw-r--r--libbb/perror_msg.c4
-rw-r--r--libbb/perror_msg_and_die.c6
-rw-r--r--libbb/perror_nomsg.c30
-rw-r--r--libbb/perror_nomsg_and_die.c30
-rw-r--r--libbb/print_file.c49
-rw-r--r--libbb/printf.c177
-rw-r--r--libbb/process_escape_sequence.c39
-rw-r--r--libbb/procps.c2
-rw-r--r--libbb/read_package_field.c4
-rw-r--r--libbb/recursive_action.c10
-rw-r--r--libbb/remove_file.c26
-rw-r--r--libbb/run_parts.c14
-rw-r--r--libbb/run_shell.c6
-rw-r--r--libbb/setup_environment.c4
-rw-r--r--libbb/simplify_path.c9
-rw-r--r--libbb/skip_whitespace.c33
-rw-r--r--libbb/speed_table.c130
-rw-r--r--libbb/syscalls.c4
-rw-r--r--libbb/syslog_msg_with_name.c2
-rw-r--r--libbb/verror_msg.c4
-rw-r--r--libbb/vherror_msg.c4
-rw-r--r--libbb/vperror_msg.c4
-rw-r--r--libbb/warn_ignoring_args.c30
-rw-r--r--libbb/wfopen.c4
-rw-r--r--libbb/wfopen_input.c54
-rw-r--r--libbb/xconnect.c6
-rw-r--r--libbb/xfuncs.c89
-rw-r--r--libbb/xgetcwd.c2
-rw-r--r--libbb/xgethostbyname.c2
-rw-r--r--libbb/xgethostbyname2.c2
-rw-r--r--libbb/xgetlarg.c11
-rw-r--r--libbb/xgetularg.c160
-rw-r--r--libbb/xreadlink.c2
-rw-r--r--libbb/xregcomp.c2
78 files changed, 1823 insertions, 1049 deletions
diff --git a/libbb/Makefile.in b/libbb/Makefile.in
index 6d2475bcf..c7916f108 100644
--- a/libbb/Makefile.in
+++ b/libbb/Makefile.in
@@ -42,26 +42,59 @@ LIBBB_SRC:= \
restricted_shell.c run_parts.c run_shell.c safe_read.c safe_strncpy.c \
setup_environment.c simplify_path.c syscalls.c syslog_msg_with_name.c \
time_string.c trim.c u_signal_names.c vdprintf.c verror_msg.c \
- vherror_msg.c vperror_msg.c wfopen.c xconnect.c xgetcwd.c xfuncs.c \
- xgethostbyname.c xgethostbyname2.c xreadlink.c xregcomp.c xgetlarg.c
-
+ vherror_msg.c vperror_msg.c wfopen.c xconnect.c xgetcwd.c \
+ xgethostbyname.c xgethostbyname2.c xreadlink.c xregcomp.c xgetlarg.c \
+ \
+ fclose_nonstdin.c fflush_stdout_and_exit.c getopt_ulflags.c \
+ default_error_retval.c wfopen_input.c speed_table.c \
+ perror_nomsg_and_die.c perror_nomsg.c skip_whitespace.c \
+ warn_ignoring_args.c
LIBBB_OBJS=$(patsubst %.c,$(LIBBB_DIR)%.o, $(LIBBB_SRC))
-LIBBB_MSRC:=$(LIBBB_DIR)messages.c
-LIBBB_MOBJ:=full_version.o name_too_long.o omitting_directory.o not_a_directory.o \
- memory_exhausted.o invalid_date.o invalid_option.o io_error.o dash_dash_help.o \
- write_error.o too_few_args.o name_longer_than_foo.o unknown.o can_not_create_raw_socket.o \
- shadow_file.o passwd_file.o group_file.o gshadow_file.o nologin_file.o securetty_file.o \
- motd_file.o
-LIBBB_MOBJS=$(patsubst %,$(LIBBB_DIR)%, $(LIBBB_MOBJ))
+LIBBB_MSRC0:=$(LIBBB_DIR)messages.c
+LIBBB_MOBJ0:=full_version.o \
+ memory_exhausted.o invalid_date.o io_error.o \
+ write_error.o name_longer_than_foo.o unknown.o \
+ can_not_create_raw_socket.o perm_denied_are_you_root.o \
+ shadow_file.o passwd_file.o group_file.o gshadow_file.o nologin_file.o \
+ securetty_file.o motd_file.o \
+ msg_standard_input.o msg_standard_output.o
+
+LIBBB_MSRC1:=$(LIBBB_DIR)xfuncs.c
+LIBBB_MOBJ1:=xmalloc.o xrealloc.o xcalloc.o xstrdup.o xstrndup.o \
+ xfopen.o xopen.o xread.o xread_all.o xread_char.o \
+ xferror.o xferror_stdout.o xfflush_stdout.o strlen.o
+
+LIBBB_MSRC2:=$(LIBBB_DIR)printf.c
+LIBBB_MOBJ2:=vfprintf.o vprintf.o fprintf.o printf.o
+
+LIBBB_MSRC3:=$(LIBBB_DIR)xgetularg.c
+LIBBB_MOBJ3:=xgetularg_bnd_sfx.o xgetlarg_bnd_sfx.o getlarg10_sfx.o \
+ xgetularg_bnd.o xgetularg10_bnd.o xgetularg10.o
+
+LIBBB_MOBJS0=$(patsubst %,$(LIBBB_DIR)%, $(LIBBB_MOBJ0))
+LIBBB_MOBJS1=$(patsubst %,$(LIBBB_DIR)%, $(LIBBB_MOBJ1))
+LIBBB_MOBJS2=$(patsubst %,$(LIBBB_DIR)%, $(LIBBB_MOBJ2))
+LIBBB_MOBJS3=$(patsubst %,$(LIBBB_DIR)%, $(LIBBB_MOBJ3))
libraries-y+=$(LIBBB_DIR)$(LIBBB_AR)
-$(LIBBB_DIR)$(LIBBB_AR): $(LIBBB_OBJS) $(LIBBB_MOBJS)
- $(AR) -ro $@ $(LIBBB_OBJS) $(LIBBB_MOBJS)
+$(LIBBB_DIR)$(LIBBB_AR): $(LIBBB_OBJS) $(LIBBB_MOBJS0) $(LIBBB_MOBJS1) \
+ $(LIBBB_MOBJS2) $(LIBBB_MOBJS3)
+ $(AR) -ro $@ $(LIBBB_OBJS) $(LIBBB_MOBJS0) $(LIBBB_MOBJS1) \
+ $(LIBBB_MOBJS2) $(LIBBB_MOBJS3)
+
+$(LIBBB_MOBJS0): $(LIBBB_MSRC0)
+ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DL_$(notdir $*) -c $< -o $@
+
+$(LIBBB_MOBJS1): $(LIBBB_MSRC1)
+ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DL_$(notdir $*) -c $< -o $@
+
+$(LIBBB_MOBJS2): $(LIBBB_MSRC2)
+ $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DL_$(notdir $*) -c $< -o $@
-$(LIBBB_MOBJS): $(LIBBB_MSRC)
+$(LIBBB_MOBJS3): $(LIBBB_MSRC3)
$(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DL_$(notdir $*) -c $< -o $@
$(LIBBB_DIR)loop.o: $(LIBBB_DIR)loop.h
diff --git a/libbb/ask_confirmation.c b/libbb/ask_confirmation.c
index d4d943ad7..a99a4e733 100644
--- a/libbb/ask_confirmation.c
+++ b/libbb/ask_confirmation.c
@@ -1,49 +1,49 @@
/* vi: set sw=4 ts=4: */
/*
- * Utility routines.
+ * bb_ask_confirmation implementation for busybox
*
- * Copyright (C) many different people. If you wrote this, please
- * acknowledge your work.
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* Read a line from stdin. If the first non-whitespace char is 'y' or 'Y',
+ * return 1. Otherwise return 0.
*/
#include <stdio.h>
+#include <ctype.h>
#include "libbb.h"
-
-int ask_confirmation()
+int bb_ask_confirmation(void)
{
- int c = '\0';
- int ret = 0;
+ int retval = 0;
+ int first = 1;
+ int c;
- while (c != '\n') {
- c = getchar();
- if ( c != '\n' ) {
- ret = ((c=='y')||(c=='Y')) ? 1 : 0;
+ while (((c = getchar()) != EOF) && (c != '\n')) {
+ /* Make sure we get the actual function call for isspace,
+ * as speed is not critical here. */
+ if (first && !(isspace)(c)) {
+ --first;
+ if ((c == 'y') || (c == 'Y')) {
+ ++retval;
+ }
}
}
- return ret;
-}
-/* END CODE */
-/*
-Local Variables:
-c-file-style: "linux"
-c-basic-offset: 4
-tab-width: 4
-End:
-*/
+ return retval;
+}
diff --git a/libbb/bb_asprintf.c b/libbb/bb_asprintf.c
index 9a71be7f5..7075b46de 100644
--- a/libbb/bb_asprintf.c
+++ b/libbb/bb_asprintf.c
@@ -5,17 +5,18 @@
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
-
-
#include "libbb.h"
-
-void bb_asprintf(char **string_ptr, const char *format, ...)
+void bb_xasprintf(char **string_ptr, const char *format, ...)
{
- va_list p;
+ va_list p;
+ int r;
+
+ va_start(p, format);
+ r = vasprintf(string_ptr, format, p);
+ va_end(p);
- va_start(p, format);
- if(vasprintf(string_ptr, format, p)<0)
- error_msg_and_die(memory_exhausted);
- va_end(p);
+ if (r < 0) {
+ bb_perror_msg_and_die("bb_xasprintf");
+ }
}
diff --git a/libbb/change_identity.c b/libbb/change_identity.c
index 819b216e0..c2b73eeb8 100644
--- a/libbb/change_identity.c
+++ b/libbb/change_identity.c
@@ -43,12 +43,12 @@
void change_identity ( const struct passwd *pw )
{
if ( initgroups ( pw-> pw_name, pw-> pw_gid ) == -1 )
- perror_msg_and_die ( "cannot set groups" );
+ bb_perror_msg_and_die ( "cannot set groups" );
endgrent ( );
if ( setgid ( pw-> pw_gid ))
- perror_msg_and_die ( "cannot set group id" );
+ bb_perror_msg_and_die ( "cannot set group id" );
if ( setuid ( pw->pw_uid ))
- perror_msg_and_die ( "cannot set user id" );
+ bb_perror_msg_and_die ( "cannot set user id" );
}
diff --git a/libbb/compare_string_array.c b/libbb/compare_string_array.c
index b158ae447..993b46266 100644
--- a/libbb/compare_string_array.c
+++ b/libbb/compare_string_array.c
@@ -27,4 +27,5 @@ extern unsigned short compare_string_array(const char *string_array[], const cha
}
}
return(i);
-} \ No newline at end of file
+}
+
diff --git a/libbb/concat_path_file.c b/libbb/concat_path_file.c
index 0146606a1..b972ba6a3 100644
--- a/libbb/concat_path_file.c
+++ b/libbb/concat_path_file.c
@@ -38,7 +38,7 @@ extern char *concat_path_file(const char *path, const char *filename)
lc = last_char_is(path, '/');
while (*filename == '/')
filename++;
- bb_asprintf(&outbuf, "%s%s%s", path, (lc==NULL)? "/" : "", filename);
+ bb_xasprintf(&outbuf, "%s%s%s", path, (lc==NULL)? "/" : "", filename);
return outbuf;
}
diff --git a/libbb/copy_file.c b/libbb/copy_file.c
index 23a2d75a3..81c547479 100644
--- a/libbb/copy_file.c
+++ b/libbb/copy_file.c
@@ -43,19 +43,19 @@ int copy_file(const char *source, const char *dest, int flags)
lstat(source, &source_stat) < 0) ||
((flags & FILEUTILS_DEREFERENCE) &&
stat(source, &source_stat) < 0)) {
- perror_msg("%s", source);
+ bb_perror_msg("%s", source);
return -1;
}
if (lstat(dest, &dest_stat) < 0) {
if (errno != ENOENT) {
- perror_msg("unable to stat `%s'", dest);
+ bb_perror_msg("unable to stat `%s'", dest);
return -1;
}
} else {
if (source_stat.st_dev == dest_stat.st_dev &&
source_stat.st_ino == dest_stat.st_ino) {
- error_msg("`%s' and `%s' are the same file", source, dest);
+ bb_error_msg("`%s' and `%s' are the same file", source, dest);
return -1;
}
dest_exists = 1;
@@ -67,14 +67,14 @@ int copy_file(const char *source, const char *dest, int flags)
mode_t saved_umask = 0;
if (!(flags & FILEUTILS_RECUR)) {
- error_msg("%s: omitting directory", source);
+ bb_error_msg("%s: omitting directory", source);
return -1;
}
/* Create DEST. */
if (dest_exists) {
if (!S_ISDIR(dest_stat.st_mode)) {
- error_msg("`%s' is not a directory", dest);
+ bb_error_msg("`%s' is not a directory", dest);
return -1;
}
} else {
@@ -88,7 +88,7 @@ int copy_file(const char *source, const char *dest, int flags)
if (mkdir(dest, mode) < 0) {
umask(saved_umask);
- perror_msg("cannot create directory `%s'", dest);
+ bb_perror_msg("cannot create directory `%s'", dest);
return -1;
}
@@ -97,7 +97,7 @@ int copy_file(const char *source, const char *dest, int flags)
/* Recursively copy files in SOURCE. */
if ((dp = opendir(source)) == NULL) {
- perror_msg("unable to open directory `%s'", source);
+ bb_perror_msg("unable to open directory `%s'", source);
status = -1;
goto end;
}
@@ -121,7 +121,7 @@ int copy_file(const char *source, const char *dest, int flags)
if (!dest_exists &&
chmod(dest, source_stat.st_mode & ~saved_umask) < 0) {
- perror_msg("unable to change permissions of `%s'", dest);
+ bb_perror_msg("unable to change permissions of `%s'", dest);
status = -1;
}
} else if (S_ISREG(source_stat.st_mode)) {
@@ -132,7 +132,7 @@ int copy_file(const char *source, const char *dest, int flags)
if (!(flags & FILEUTILS_DEREFERENCE) &&
is_in_ino_dev_hashtable(&source_stat, &link_name)) {
if (link(link_name, dest) < 0) {
- perror_msg("unable to link `%s'", dest);
+ bb_perror_msg("unable to link `%s'", dest);
return -1;
}
@@ -140,14 +140,14 @@ int copy_file(const char *source, const char *dest, int flags)
}
#endif
- if ((sfp = wfopen(source, "r")) == NULL) {
+ if ((sfp = bb_wfopen(source, "r")) == NULL) {
return -1;
}
if (dest_exists) {
if (flags & FILEUTILS_INTERACTIVE) {
- fprintf(stderr, "%s: overwrite `%s'? ", applet_name, dest);
- if (!ask_confirmation()) {
+ fprintf(stderr, "%s: overwrite `%s'? ", bb_applet_name, dest);
+ if (!bb_ask_confirmation()) {
fclose (sfp);
return 0;
}
@@ -155,13 +155,13 @@ int copy_file(const char *source, const char *dest, int flags)
if ((dfp = fopen(dest, "w")) == NULL) {
if (!(flags & FILEUTILS_FORCE)) {
- perror_msg("unable to open `%s'", dest);
+ bb_perror_msg("unable to open `%s'", dest);
fclose (sfp);
return -1;
}
if (unlink(dest) < 0) {
- perror_msg("unable to remove `%s'", dest);
+ bb_perror_msg("unable to remove `%s'", dest);
fclose (sfp);
return -1;
}
@@ -177,22 +177,22 @@ int copy_file(const char *source, const char *dest, int flags)
(dfp = fdopen(fd, "w")) == NULL) {
if (fd >= 0)
close(fd);
- perror_msg("unable to open `%s'", dest);
+ bb_perror_msg("unable to open `%s'", dest);
fclose (sfp);
return -1;
}
}
- if (copyfd(fileno(sfp), fileno(dfp), 0) == -1)
+ if (bb_copyfd(fileno(sfp), fileno(dfp), 0) == -1)
status = -1;
if (fclose(dfp) < 0) {
- perror_msg("unable to close `%s'", dest);
+ bb_perror_msg("unable to close `%s'", dest);
status = -1;
}
if (fclose(sfp) < 0) {
- perror_msg("unable to close `%s'", source);
+ bb_perror_msg("unable to close `%s'", source);
status = -1;
}
}
@@ -202,23 +202,23 @@ int copy_file(const char *source, const char *dest, int flags)
if (dest_exists &&
((flags & FILEUTILS_FORCE) == 0 || unlink(dest) < 0)) {
- perror_msg("unable to remove `%s'", dest);
+ bb_perror_msg("unable to remove `%s'", dest);
return -1;
}
} else {
- error_msg("internal error: unrecognized file type");
+ bb_error_msg("internal error: unrecognized file type");
return -1;
}
if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) ||
S_ISSOCK(source_stat.st_mode)) {
if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) {
- perror_msg("unable to create `%s'", dest);
+ bb_perror_msg("unable to create `%s'", dest);
return -1;
}
} else if (S_ISFIFO(source_stat.st_mode)) {
if (mkfifo(dest, source_stat.st_mode) < 0) {
- perror_msg("cannot create fifo `%s'", dest);
+ bb_perror_msg("cannot create fifo `%s'", dest);
return -1;
}
} else if (S_ISLNK(source_stat.st_mode)) {
@@ -226,7 +226,7 @@ int copy_file(const char *source, const char *dest, int flags)
lpath = xreadlink(source);
if (symlink(lpath, dest) < 0) {
- perror_msg("cannot create symlink `%s'", dest);
+ bb_perror_msg("cannot create symlink `%s'", dest);
return -1;
}
free(lpath);
@@ -234,7 +234,7 @@ int copy_file(const char *source, const char *dest, int flags)
#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
if (flags & FILEUTILS_PRESERVE_STATUS)
if (lchown(dest, source_stat.st_uid, source_stat.st_gid) < 0)
- perror_msg("unable to preserve ownership of `%s'", dest);
+ bb_perror_msg("unable to preserve ownership of `%s'", dest);
#endif
#ifdef CONFIG_FEATURE_PRESERVE_HARDLINKS
@@ -256,13 +256,13 @@ end:
times.actime = source_stat.st_atime;
times.modtime = source_stat.st_mtime;
if (utime(dest, &times) < 0)
- perror_msg("unable to preserve times of `%s'", dest);
+ bb_perror_msg("unable to preserve times of `%s'", dest);
if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) {
source_stat.st_mode &= ~(S_ISUID | S_ISGID);
- perror_msg("unable to preserve ownership of `%s'", dest);
+ bb_perror_msg("unable to preserve ownership of `%s'", dest);
}
if (chmod(dest, source_stat.st_mode) < 0)
- perror_msg("unable to preserve permissions of `%s'", dest);
+ bb_perror_msg("unable to preserve permissions of `%s'", dest);
}
return status;
diff --git a/libbb/copy_file_chunk.c b/libbb/copy_file_chunk.c
deleted file mode 100644
index 63d2ab173..000000000
--- a/libbb/copy_file_chunk.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/* vi: set sw=4 ts=4: */
-/*
- * Utility routines.
- *
- * Copyright (C) many different people. If you wrote this, please
- * acknowledge your work.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
- */
-
-#include <stdio.h>
-#include <sys/stat.h>
-#include "libbb.h"
-
-/* Copy CHUNKSIZE bytes (or until EOF if CHUNKSIZE equals -1) from SRC_FILE
- * to DST_FILE. */
-extern int copy_file_chunk(FILE *src_file, FILE *dst_file, unsigned long long chunksize)
-{
- size_t nread, nwritten, size;
- char buffer[BUFSIZ];
-
- while (chunksize != 0) {
- if (chunksize > BUFSIZ)
- size = BUFSIZ;
- else
- size = chunksize;
-
- nread = fread (buffer, 1, size, src_file);
-
- if (nread != size && ferror (src_file)) {
- perror_msg ("read");
- return -1;
- } else if (nread == 0) {
- if (chunksize != -1) {
- error_msg ("Unable to read all data");
- return -1;
- }
-
- return 0;
- }
-
- nwritten = fwrite (buffer, 1, nread, dst_file);
-
- if (nwritten != nread) {
- if (ferror (dst_file))
- perror_msg ("write");
- else
- error_msg ("Unable to write all data");
- return -1;
- }
-
- if (chunksize != -1)
- chunksize -= nwritten;
- }
-
- return 0;
-}
diff --git a/libbb/copyfd.c b/libbb/copyfd.c
index 4df1fd084..41b78c7d6 100644
--- a/libbb/copyfd.c
+++ b/libbb/copyfd.c
@@ -22,65 +22,51 @@
#include <unistd.h>
#include <string.h>
#include <errno.h>
-#include "libbb.h"
+#include "busybox.h"
-/* If chunksize is 0 copy untill EOF */
-extern int copyfd(int fd1, int fd2, const off_t chunksize)
+#if BUFSIZ < 4096
+#undef BUFSIZ
+#define BUFSIZ 4096
+#endif
+
+/* If chunksize is 0 copy until EOF */
+extern int bb_copyfd(int fd1, int fd2, const off_t chunksize)
{
- size_t nread;
- size_t nwritten;
+ ssize_t nread;
size_t size;
- size_t remaining;
- char buffer[BUFSIZ];
+ off_t remaining;
+ RESERVE_CONFIG_BUFFER(buffer,BUFSIZ);
+ remaining = size = BUFSIZ;
if (chunksize) {
remaining = chunksize;
- } else {
- remaining = -1;
}
do {
- if ((chunksize > BUFSIZ) || (chunksize == 0)) {
- size = BUFSIZ;
- } else {
- size = chunksize;
+ if (size > remaining) {
+ size = remaining;
}
- nread = safe_read(fd1, buffer, size);
-
- if (nread == -1) {
- perror_msg("read failure");
- return(-1);
- }
- else if (nread == 0) {
+ if ((nread = safe_read(fd1, buffer, size)) > 0) {
+ if (bb_full_write(fd2, buffer, nread) < 0) {
+ bb_perror_msg(bb_msg_write_error); /* match Read error below */
+ break;
+ }
+ if (chunksize && ((remaining -= nread) == 0)) {
+ return 0;
+ }
+ } else if (!nread) {
if (chunksize) {
- error_msg("Unable to read all data");
- return(-1);
- } else {
- return(0);
+ bb_error_msg("Unable to read all data");
+ break;
}
+ return 0;
+ } else { /* nread < 0 */
+ bb_perror_msg("Read error"); /* match bb_msg_write_error above */
+ break;
}
- nwritten = full_write(fd2, buffer, nread);
+ } while (1);
- if (nwritten != nread) {
- error_msg("Unable to write all data");
- return(-1);
- }
-
- if (chunksize) {
- remaining -= nwritten;
- }
- } while (remaining != 0);
-
- return 0;
+ return -1;
}
-
-/* END CODE */
-/*
-Local Variables:
-c-file-style: "linux"
-c-basic-offset: 4
-tab-width: 4
-End:
-*/
diff --git a/libbb/correct_password.c b/libbb/correct_password.c
index 758b89eed..396253614 100644
--- a/libbb/correct_password.c
+++ b/libbb/correct_password.c
@@ -55,7 +55,7 @@ int correct_password ( const struct passwd *pw )
struct spwd *sp = getspnam ( pw-> pw_name );
if ( !sp )
- error_msg_and_die ( "no valid shadow password" );
+ bb_error_msg_and_die ( "no valid shadow password" );
correct = sp-> sp_pwdp;
}
@@ -73,6 +73,6 @@ int correct_password ( const struct passwd *pw )
return 0;
}
encrypted = crypt ( unencrypted, correct );
- memset ( unencrypted, 0, xstrlen ( unencrypted ));
+ memset ( unencrypted, 0, bb_strlen ( unencrypted ));
return ( strcmp ( encrypted, correct ) == 0 ) ? 1 : 0;
}
diff --git a/libbb/create_icmp6_socket.c b/libbb/create_icmp6_socket.c
index 1d0b6b6bf..596610449 100644
--- a/libbb/create_icmp6_socket.c
+++ b/libbb/create_icmp6_socket.c
@@ -26,9 +26,9 @@ int create_icmp6_socket(void)
if ((sock = socket(AF_INET6, SOCK_RAW,
(proto ? proto->p_proto : IPPROTO_ICMPV6))) < 0) {
if (errno == EPERM)
- error_msg_and_die("permission denied. (are you root?)");
+ bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
else
- perror_msg_and_die(can_not_create_raw_socket);
+ bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);
}
/* drop root privs if running setuid */
diff --git a/libbb/create_icmp_socket.c b/libbb/create_icmp_socket.c
index d804b3987..58d792b1b 100644
--- a/libbb/create_icmp_socket.c
+++ b/libbb/create_icmp_socket.c
@@ -25,9 +25,9 @@ int create_icmp_socket(void)
if ((sock = socket(AF_INET, SOCK_RAW,
(proto ? proto->p_proto : 1))) < 0) { /* 1 == ICMP */
if (errno == EPERM)
- error_msg_and_die("permission denied. (are you root?)");
+ bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
else
- perror_msg_and_die(can_not_create_raw_socket);
+ bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);
}
/* drop root privs if running setuid */
diff --git a/libbb/default_error_retval.c b/libbb/default_error_retval.c
new file mode 100644
index 000000000..7d2d89bb5
--- /dev/null
+++ b/libbb/default_error_retval.c
@@ -0,0 +1,32 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* Seems silly to copyright a global variable. ;-) Oh well.
+ *
+ * At least one applet (cmp) returns a value different from the typical
+ * EXIT_FAILURE values (1) when an error occurs. So, make it configureable
+ * by the applet. I suppose we could use a wrapper function to set it, but
+ * that too seems silly.
+ */
+
+#include <stdlib.h>
+#include "libbb.h"
+
+int bb_default_error_retval = EXIT_FAILURE;
diff --git a/libbb/dirname.c b/libbb/dirname.c
index df9a49daa..81298730b 100644
--- a/libbb/dirname.c
+++ b/libbb/dirname.c
@@ -1,8 +1,8 @@
/* vi: set sw=4 ts=4: */
/*
- * Mini dirname function.
+ * dirname implementation for busybox (for libc's missing one)
*
- * Copyright (C) 2001 Matt Kraai.
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,39 +17,53 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* Note: The previous busybox implementation did not handle NULL path
+ * and also moved a pointer before path, which is not portable in C.
+ * So I replaced it with my uClibc version.
*/
#include <string.h>
#include "libbb.h"
-#if defined __UCLIBC__ || __GNU_LIBRARY___ < 5
-
-/* Return a string containing the path name of the parent
- * directory of PATH. */
+#if __GNU_LIBRARY__ < 5
+extern
char *dirname(char *path)
{
- char *s;
-
- /* Go to the end of the string. */
- s = path + strlen(path) - 1;
-
- /* Strip off trailing /s (unless it is also the leading /). */
- while (path < s && s[0] == '/')
- s--;
+ static const char null_or_empty_or_noslash[] = ".";
+ register char *s;
+ register char *last;
+ char *first;
- /* Strip the last component. */
- while (path <= s && s[0] != '/')
- s--;
+ last = s = path;
- while (path < s && s[0] == '/')
- s--;
+ if (s != NULL) {
- if (s < path)
- return ".";
+ LOOP:
+ while (*s && (*s != '/')) ++s;
+ first = s;
+ while (*s == '/') ++s;
+ if (*s) {
+ last = first;
+ goto LOOP;
+ }
- s[1] = '\0';
- return path;
+ if (last == path) {
+ if (*last != '/') {
+ goto DOT;
+ }
+ if ((*++last == '/') && (last[1] == 0)) {
+ ++last;
+ }
+ }
+ *last = 0;
+ return path;
+ }
+ DOT:
+ return (char *) null_or_empty_or_noslash;
}
#endif
diff --git a/libbb/dump.c b/libbb/dump.c
index 1afad83fd..26dabe57f 100644
--- a/libbb/dump.c
+++ b/libbb/dump.c
@@ -25,94 +25,80 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h> /* for isdigit() */
-#include "dump.h"
#include "libbb.h"
+#include "dump.h"
-enum _vflag vflag = FIRST;
-FS *fshead; /* head of format strings */
-extern FS *fshead; /* head of format strings */
-extern int blocksize;
+enum _vflag bb_dump_vflag = FIRST;
+FS *bb_dump_fshead; /* head of format strings */
static FU *endfu;
static char **_argv;
static off_t savaddress; /* saved address/offset in stream */
static off_t eaddress; /* end address */
static off_t address; /* address/offset in stream */
-off_t skip; /* bytes to skip */
-off_t saveaddress;
-int exitval; /* final exit value */
-int blocksize; /* data block size */
-int length = -1; /* max bytes to read */
+off_t bb_dump_skip; /* bytes to skip */
+static int exitval; /* final exit value */
+int bb_dump_blocksize; /* data block size */
+int bb_dump_length = -1; /* max bytes to read */
+
+static const char index_str[] = ".#-+ 0123456789";
+static const char size_conv_str[] =
+"\x1\x4\x4\x4\x4\x4\x4\x8\x8\x8\x8\010cdiouxXeEfgG";
-int size(FS * fs)
+static const char lcc[] = "diouxX";
+
+int bb_dump_size(FS * fs)
{
register FU *fu;
- register int bcnt, cursize;
+ register int bcnt, cur_size;
register char *fmt;
+ const char *p;
int prec;
- /* figure out the data block size needed for each format unit */
- for (cursize = 0, fu = fs->nextfu; fu; fu = fu->nextfu) {
+ /* figure out the data block bb_dump_size needed for each format unit */
+ for (cur_size = 0, fu = fs->nextfu; fu; fu = fu->nextfu) {
if (fu->bcnt) {
- cursize += fu->bcnt * fu->reps;
+ cur_size += fu->bcnt * fu->reps;
continue;
}
for (bcnt = prec = 0, fmt = fu->fmt; *fmt; ++fmt) {
if (*fmt != '%')
continue;
/*
- * skip any special chars -- save precision in
+ * bb_dump_skip any special chars -- save precision in
* case it's a %s format.
*/
- while (index(".#-+ 0123456789" + 1, *++fmt));
+ while (strchr(index_str + 1, *++fmt));
if (*fmt == '.' && isdigit(*++fmt)) {
prec = atoi(fmt);
while (isdigit(*++fmt));
}
- switch (*fmt) {
- case 'c':
- bcnt += 1;
- break;
- case 'd':
- case 'i':
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- bcnt += 4;
- break;
- case 'e':
- case 'E':
- case 'f':
- case 'g':
- case 'G':
- bcnt += 8;
- break;
- case 's':
- bcnt += prec;
- break;
- case '_':
- switch (*++fmt) {
- case 'c':
- case 'p':
- case 'u':
- bcnt += 1;
- break;
+ if (!(p = strchr(size_conv_str + 12, *fmt))) {
+ if (*fmt == 's') {
+ bcnt += prec;
+ } else if (*fmt == '_') {
+ ++fmt;
+ if ((*fmt == 'c') || (*fmt == 'p') || (*fmt == 'u')) {
+ bcnt += 1;
+ }
}
+ } else {
+ bcnt += size_conv_str[p - (size_conv_str + 12)];
}
}
- cursize += bcnt * fu->reps;
+ cur_size += bcnt * fu->reps;
}
- return (cursize);
+ return (cur_size);
}
-void rewrite(FS * fs)
+static void rewrite(FS * fs)
{
enum { NOTOKAY, USEBCNT, USEPREC } sokay;
register PR *pr, **nextpr = NULL;
register FU *fu;
register char *p1, *p2;
char savech, *fmtp;
+ const char *byte_count_str;
int nconv, prec = 0;
for (fu = fs->nextfu; fu; fu = fu->nextfu) {
@@ -128,7 +114,7 @@ void rewrite(FS * fs)
else
*nextpr = pr;
- /* skip preceding text and up to the next % sign */
+ /* bb_dump_skip preceding text and up to the next % sign */
for (p1 = fmtp; *p1 && *p1 != '%'; ++p1);
/* only text in the string */
@@ -144,11 +130,11 @@ void rewrite(FS * fs)
*/
if (fu->bcnt) {
sokay = USEBCNT;
- /* skip to conversion character */
- for (++p1; index(".#-+ 0123456789", *p1); ++p1);
+ /* bb_dump_skip to conversion character */
+ for (++p1; strchr(index_str, *p1); ++p1);
} else {
- /* skip any special chars, field width */
- while (index(".#-+ 0123456789" + 1, *++p1));
+ /* bb_dump_skip any special chars, field width */
+ while (strchr(index_str + 1, *++p1));
if (*p1 == '.' && isdigit(*++p1)) {
sokay = USEPREC;
prec = atoi(p1);
@@ -162,104 +148,59 @@ void rewrite(FS * fs)
/*
* figure out the byte count for each conversion;
* rewrite the format as necessary, set up blank-
- * padding for end of data.
+ * pbb_dump_adding for end of data.
*/
- switch (*p1) {
- case 'c':
+
+ if (*p1 == 'c') {
pr->flags = F_CHAR;
- switch (fu->bcnt) {
- case 0:
- case 1:
- pr->bcnt = 1;
- break;
- default:
- p1[1] = '\0';
- error_msg_and_die
- ("bad byte count for conversion character %s.", p1);
+ DO_BYTE_COUNT_1:
+ byte_count_str = "\001";
+ DO_BYTE_COUNT:
+ if (fu->bcnt) {
+ do {
+ if (fu->bcnt == *byte_count_str) {
+ break;
+ }
+ } while (*++byte_count_str);
}
- break;
- case 'd':
- case 'i':
- pr->flags = F_INT;
- goto sw1;
- case 'l':
+ /* Unlike the original, output the remainder of the format string. */
+ if (!*byte_count_str) {
+ bb_error_msg_and_die("bad byte count for conversion character %s.", p1);
+ }
+ pr->bcnt = *byte_count_str;
+ } else if (*p1 == 'l') {
++p2;
- switch (p1[1]) {
- case 'd':
- case 'i':
- ++p1;
+ ++p1;
+ DO_INT_CONV:
+ {
+ const char *e;
+ if (!(e = strchr(lcc, *p1))) {
+ goto DO_BAD_CONV_CHAR;
+ }
pr->flags = F_INT;
- goto sw1;
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- ++p1;
- pr->flags = F_UINT;
- goto sw1;
- default:
- p1[2] = '\0';
- error_msg_and_die
- ("hexdump: bad conversion character %%%s.\n", p1);
+ if (e > lcc + 1) {
+ pr->flags = F_UINT;
+ }
+ byte_count_str = "\004\002\001";
+ goto DO_BYTE_COUNT;
}
/* NOTREACHED */
- case 'o':
- case 'u':
- case 'x':
- case 'X':
- pr->flags = F_UINT;
- sw1:switch (fu->bcnt) {
- case 0:
- case 4:
- pr->bcnt = 4;
- break;
- case 1:
- pr->bcnt = 1;
- break;
- case 2:
- pr->bcnt = 2;
- break;
- default:
- p1[1] = '\0';
- error_msg_and_die
- ("bad byte count for conversion character %s.", p1);
- }
- break;
- case 'e':
- case 'E':
- case 'f':
- case 'g':
- case 'G':
+ } else if (strchr(lcc, *p1)) {
+ goto DO_INT_CONV;
+ } else if (strchr("eEfgG", *p1)) {
pr->flags = F_DBL;
- switch (fu->bcnt) {
- case 0:
- case 8:
- pr->bcnt = 8;
- break;
- case 4:
- pr->bcnt = 4;
- break;
- default:
- p1[1] = '\0';
- error_msg_and_die
- ("bad byte count for conversion character %s.", p1);
- }
- break;
- case 's':
+ byte_count_str = "\010\004";
+ goto DO_BYTE_COUNT;
+ } else if (*p1 == 's') {
pr->flags = F_STR;
- switch (sokay) {
- case NOTOKAY:
- error_msg_and_die
- ("%%s requires a precision or a byte count.");
- case USEBCNT:
+ if (sokay == USEBCNT) {
pr->bcnt = fu->bcnt;
- break;
- case USEPREC:
+ } else if (sokay == USEPREC) {
pr->bcnt = prec;
- break;
+ } else { /* NOTOKAY */
+ bb_error_msg_and_die("%%s requires a precision or a byte count.");
}
- break;
- case '_':
+ } else if (*p1 == '_') {
++p2;
switch (p1[1]) {
case 'A':
@@ -269,51 +210,29 @@ void rewrite(FS * fs)
case 'a':
pr->flags = F_ADDRESS;
++p2;
- switch (p1[2]) {
- case 'd':
- case 'o':
- case 'x':
- *p1 = p1[2];
- break;
- default:
- p1[3] = '\0';
- error_msg_and_die
- ("hexdump: bad conversion character %%%s.\n", p1);
+ if ((p1[2] != 'd') && (p1[2] != 'o') && (p1[2] != 'x')) {
+ goto DO_BAD_CONV_CHAR;
}
+ *p1 = p1[2];
break;
case 'c':
pr->flags = F_C;
/* *p1 = 'c'; set in conv_c */
- goto sw2;
+ goto DO_BYTE_COUNT_1;
case 'p':
pr->flags = F_P;
*p1 = 'c';
- goto sw2;
+ goto DO_BYTE_COUNT_1;
case 'u':
pr->flags = F_U;
/* *p1 = 'c'; set in conv_u */
- sw2:switch (fu->bcnt) {
- case 0:
- case 1:
- pr->bcnt = 1;
- break;
- default:
- p1[2] = '\0';
- error_msg_and_die
- ("bad byte count for conversion character %s.",
- p1);
- }
- break;
+ goto DO_BYTE_COUNT_1;
default:
- p1[2] = '\0';
- error_msg_and_die
- ("hexdump: bad conversion character %%%s.\n", p1);
+ goto DO_BAD_CONV_CHAR;
}
- break;
- default:
- p1[1] = '\0';
- error_msg_and_die("hexdump: bad conversion character %%%s.\n",
- p1);
+ } else {
+ DO_BAD_CONV_CHAR:
+ bb_error_msg_and_die("bad conversion character %%%s.\n", p1);
}
/*
@@ -322,16 +241,14 @@ void rewrite(FS * fs)
*/
savech = *p2;
p1[1] = '\0';
- if (!(pr->fmt = strdup(fmtp)))
- perror_msg_and_die("hexdump");
+ pr->fmt = bb_xstrdup(fmtp);
*p2 = savech;
pr->cchar = pr->fmt + (p1 - fmtp);
fmtp = p2;
/* only one conversion character if byte count */
if (!(pr->flags & F_ADDRESS) && fu->bcnt && nconv++) {
- error_msg_and_die
- ("hexdump: byte count with multiple conversion characters.\n");
+ bb_error_msg_and_die("byte count with multiple conversion characters.\n");
}
}
/*
@@ -344,7 +261,7 @@ void rewrite(FS * fs)
}
/*
* if the format string interprets any data at all, and it's
- * not the same as the blocksize, and its last format unit
+ * not the same as the bb_dump_blocksize, and its last format unit
* interprets any data at all, and has no iteration count,
* repeat it as necessary.
*
@@ -352,9 +269,9 @@ void rewrite(FS * fs)
* gets output from the last iteration of the format unit.
*/
for (fu = fs->nextfu;; fu = fu->nextfu) {
- if (!fu->nextfu && fs->bcnt < blocksize &&
+ if (!fu->nextfu && fs->bcnt < bb_dump_blocksize &&
!(fu->flags & F_SETREP) && fu->bcnt)
- fu->reps += (blocksize - fs->bcnt) / fu->bcnt;
+ fu->reps += (bb_dump_blocksize - fs->bcnt) / fu->bcnt;
if (fu->reps > 1) {
for (pr = fu->nextpr;; pr = pr->nextpr)
if (!pr->nextpr)
@@ -369,31 +286,31 @@ void rewrite(FS * fs)
}
}
-static void doskip(char *fname, int statok)
+static void do_skip(char *fname, int statok)
{
struct stat sbuf;
if (statok) {
if (fstat(fileno(stdin), &sbuf)) {
- perror_msg_and_die("hexdump: %s", fname);
+ bb_perror_msg_and_die("%s", fname);
}
if ((!(S_ISCHR(sbuf.st_mode) ||
S_ISBLK(sbuf.st_mode) ||
- S_ISFIFO(sbuf.st_mode))) && skip >= sbuf.st_size) {
- /* If size valid and skip >= size */
- skip -= sbuf.st_size;
+ S_ISFIFO(sbuf.st_mode))) && bb_dump_skip >= sbuf.st_size) {
+ /* If bb_dump_size valid and bb_dump_skip >= size */
+ bb_dump_skip -= sbuf.st_size;
address += sbuf.st_size;
return;
}
}
- if (fseek(stdin, skip, SEEK_SET)) {
- perror_msg_and_die("hexdump: %s", fname);
+ if (fseek(stdin, bb_dump_skip, SEEK_SET)) {
+ bb_perror_msg_and_die("%s", fname);
}
- savaddress = address += skip;
- skip = 0;
+ savaddress = address += bb_dump_skip;
+ bb_dump_skip = 0;
}
-int next(char **argv)
+static int next(char **argv)
{
static int done;
int statok;
@@ -405,7 +322,7 @@ int next(char **argv)
for (;;) {
if (*_argv) {
if (!(freopen(*_argv, "r", stdin))) {
- perror_msg("%s", *_argv);
+ bb_perror_msg("%s", *_argv);
exitval = 1;
++_argv;
continue;
@@ -416,11 +333,11 @@ int next(char **argv)
return (0);
statok = 0;
}
- if (skip)
- doskip(statok ? *_argv : "stdin", statok);
+ if (bb_dump_skip)
+ do_skip(statok ? *_argv : "stdin", statok);
if (*_argv)
++_argv;
- if (!skip)
+ if (!bb_dump_skip)
return (1);
}
/* NOTREACHED */
@@ -435,26 +352,26 @@ static u_char *get(void)
u_char *tmpp;
if (!curp) {
- curp = (u_char *) xmalloc(blocksize);
- savp = (u_char *) xmalloc(blocksize);
+ curp = (u_char *) xmalloc(bb_dump_blocksize);
+ savp = (u_char *) xmalloc(bb_dump_blocksize);
} else {
tmpp = curp;
curp = savp;
savp = tmpp;
- address = savaddress += blocksize;
+ address = savaddress += bb_dump_blocksize;
}
- for (need = blocksize, nread = 0;;) {
+ for (need = bb_dump_blocksize, nread = 0;;) {
/*
* if read the right number of bytes, or at EOF for one file,
* and no other files are available, zero-pad the rest of the
* block and set the end flag.
*/
- if (!length || (ateof && !next((char **) NULL))) {
- if (need == blocksize) {
+ if (!bb_dump_length || (ateof && !next((char **) NULL))) {
+ if (need == bb_dump_blocksize) {
return ((u_char *) NULL);
}
- if (vflag != ALL && !bcmp(curp, savp, nread)) {
- if (vflag != DUP) {
+ if (bb_dump_vflag != ALL && !bcmp(curp, savp, nread)) {
+ if (bb_dump_vflag != DUP) {
printf("*\n");
}
return ((u_char *) NULL);
@@ -464,31 +381,32 @@ static u_char *get(void)
return (curp);
}
n = fread((char *) curp + nread, sizeof(u_char),
- length == -1 ? need : MIN(length, need), stdin);
+ bb_dump_length == -1 ? need : MIN(bb_dump_length, need), stdin);
if (!n) {
if (ferror(stdin)) {
- perror_msg("%s", _argv[-1]);
+ bb_perror_msg("%s", _argv[-1]);
}
ateof = 1;
continue;
}
ateof = 0;
- if (length != -1) {
- length -= n;
+ if (bb_dump_length != -1) {
+ bb_dump_length -= n;
}
if (!(need -= n)) {
- if (vflag == ALL || vflag == FIRST || bcmp(curp, savp, blocksize)) {
- if (vflag == DUP || vflag == FIRST) {
- vflag = WAIT;
+ if (bb_dump_vflag == ALL || bb_dump_vflag == FIRST
+ || bcmp(curp, savp, bb_dump_blocksize)) {
+ if (bb_dump_vflag == DUP || bb_dump_vflag == FIRST) {
+ bb_dump_vflag = WAIT;
}
return (curp);
}
- if (vflag == WAIT) {
+ if (bb_dump_vflag == WAIT) {
printf("*\n");
}
- vflag = DUP;
- address = savaddress += blocksize;
- need = blocksize;
+ bb_dump_vflag = DUP;
+ address = savaddress += bb_dump_blocksize;
+ need = bb_dump_blocksize;
nread = 0;
} else {
nread += n;
@@ -507,67 +425,59 @@ static void bpad(PR * pr)
pr->flags = F_BPAD;
*pr->cchar = 's';
for (p1 = pr->fmt; *p1 != '%'; ++p1);
- for (p2 = ++p1; *p1 && index(" -0+#", *p1); ++p1);
+ for (p2 = ++p1; *p1 && strchr(" -0+#", *p1); ++p1);
while ((*p2++ = *p1++) != 0);
}
-void conv_c(PR * pr, u_char * p)
+static const char conv_str[] =
+ "\0\\0\0"
+ "\007\\a\0" /* \a */
+ "\b\\b\0"
+ "\f\\b\0"
+ "\n\\n\0"
+ "\r\\r\0"
+ "\t\\t\0"
+ "\v\\v\0"
+ "\0";
+
+
+static void conv_c(PR * pr, u_char * p)
{
- char buf[10], *str;
-
- switch (*p) {
- case '\0':
- str = "\\0";
- goto strpr;
- /* case '\a': */
- case '\007':
- str = "\\a";
- goto strpr;
- case '\b':
- str = "\\b";
- goto strpr;
- case '\f':
- str = "\\f";
- goto strpr;
- case '\n':
- str = "\\n";
- goto strpr;
- case '\r':
- str = "\\r";
- goto strpr;
- case '\t':
- str = "\\t";
- goto strpr;
- case '\v':
- str = "\\v";
- goto strpr;
- default:
- break;
- }
+ const char *str = conv_str;
+ char buf[10];
+
+ do {
+ if (*p == *str) {
+ ++str;
+ goto strpr;
+ }
+ str += 4;
+ } while (*str);
+
if (isprint(*p)) {
*pr->cchar = 'c';
(void) printf(pr->fmt, *p);
} else {
- sprintf(str = buf, "%03o", (int) *p);
+ sprintf(buf, "%03o", (int) *p);
+ str = buf;
strpr:
*pr->cchar = 's';
printf(pr->fmt, str);
}
}
-void conv_u(PR * pr, u_char * p)
+static void conv_u(PR * pr, u_char * p)
{
- static char *list[] = {
- "nul", "soh", "stx", "etx", "eot", "enq", "ack", "bel",
- "bs", "ht", "lf", "vt", "ff", "cr", "so", "si",
- "dle", "dcl", "dc2", "dc3", "dc4", "nak", "syn", "etb",
- "can", "em", "sub", "esc", "fs", "gs", "rs", "us",
- };
+ static const char list[] =
+ "nul\0soh\0stx\0etx\0eot\0enq\0ack\0bel\0"
+ "bs\0_ht\0_lf\0_vt\0_ff\0_cr\0_so\0_si\0_"
+ "dle\0dcl\0dc2\0dc3\0dc4\0nak\0syn\0etb\0"
+ "can\0em\0_sub\0esc\0fs\0_gs\0_rs\0_us";
/* od used nl, not lf */
if (*p <= 0x1f) {
*pr->cchar = 's';
- printf(pr->fmt, list[*p]);
+ printf(pr->fmt, list[4 * (int)(*p)]);
} else if (*p == 0x7f) {
*pr->cchar = 's';
printf(pr->fmt, "del");
@@ -580,7 +490,7 @@ void conv_u(PR * pr, u_char * p)
}
}
-void display(void)
+static void display(void)
{
/* extern FU *endfu; */
register FS *fs;
@@ -589,11 +499,11 @@ void display(void)
register int cnt;
register u_char *bp;
-/* off_t saveaddress; */
+ off_t saveaddress;
u_char savech = 0, *savebp;
while ((bp = get()) != NULL) {
- for (fs = fshead, savebp = bp, saveaddress = address; fs;
+ for (fs = bb_dump_fshead, savebp = bp, saveaddress = address; fs;
fs = fs->nextfs, bp = savebp, address = saveaddress) {
for (fu = fs->nextfu; fu; fu = fu->nextfu) {
if (fu->flags & F_IGNORE) {
@@ -707,8 +617,8 @@ void display(void)
}
if (endfu) {
/*
- * if eaddress not set, error or file size was multiple of
- * blocksize, and no partial block ever found.
+ * if eaddress not set, error or file bb_dump_size was multiple of
+ * bb_dump_blocksize, and no partial block ever found.
*/
if (!eaddress) {
if (!address) {
@@ -729,19 +639,19 @@ void display(void)
}
}
-int dump(char **argv)
+int bb_dump_dump(char **argv)
{
register FS *tfs;
- /* figure out the data block size */
- for (blocksize = 0, tfs = fshead; tfs; tfs = tfs->nextfs) {
- tfs->bcnt = size(tfs);
- if (blocksize < tfs->bcnt) {
- blocksize = tfs->bcnt;
+ /* figure out the data block bb_dump_size */
+ for (bb_dump_blocksize = 0, tfs = bb_dump_fshead; tfs; tfs = tfs->nextfs) {
+ tfs->bcnt = bb_dump_size(tfs);
+ if (bb_dump_blocksize < tfs->bcnt) {
+ bb_dump_blocksize = tfs->bcnt;
}
}
/* rewrite the rules, do syntax checking */
- for (tfs = fshead; tfs; tfs = tfs->nextfs) {
+ for (tfs = bb_dump_fshead; tfs; tfs = tfs->nextfs) {
rewrite(tfs);
}
@@ -751,21 +661,21 @@ int dump(char **argv)
return (exitval);
}
-void add(char *fmt)
+void bb_dump_add(const char *fmt)
{
- register char *p;
+ register const char *p;
register char *p1;
register char *p2;
static FS **nextfs;
FS *tfs;
FU *tfu, **nextfu;
- char *savep;
+ const char *savep;
/* start new linked list of format units */
/* NOSTRICT */
tfs = (FS *) xmalloc(sizeof(FS));
- if (!fshead) {
- fshead = tfs;
+ if (!bb_dump_fshead) {
+ bb_dump_fshead = tfs;
} else {
*nextfs = tfs;
}
@@ -774,8 +684,8 @@ void add(char *fmt)
/* take the format string and break it up into format units */
for (p = fmt;;) {
- /* skip leading white space */
- for (; isspace(*p); ++p);
+ /* bb_dump_skip leading white space */
+ p = bb_skip_whitespace(p);
if (!*p) {
break;
}
@@ -791,43 +701,41 @@ void add(char *fmt)
if (isdigit(*p)) {
for (savep = p; isdigit(*p); ++p);
if (!isspace(*p) && *p != '/') {
- error_msg_and_die("hexdump: bad format {%s}", fmt);
+ bb_error_msg_and_die("bad format {%s}", fmt);
}
/* may overwrite either white space or slash */
tfu->reps = atoi(savep);
tfu->flags = F_SETREP;
- /* skip trailing white space */
- for (++p; isspace(*p); ++p);
+ /* bb_dump_skip trailing white space */
+ p = bb_skip_whitespace(++p);
}
- /* skip slash and trailing white space */
+ /* bb_dump_skip slash and trailing white space */
if (*p == '/') {
- while (isspace(*++p));
+ p = bb_skip_whitespace(++p);
}
/* byte count */
if (isdigit(*p)) {
for (savep = p; isdigit(*p); ++p);
if (!isspace(*p)) {
- error_msg_and_die("hexdump: bad format {%s}", fmt);
+ bb_error_msg_and_die("bad format {%s}", fmt);
}
tfu->bcnt = atoi(savep);
- /* skip trailing white space */
- for (++p; isspace(*p); ++p);
+ /* bb_dump_skip trailing white space */
+ p = bb_skip_whitespace(++p);
}
/* format */
if (*p != '"') {
- error_msg_and_die("hexdump: bad format {%s}", fmt);
+ bb_error_msg_and_die("bad format {%s}", fmt);
}
for (savep = ++p; *p != '"';) {
if (*p++ == 0) {
- error_msg_and_die("hexdump: bad format {%s}", fmt);
+ bb_error_msg_and_die("bad format {%s}", fmt);
}
}
- if (!(tfu->fmt = malloc(p - savep + 1))) {
- perror_msg_and_die("hexdump");
- }
+ tfu->fmt = xmalloc(p - savep + 1);
strncpy(tfu->fmt, savep, p - savep);
tfu->fmt[p - savep] = '\0';
/* escape(tfu->fmt); */
@@ -841,33 +749,16 @@ void add(char *fmt)
break;
}
if (*p1 == '\\') {
- switch (*++p1) {
- case 'a':
- /* *p2 = '\a'; */
- *p2 = '\007';
- break;
- case 'b':
- *p2 = '\b';
- break;
- case 'f':
- *p2 = '\f';
- break;
- case 'n':
- *p2 = '\n';
- break;
- case 'r':
- *p2 = '\r';
- break;
- case 't':
- *p2 = '\t';
- break;
- case 'v':
- *p2 = '\v';
- break;
- default:
- *p2 = *p1;
- break;
- }
+ const char *cs = conv_str + 4;
+ ++p1;
+ *p2 = *p1;
+ do {
+ if (*p1 == cs[2]) {
+ *p2 = cs[0];
+ break;
+ }
+ cs += 4;
+ } while (*cs);
}
}
diff --git a/libbb/error_msg.c b/libbb/error_msg.c
index 58308b6be..5456dd361 100644
--- a/libbb/error_msg.c
+++ b/libbb/error_msg.c
@@ -25,12 +25,12 @@
#include <stdlib.h>
#include "libbb.h"
-extern void error_msg(const char *s, ...)
+extern void bb_error_msg(const char *s, ...)
{
va_list p;
va_start(p, s);
- verror_msg(s, p);
+ bb_verror_msg(s, p);
va_end(p);
putc('\n', stderr);
}
diff --git a/libbb/error_msg_and_die.c b/libbb/error_msg_and_die.c
index 67a79c375..7e7393773 100644
--- a/libbb/error_msg_and_die.c
+++ b/libbb/error_msg_and_die.c
@@ -25,15 +25,15 @@
#include <stdlib.h>
#include "libbb.h"
-extern void error_msg_and_die(const char *s, ...)
+extern void bb_error_msg_and_die(const char *s, ...)
{
va_list p;
va_start(p, s);
- verror_msg(s, p);
+ bb_verror_msg(s, p);
va_end(p);
putc('\n', stderr);
- exit(EXIT_FAILURE);
+ exit(bb_default_error_retval);
}
diff --git a/libbb/fclose_nonstdin.c b/libbb/fclose_nonstdin.c
new file mode 100644
index 000000000..97e303e9c
--- /dev/null
+++ b/libbb/fclose_nonstdin.c
@@ -0,0 +1,37 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * fclose_nonstdin implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* A number of standard utilites can accept multiple command line args
+ * of '-' for stdin, according to SUSv3. So we encapsulate the check
+ * here to save a little space.
+ */
+
+#include <stdio.h>
+#include <libbb.h>
+
+int bb_fclose_nonstdin(FILE *f)
+{
+ if (f != stdin) {
+ return fclose(f);
+ }
+ return 0;
+}
diff --git a/libbb/fflush_stdout_and_exit.c b/libbb/fflush_stdout_and_exit.c
new file mode 100644
index 000000000..cbba04207
--- /dev/null
+++ b/libbb/fflush_stdout_and_exit.c
@@ -0,0 +1,37 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * fflush_stdout_and_exit implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* Attempt to fflush(stdout), and exit with an error code if stdout is
+ * in an error state.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <libbb.h>
+
+void bb_fflush_stdout_and_exit(int retval)
+{
+ if (fflush(stdout)) {
+ retval = bb_default_error_retval;
+ }
+ exit(retval);
+}
diff --git a/libbb/find_root_device.c b/libbb/find_root_device.c
index 0a3f1bc77..763ac7519 100644
--- a/libbb/find_root_device.c
+++ b/libbb/find_root_device.c
@@ -38,14 +38,14 @@ extern char *find_real_root_device_name(const char* name)
dev_t dev;
if (stat("/", &rootStat) != 0)
- perror_msg("could not stat '/'");
+ bb_perror_msg("could not stat '/'");
else {
if ((dev = rootStat.st_rdev)==0)
dev=rootStat.st_dev;
dir = opendir("/dev");
if (!dir)
- perror_msg("could not open '/dev'");
+ bb_perror_msg("could not open '/dev'");
else {
while((entry = readdir(dir)) != NULL) {
@@ -69,7 +69,7 @@ extern char *find_real_root_device_name(const char* name)
}
}
if(fileName==NULL)
- fileName=xstrdup("/dev/root");
+ fileName=bb_xstrdup("/dev/root");
return fileName;
}
diff --git a/libbb/full_read.c b/libbb/full_read.c
index ccf26fc3d..e75f967db 100644
--- a/libbb/full_read.c
+++ b/libbb/full_read.c
@@ -23,17 +23,16 @@
#include <unistd.h>
#include "libbb.h"
-
/*
* Read all of the supplied buffer from a file.
* This does multiple reads as necessary.
* Returns the amount read, or -1 on an error.
* A short read is returned on an end of file.
*/
-int full_read(int fd, char *buf, int len)
+ssize_t bb_full_read(int fd, void *buf, size_t len)
{
- int cc;
- int total;
+ ssize_t cc;
+ ssize_t total;
total = 0;
@@ -41,12 +40,12 @@ int full_read(int fd, char *buf, int len)
cc = read(fd, buf, len);
if (cc < 0)
- return -1;
+ return cc; /* read() returns -1 on failure. */
if (cc == 0)
break;
- buf += cc;
+ buf = ((char *)buf) + cc;
total += cc;
len -= cc;
}
diff --git a/libbb/full_write.c b/libbb/full_write.c
index a2c07fbc9..1106a53b4 100644
--- a/libbb/full_write.c
+++ b/libbb/full_write.c
@@ -28,10 +28,10 @@
* This does multiple writes as necessary.
* Returns the amount written, or -1 on an error.
*/
-int full_write(int fd, const char *buf, int len)
+ssize_t bb_full_write(int fd, const void *buf, size_t len)
{
- int cc;
- int total;
+ ssize_t cc;
+ ssize_t total;
total = 0;
@@ -39,10 +39,10 @@ int full_write(int fd, const char *buf, int len)
cc = write(fd, buf, len);
if (cc < 0)
- return -1;
+ return cc; /* write() returns -1 on failure. */
- buf += cc;
total += cc;
+ buf = ((const char *)buf) + cc;
len -= cc;
}
diff --git a/libbb/get_console.c b/libbb/get_console.c
index 794888fa7..562b57703 100644
--- a/libbb/get_console.c
+++ b/libbb/get_console.c
@@ -106,7 +106,7 @@ int get_console_fd(void)
if (is_a_console(fd))
return fd;
- error_msg("Couldn't get a file descriptor referring to the console");
+ bb_error_msg("Couldn't get a file descriptor referring to the console");
return -1; /* total failure */
}
diff --git a/libbb/get_last_path_component.c b/libbb/get_last_path_component.c
index 6af726c83..497d6ae4e 100644
--- a/libbb/get_last_path_component.c
+++ b/libbb/get_last_path_component.c
@@ -1,8 +1,8 @@
/* vi: set sw=4 ts=4: */
/*
- * get_last_path_component implementation for busybox
+ * bb_get_last_path_component implementation for busybox
*
- * Copyright (C) 2001 Manuel Novoa III <mjn3@opensource.lineo.com>
+ * Copyright (C) 2001 Manuel Novoa III <mjn3@codepoet.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,7 +24,7 @@
/* WARNING!!! Doing so will break basename applet at least! */
#define EMULATE_BASENAME 0
-char *get_last_path_component(char *path)
+char *bb_get_last_path_component(char *path)
{
#if EMULATE_BASENAME
static const char null_or_empty[] = ".";
diff --git a/libbb/get_line_from_file.c b/libbb/get_line_from_file.c
index 5e7062127..5af898934 100644
--- a/libbb/get_line_from_file.c
+++ b/libbb/get_line_from_file.c
@@ -21,41 +21,57 @@
*/
#include <stdio.h>
+#include <stdlib.h>
#include "libbb.h"
-
-
-/* get_line_from_file() - This function reads an entire line from a text file
+/* get_line_from_file() - This function reads an entire line from a text file,
* up to a newline. It returns a malloc'ed char * which must be stored and
- * free'ed by the caller. */
-extern char *get_line_from_file(FILE *file)
+ * free'ed by the caller. If 'c' is nonzero, the trailing '\n' (if any)
+ * is removed. In event of a read error or EOF, NULL is returned. */
+
+static char *private_get_line_from_file(FILE *file, int c)
{
- static const int GROWBY = 80; /* how large we will grow strings by */
+#define GROWBY (80) /* how large we will grow strings by */
int ch;
int idx = 0;
char *linebuf = NULL;
int linebufsz = 0;
- while (1) {
- ch = fgetc(file);
- if (ch == EOF)
- break;
+ while ((ch = getc(file)) != EOF) {
/* grow the line buffer as necessary */
- while (idx > linebufsz-2)
+ if (idx > linebufsz-2) {
linebuf = xrealloc(linebuf, linebufsz += GROWBY);
+ }
linebuf[idx++] = (char)ch;
- if (ch == '\n' || ch == '\0')
+ if (ch == '\n' || ch == '\0') {
+ if (c) {
+ --idx;
+ }
break;
+ }
}
- if (idx == 0)
- return NULL;
-
- linebuf[idx] = 0;
+ if (linebuf) {
+ if (ferror(file)) {
+ free(linebuf);
+ return NULL;
+ }
+ linebuf[idx] = 0;
+ }
return linebuf;
}
+extern char *bb_get_line_from_file(FILE *file)
+{
+ return private_get_line_from_file(file, 0);
+}
+
+extern char *bb_get_chomped_line_from_file(FILE *file)
+{
+ return private_get_line_from_file(file, 1);
+}
+
/* END CODE */
/*
diff --git a/libbb/time_string.c b/libbb/getopt_ulflags.c
index d103a02f8..91de392b6 100644
--- a/libbb/time_string.c
+++ b/libbb/getopt_ulflags.c
@@ -1,8 +1,8 @@
/* vi: set sw=4 ts=4: */
/*
- * Utility routines.
+ * getopt_ulflags implementation for busybox
*
- * Copyright (C) 1999,2000,2001 by Erik Andersen <andersee@debian.org>
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,46 +17,25 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
*/
-#include <stdio.h>
+#include <getopt.h>
#include <string.h>
-#include <time.h>
-#include <utime.h>
#include "libbb.h"
-
-/*
- * Return the standard ls-like time string from a time_t
- * This is static and so is overwritten on each call.
- */
-const char *time_string(time_t timeVal)
+unsigned long bb_getopt_ulflags(int argc, char **argv, const char *applet_opts)
{
- time_t now;
- char *str;
- static char buf[26];
-
- time(&now);
-
- str = ctime(&timeVal);
-
- strcpy(buf, &str[4]);
- buf[12] = '\0';
-
- if ((timeVal > now) || (timeVal < now - 365 * 24 * 60 * 60L)) {
- strcpy(&buf[7], &str[20]);
- buf[11] = '\0';
+ unsigned long flags = 0;
+ const char *s;
+ int c;
+
+ while ((c = getopt(argc, argv, applet_opts)) > 0) {
+ if (!(s = strchr(applet_opts, c))) {
+ bb_show_usage();
+ }
+ flags |= (1 << (s-applet_opts));
}
- return buf;
+ return flags;
}
-
-
-/* END CODE */
-/*
-Local Variables:
-c-file-style: "linux"
-c-basic-offset: 4
-tab-width: 4
-End:
-*/
diff --git a/libbb/herror_msg.c b/libbb/herror_msg.c
index 1081a56b1..4fe921b29 100644
--- a/libbb/herror_msg.c
+++ b/libbb/herror_msg.c
@@ -24,12 +24,12 @@
#include "libbb.h"
-extern void herror_msg(const char *s, ...)
+extern void bb_herror_msg(const char *s, ...)
{
va_list p;
va_start(p, s);
- vherror_msg(s, p);
+ bb_vherror_msg(s, p);
va_end(p);
}
diff --git a/libbb/herror_msg_and_die.c b/libbb/herror_msg_and_die.c
index a47c7ff95..33a8c3e28 100644
--- a/libbb/herror_msg_and_die.c
+++ b/libbb/herror_msg_and_die.c
@@ -24,14 +24,14 @@
#include "libbb.h"
-extern void herror_msg_and_die(const char *s, ...)
+extern void bb_herror_msg_and_die(const char *s, ...)
{
va_list p;
va_start(p, s);
- vherror_msg(s, p);
+ bb_vherror_msg(s, p);
va_end(p);
- exit(EXIT_FAILURE);
+ exit(bb_default_error_retval);
}
diff --git a/libbb/inet_common.c b/libbb/inet_common.c
index 16dd1db7c..5e2343bdd 100644
--- a/libbb/inet_common.c
+++ b/libbb/inet_common.c
@@ -4,7 +4,7 @@
*
* Heavily modified by Manuel Novoa III Mar 12, 2001
*
- * Version: $Id: inet_common.c,v 1.5 2002/11/28 09:52:23 bug1 Exp $
+ * Version: $Id: inet_common.c,v 1.6 2003/03/19 09:12:07 mjn3 Exp $
*
*/
@@ -44,7 +44,7 @@ int INET_resolve(const char *name, struct sockaddr_in *s_in, int hostfirst)
/* If we expect this to be a hostname, try hostname database first */
#ifdef DEBUG
if (hostfirst) {
- error_msg("gethostbyname (%s)", name);
+ bb_error_msg("gethostbyname (%s)", name);
}
#endif
if (hostfirst && (hp = gethostbyname(name)) != (struct hostent *) NULL) {
@@ -54,7 +54,7 @@ int INET_resolve(const char *name, struct sockaddr_in *s_in, int hostfirst)
}
/* Try the NETWORKS database to see if this is a known network. */
#ifdef DEBUG
- error_msg("getnetbyname (%s)", name);
+ bb_error_msg("getnetbyname (%s)", name);
#endif
if ((np = getnetbyname(name)) != (struct netent *) NULL) {
s_in->sin_addr.s_addr = htonl(np->n_net);
@@ -71,7 +71,7 @@ int INET_resolve(const char *name, struct sockaddr_in *s_in, int hostfirst)
#endif
#ifdef DEBUG
- error_msg("gethostbyname (%s)", name);
+ bb_error_msg("gethostbyname (%s)", name);
#endif
if ((hp = gethostbyname(name)) == (struct hostent *) NULL) {
errno = h_errno;
@@ -109,7 +109,7 @@ int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in,
/* Grmpf. -FvK */
if (s_in->sin_family != AF_INET) {
#ifdef DEBUG
- error_msg("rresolve: unsupport address family %d !",
+ bb_error_msg("rresolve: unsupport address family %d !",
s_in->sin_family);
#endif
errno = EAFNOSUPPORT;
@@ -117,7 +117,7 @@ int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in,
}
ad = (unsigned long) s_in->sin_addr.s_addr;
#ifdef DEBUG
- error_msg("rresolve: %08lx, mask %08x, num %08x", ad, netmask, numeric);
+ bb_error_msg("rresolve: %08lx, mask %08x, num %08x", ad, netmask, numeric);
#endif
if (ad == INADDR_ANY) {
if ((numeric & 0x0FFF) == 0) {
@@ -143,7 +143,7 @@ int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in,
if (pn->addr.sin_addr.s_addr == ad && pn->host == host) {
safe_strncpy(name, pn->name, len);
#ifdef DEBUG
- error_msg("rresolve: found %s %08lx in cache",
+ bb_error_msg("rresolve: found %s %08lx in cache",
(host ? "host" : "net"), ad);
#endif
return (0);
@@ -156,7 +156,7 @@ int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in,
ent = NULL;
if (host) {
#ifdef DEBUG
- error_msg("gethostbyaddr (%08lx)", ad);
+ bb_error_msg("gethostbyaddr (%08lx)", ad);
#endif
ent = gethostbyaddr((char *) &ad, 4, AF_INET);
if (ent != NULL) {
@@ -164,7 +164,7 @@ int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in,
}
} else {
#ifdef DEBUG
- error_msg("getnetbyaddr (%08lx)", host_ad);
+ bb_error_msg("getnetbyaddr (%08lx)", host_ad);
#endif
np = getnetbyaddr(host_ad, AF_INET);
if (np != NULL) {
@@ -178,7 +178,7 @@ int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in,
pn->addr = *s_in;
pn->next = INET_nn;
pn->host = host;
- pn->name = xstrdup(name);
+ pn->name = bb_xstrdup(name);
INET_nn = pn;
return (0);
@@ -194,7 +194,7 @@ int INET6_resolve(char *name, struct sockaddr_in6 *sin6)
memset(&req, '\0', sizeof req);
req.ai_family = AF_INET6;
if ((s = getaddrinfo(name, NULL, &req, &ai))) {
- error_msg("getaddrinfo: %s: %d", name, s);
+ bb_error_msg("getaddrinfo: %s: %d", name, s);
return -1;
}
memcpy(sin6, ai->ai_addr, sizeof(struct sockaddr_in6));
@@ -219,7 +219,7 @@ int INET6_rresolve(char *name, size_t len, struct sockaddr_in6 *sin6,
/* Grmpf. -FvK */
if (sin6->sin6_family != AF_INET6) {
#ifdef DEBUG
- error_msg(_("rresolve: unsupport address family %d !\n"),
+ bb_error_msg(_("rresolve: unsupport address family %d !\n"),
sin6->sin6_family);
#endif
errno = EAFNOSUPPORT;
@@ -240,7 +240,7 @@ int INET6_rresolve(char *name, size_t len, struct sockaddr_in6 *sin6,
s = getnameinfo((struct sockaddr *) sin6, sizeof(struct sockaddr_in6), name, len, NULL, 0, 0);
if (s) {
- error_msg("getnameinfo failed");
+ bb_error_msg("getnameinfo failed");
return -1;
}
return (0);
diff --git a/libbb/interface.c b/libbb/interface.c
index fb794169d..531700f45 100644
--- a/libbb/interface.c
+++ b/libbb/interface.c
@@ -15,7 +15,7 @@
* that either displays or sets the characteristics of
* one or more of the system's networking interfaces.
*
- * Version: $Id: interface.c,v 1.14 2003/02/09 22:40:33 bug1 Exp $
+ * Version: $Id: interface.c,v 1.15 2003/03/19 09:12:07 mjn3 Exp $
*
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
* and others. Copyright 1993 MicroWalt Corporation
@@ -619,7 +619,7 @@ static int aftrans_opt(const char *arg)
if (strcmp(tmp1, paft->alias))
continue;
if (strlen(paft->name) + strlen(afname) + 1 >= sizeof(afname)) {
- error_msg(_("Too many address family arguments."));
+ bb_error_msg(_("Too many address family arguments."));
return (0);
}
if (paft->flag)
@@ -630,7 +630,7 @@ static int aftrans_opt(const char *arg)
break;
}
if (!paft->alias) {
- error_msg(_("Unknown address family `%s'."), tmp1);
+ bb_error_msg(_("Unknown address family `%s'."), tmp1);
return (1);
}
tmp1 = tmp2;
@@ -693,7 +693,7 @@ static struct aftype *get_aftype(const char *name)
afp++;
}
if (strchr(name, ','))
- error_msg(_("Please don't supply more than one address family."));
+ bb_error_msg(_("Please don't supply more than one address family."));
return (NULL);
}
#endif /* KEEP_UNUSED */
@@ -888,7 +888,7 @@ static int sockets_open(int family)
sfd = af->fd;
}
if (sfd < 0) {
- error_msg(_("No usable address families found."));
+ bb_error_msg(_("No usable address families found."));
}
return sfd;
}
@@ -960,7 +960,7 @@ static int if_readconf(void)
(as of 2.1.128) */
skfd2 = get_socket_for_af(AF_INET);
if (skfd2 < 0) {
- perror_msg(("warning: no inet socket available"));
+ bb_perror_msg(("warning: no inet socket available"));
/* Try to soldier on with whatever socket we can get hold of. */
skfd2 = sockets_open(0);
if (skfd2 < 0)
@@ -1106,7 +1106,7 @@ static int if_readlist_proc(char *target)
fh = fopen(_PATH_PROCNET_DEV, "r");
if (!fh) {
- perror_msg(_("Warning: cannot open %s. Limited output."), _PATH_PROCNET_DEV);
+ bb_perror_msg(_("Warning: cannot open %s. Limited output."), _PATH_PROCNET_DEV);
return if_readconf();
}
fgets(buf, sizeof buf, fh); /* eat line */
@@ -1366,7 +1366,7 @@ static int do_if_fetch(struct interface *ife)
} else {
errmsg = strerror(errno);
}
- error_msg(_("%s: error fetching interface information: %s\n"),
+ bb_error_msg(_("%s: error fetching interface information: %s\n"),
ife->name, errmsg);
return -1;
}
@@ -1441,7 +1441,7 @@ static int in_ether(char *bufp, struct sockaddr *sap)
val = c - 'A' + 10;
else {
#ifdef DEBUG
- error_msg(_("in_ether(%s): invalid ether address!\n"), orig);
+ bb_error_msg(_("in_ether(%s): invalid ether address!\n"), orig);
#endif
errno = EINVAL;
return (-1);
@@ -1458,7 +1458,7 @@ static int in_ether(char *bufp, struct sockaddr *sap)
val >>= 4;
else {
#ifdef DEBUG
- error_msg(_("in_ether(%s): invalid ether address!"), orig);
+ bb_error_msg(_("in_ether(%s): invalid ether address!"), orig);
#endif
errno = EINVAL;
return (-1);
@@ -1472,7 +1472,7 @@ static int in_ether(char *bufp, struct sockaddr *sap)
if (*bufp == ':') {
#ifdef DEBUG
if (i == ETH_ALEN) {
- error_msg(_("in_ether(%s): trailing : ignored!"), orig);
+ bb_error_msg(_("in_ether(%s): trailing : ignored!"), orig);
}
#endif
bufp++;
@@ -1482,11 +1482,11 @@ static int in_ether(char *bufp, struct sockaddr *sap)
#ifdef DEBUG
/* That's it. Any trailing junk? */
if ((i == ETH_ALEN) && (*bufp != '\0')) {
- error_msg(_("in_ether(%s): trailing junk!"), orig);
+ bb_error_msg(_("in_ether(%s): trailing junk!"), orig);
errno = EINVAL;
return (-1);
}
- error_msg("in_ether(%s): %s", orig, pr_ether(sap->sa_data));
+ bb_error_msg("in_ether(%s): %s", orig, pr_ether(sap->sa_data));
#endif
return (0);
@@ -1511,7 +1511,7 @@ static struct hwtype ether_hwtype = {
/* Start the PPP encapsulation on the file descriptor. */
static int do_ppp(int fd)
{
- error_msg(_("You cannot start PPP with this program."));
+ bb_error_msg(_("You cannot start PPP with this program."));
return -1;
}
#endif /* KEEP_UNUSED */
@@ -2052,7 +2052,7 @@ int display_interfaces(char *ifname)
/* Create a channel to the NET kernel. */
if ((skfd = sockets_open(0)) < 0) {
- perror_msg_and_die("socket");
+ bb_perror_msg_and_die("socket");
}
/* Do we have to show the current setup? */
diff --git a/libbb/kernel_version.c b/libbb/kernel_version.c
index 694af8e2c..14b163654 100644
--- a/libbb/kernel_version.c
+++ b/libbb/kernel_version.c
@@ -37,7 +37,7 @@ extern int get_kernel_revision(void)
int i, r;
if (uname(&name) == -1) {
- perror_msg("cannot get system information");
+ bb_perror_msg("cannot get system information");
return (0);
}
diff --git a/libbb/loop.c b/libbb/loop.c
index 7e58b2f85..29128abe4 100644
--- a/libbb/loop.c
+++ b/libbb/loop.c
@@ -33,11 +33,11 @@ extern int del_loop(const char *device)
int fd;
if ((fd = open(device, O_RDONLY)) < 0) {
- perror_msg("%s", device);
+ bb_perror_msg("%s", device);
return (FALSE);
}
if (ioctl(fd, LOOP_CLR_FD, 0) < 0) {
- perror_msg("ioctl: LOOP_CLR_FD");
+ bb_perror_msg("ioctl: LOOP_CLR_FD");
return (FALSE);
}
close(fd);
@@ -53,12 +53,12 @@ extern int set_loop(const char *device, const char *file, int offset,
mode = *loopro ? O_RDONLY : O_RDWR;
if ((ffd = open(file, mode)) < 0 && !*loopro
&& (errno != EROFS || (ffd = open(file, mode = O_RDONLY)) < 0)) {
- perror_msg("%s", file);
+ bb_perror_msg("%s", file);
return 1;
}
if ((fd = open(device, mode)) < 0) {
close(ffd);
- perror_msg("%s", device);
+ bb_perror_msg("%s", device);
return 1;
}
*loopro = (mode == O_RDONLY);
@@ -70,14 +70,14 @@ extern int set_loop(const char *device, const char *file, int offset,
loopinfo.lo_encrypt_key_size = 0;
if (ioctl(fd, LOOP_SET_FD, ffd) < 0) {
- perror_msg("ioctl: LOOP_SET_FD");
+ bb_perror_msg("ioctl: LOOP_SET_FD");
close(fd);
close(ffd);
return 1;
}
if (ioctl(fd, LOOP_SET_STATUS, &loopinfo) < 0) {
(void) ioctl(fd, LOOP_CLR_FD, 0);
- perror_msg("ioctl: LOOP_SET_STATUS");
+ bb_perror_msg("ioctl: LOOP_SET_STATUS");
close(fd);
close(ffd);
return 1;
diff --git a/libbb/make_directory.c b/libbb/make_directory.c
index 65be397bf..e3d2c52b1 100644
--- a/libbb/make_directory.c
+++ b/libbb/make_directory.c
@@ -1,12 +1,8 @@
/* vi: set sw=4 ts=4: */
/*
- * Mini make_directory implementation for busybox
+ * parse_mode implementation for busybox
*
- * Copyright (C) 2001 Matt Kraai.
- *
- * Rewriten in 2002
- * Copyright (C) 2002 Glenn McGrath
- * Copyright (C) 2002 Vladimir N. Oleynik
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,57 +20,87 @@
*
*/
+/* Mar 5, 2003 Manuel Novoa III
+ *
+ * This is the main work function for the 'mkdir' applet. As such, it
+ * strives to be SUSv3 compliant in it's behaviour when recursively
+ * making missing parent dirs, and in it's mode setting of the final
+ * directory 'path'.
+ *
+ * To recursively build all missing intermediate directories, make
+ * sure that (flags & FILEUTILS_RECUR) is non-zero. Newly created
+ * intermediate directories will have at least u+wx perms.
+ *
+ * To set specific permisions on 'path', pass the appropriate 'mode'
+ * val. Otherwise, pass -1 to get default permisions.
+ */
+
#include <errno.h>
-#include <fcntl.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
#include <unistd.h>
-#include <stdlib.h>
-
#include "libbb.h"
-/* Create the directory PATH with mode MODE, or the default if MODE is -1.
- * Also create parent directories as necessary if flags contains
- * FILEUTILS_RECUR. */
-
-int make_directory (char *path, long mode, int flags)
+int bb_make_directory (char *path, long mode, int flags)
{
- int ret;
-
- if (flags == FILEUTILS_RECUR) {
- char *pp = strrchr(path, '/');
- if ((pp) && (pp != path)) {
- *pp = '\0';
- make_directory(path, -1, flags);
- *pp = '/';
- }
- }
+ mode_t mask;
+ const char *fail_msg;
+ char *s = path;
+ char c;
- if (mode == -1) {
- struct stat statbuf;
- char *pp = strrchr(path, '/');
+ mask = umask(0);
+ umask(mask & ~0300);
- statbuf.st_mode = 0777;
+ do {
+ c = 0;
- /* stat the directory */
- if ((pp) && (pp != path)) {
- *pp = '\0';
- stat(path, &statbuf);
- *pp = '/';
+ if (flags & FILEUTILS_RECUR) { /* Get the parent. */
+ /* Bypass leading non-'/'s and then subsequent '/'s. */
+ while (*s) {
+ if (*s == '/') {
+ do {
+ ++s;
+ } while (*s == '/');
+ c = *s; /* Save the current char */
+ *s = 0; /* and replace it with nul. */
+ break;
+ }
+ ++s;
+ }
}
- mode = statbuf.st_mode;
- }
+ if (mkdir(path, 0777) < 0) {
+ /* If we failed for any other reason than the directory
+ * already exists, output a diagnostic and return -1.*/
+ if (errno != EEXIST) {
+ fail_msg = "create";
+ umask(mask);
+ break;
+ }
+ /* Since the directory exists, don't attempt to change
+ * permissions if it was the full target. Note that
+ * this is not an error conditon. */
+ if (!c) {
+ umask(mask);
+ return 0;
+ }
+ }
- ret = mkdir(path, mode);
- if (ret == -1) {
- if ((flags == FILEUTILS_RECUR) && (errno == EEXIST)) {
- ret = 0;
- } else {
- perror_msg_and_die("Cannot create directory '%s'", path);
+ if (!c) {
+ /* Done. If necessary, updated perms on the newly
+ * created directory. Failure to update here _is_
+ * an error.*/
+ umask(mask);
+ if ((mode != -1) && (chmod(path, mode) < 0)){
+ fail_msg = "set permissions of";
+ break;
+ }
+ return 0;
}
- }
- return(ret);
+ /* Remove any inserted nul from the path (recursive mode). */
+ *s = c;
+
+ } while (1);
+
+ bb_perror_msg ("Cannot %s directory `%s'", fail_msg, path);
+ return -1;
}
diff --git a/libbb/messages.c b/libbb/messages.c
index cc7e2146c..e5ffbf7f7 100644
--- a/libbb/messages.c
+++ b/libbb/messages.c
@@ -23,82 +23,71 @@
#include "libbb.h"
#ifdef L_full_version
- const char * const full_version = BB_BANNER " multi-call binary";
-#endif
-#ifdef L_name_too_long
- const char * const name_too_long = "file name too long";
-#endif
-
-#ifdef L_omitting_directory
- const char * const omitting_directory = "%s: omitting directory";
-#endif
-#ifdef L_not_a_directory
- const char * const not_a_directory = "%s: not a directory";
+ const char * const bb_msg_full_version = BB_BANNER " multi-call binary";
#endif
#ifdef L_memory_exhausted
- const char * const memory_exhausted = "memory exhausted";
+ const char * const bb_msg_memory_exhausted = "memory exhausted";
#endif
#ifdef L_invalid_date
- const char * const invalid_date = "invalid date `%s'";
-#endif
-#ifdef L_invalid_option
- const char * const invalid_option = "invalid option -- %c";
+ const char * const bb_msg_invalid_date = "invalid date `%s'";
#endif
#ifdef L_io_error
- const char * const io_error = "%s: input/output error -- %m";
-#endif
-#ifdef L_dash_dash_help
- const char * const dash_dash_help = "--help";
+ const char * const bb_msg_io_error = "%s: input/output error -- %m";
#endif
#ifdef L_write_error
- const char * const write_error = "Write Error";
-#endif
-#ifdef L_too_few_args
- const char * const too_few_args = "too few arguments";
+ const char * const bb_msg_write_error = "Write Error";
#endif
#ifdef L_name_longer_than_foo
- const char * const name_longer_than_foo = "Names longer than %d chars not supported.";
+ const char * const bb_msg_name_longer_than_foo = "Names longer than %d chars not supported.";
#endif
#ifdef L_unknown
- const char * const unknown = "(unknown)";
+ const char * const bb_msg_unknown = "(unknown)";
#endif
-
#ifdef L_can_not_create_raw_socket
- const char * const can_not_create_raw_socket = "can`t create raw socket";
+ const char * const bb_msg_can_not_create_raw_socket = "can`t create raw socket";
+#endif
+#ifdef L_perm_denied_are_you_root
+ const char * const bb_msg_perm_denied_are_you_root = "permission denied. (are you root?)";
+#endif
+#ifdef L_msg_standard_input
+ const char * const bb_msg_standard_input = "standard input";
+#endif
+#ifdef L_msg_standard_output
+ const char * const bb_msg_standard_output = "standard output";
#endif
#ifdef L_passwd_file
#define PASSWD_FILE "/etc/passwd"
-const char * const passwd_file = PASSWD_FILE;
+const char * const bb_path_passwd_file = PASSWD_FILE;
#endif
#ifdef L_shadow_file
#define SHADOW_FILE "/etc/shadow"
-const char * const shadow_file = SHADOW_FILE;
+const char * const bb_path_shadow_file = SHADOW_FILE;
#endif
#ifdef L_group_file
#define GROUP_FILE "/etc/group"
-const char * const group_file = GROUP_FILE;
+const char * const bb_path_group_file = GROUP_FILE;
#endif
#ifdef L_gshadow_file
#define GSHADOW_FILE "/etc/gshadow"
-const char * const gshadow_file = GSHADOW_FILE;
+const char * const bb_path_gshadow_file = GSHADOW_FILE;
#endif
#ifdef L_nologin_file
#define NOLOGIN_FILE "/etc/nologin"
-const char * const nologin_file = NOLOGIN_FILE;
+const char * const bb_path_nologin_file = NOLOGIN_FILE;
#endif
#ifdef L_securetty_file
#define SECURETTY_FILE "/etc/securetty"
-const char * const securetty_file = SECURETTY_FILE;
+const char * const bb_path_securetty_file = SECURETTY_FILE;
#endif
#ifdef L_motd_file
#define MOTD_FILE "/etc/motd"
-const char * const motd_file = MOTD_FILE;
+const char * const bb_path_motd_file = MOTD_FILE;
#endif
diff --git a/libbb/mode_string.c b/libbb/mode_string.c
index 12dc17966..8d4d736ef 100644
--- a/libbb/mode_string.c
+++ b/libbb/mode_string.c
@@ -1,78 +1,134 @@
/* vi: set sw=4 ts=4: */
/*
- * Utility routines.
+ * mode_string implementation for busybox
*
- * Copyright (C) many different people. If you wrote this, please
- * acknowledge your work.
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
*/
-#include <stdio.h>
-#include "libbb.h"
+#include <assert.h>
+#include <sys/stat.h>
+#if ( S_ISUID != 04000 ) || ( S_ISGID != 02000 ) || ( S_ISVTX != 01000 ) \
+ || ( S_IRUSR != 00400 ) || ( S_IWUSR != 00200 ) || ( S_IXUSR != 00100 ) \
+ || ( S_IRGRP != 00040 ) || ( S_IWGRP != 00020 ) || ( S_IXGRP != 00010 ) \
+ || ( S_IROTH != 00004 ) || ( S_IWOTH != 00002 ) || ( S_IXOTH != 00001 )
+#error permission bitflag value assumption(s) violated!
+#endif
+#if ( S_IFSOCK!= 0140000 ) || ( S_IFLNK != 0120000 ) \
+ || ( S_IFREG != 0100000 ) || ( S_IFBLK != 0060000 ) \
+ || ( S_IFDIR != 0040000 ) || ( S_IFCHR != 0020000 ) \
+ || ( S_IFIFO != 0010000 )
+#warning mode type bitflag value assumption(s) violated! falling back to larger version
-#define TYPEINDEX(mode) (((mode) >> 12) & 0x0f)
-#define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)])
+#if (S_IRWXU | S_IRWXG | S_IRWXO | S_ISUID | S_ISGID | S_ISVTX) == 07777
+#undef mode_t
+#define mode_t unsigned short
+#endif
-/* The special bits. If set, display SMODE0/1 instead of MODE0/1 */
-static const mode_t SBIT[] = {
- 0, 0, S_ISUID,
- 0, 0, S_ISGID,
- 0, 0, S_ISVTX
+static const mode_t mode_flags[] = {
+ S_IRUSR, S_IWUSR, S_IXUSR, S_ISUID,
+ S_IRGRP, S_IWGRP, S_IXGRP, S_ISGID,
+ S_IROTH, S_IWOTH, S_IXOTH, S_ISVTX
};
-/* The 9 mode bits to test */
-static const mode_t MBIT[] = {
- S_IRUSR, S_IWUSR, S_IXUSR,
- S_IRGRP, S_IWGRP, S_IXGRP,
- S_IROTH, S_IWOTH, S_IXOTH
-};
+/* The static const char arrays below are duplicated for the two cases
+ * because moving them ahead of the mode_flags declaration cause a text
+ * size increase with the gcc version I'm using. */
-static const char MODE1[] = "rwxrwxrwx";
-static const char MODE0[] = "---------";
-static const char SMODE1[] = "..s..s..t";
-static const char SMODE0[] = "..S..S..T";
+/* The previous version used "0pcCd?bB-?l?s???". However, the '0', 'C',
+ * and 'B' types don't appear to be available on linux. So I removed them. */
+static const char type_chars[16] = "?pc?d?b?-?l?s???";
+/* 0123456789abcdef */
+static const char mode_chars[7] = "rwxSTst";
-/*
- * Return the standard ls-like mode string from a file mode.
- * This is static and so is overwritten on each call.
- */
-const char *mode_string(int mode)
+const char *bb_mode_string(int mode)
{
static char buf[12];
+ char *p = buf;
+
+ int i, j, k;
- int i;
+ *p = type_chars[ (mode >> 12) & 0xf ];
+ i = 0;
+ do {
+ j = k = 0;
+ do {
+ *++p = '-';
+ if (mode & mode_flags[i+j]) {
+ *p = mode_chars[j];
+ k = j;
+ }
+ } while (++j < 3);
+ if (mode & mode_flags[i+j]) {
+ *p = mode_chars[3 + (k & 2) + ((i&8) >> 3)];
+ }
+ i += 4;
+ } while (i < 12);
+
+ /* Note: We don't bother with nul termination because bss initialization
+ * should have taken care of that for us. If the user scribbled in buf
+ * memory, they deserve whatever happens. But we'll at least assert. */
+ assert(buf[10] == 0);
- buf[0] = TYPECHAR(mode);
- for (i = 0; i < 9; i++) {
- if (mode & SBIT[i])
- buf[i + 1] = (mode & MBIT[i]) ? SMODE1[i] : SMODE0[i];
- else
- buf[i + 1] = (mode & MBIT[i]) ? MODE1[i] : MODE0[i];
- }
return buf;
}
-/* END CODE */
-/*
-Local Variables:
-c-file-style: "linux"
-c-basic-offset: 4
-tab-width: 4
-End:
-*/
+#else
+
+/* The previous version used "0pcCd?bB-?l?s???". However, the '0', 'C',
+ * and 'B' types don't appear to be available on linux. So I removed them. */
+static const char type_chars[16] = "?pc?d?b?-?l?s???";
+/* 0123456789abcdef */
+static const char mode_chars[7] = "rwxSTst";
+
+const char *bb_mode_string(int mode)
+{
+ static char buf[12];
+ char *p = buf;
+
+ int i, j, k, m;
+
+ *p = type_chars[ (mode >> 12) & 0xf ];
+ i = 0;
+ m = 0400;
+ do {
+ j = k = 0;
+ do {
+ *++p = '-';
+ if (mode & m) {
+ *p = mode_chars[j];
+ k = j;
+ }
+ m >>= 1;
+ } while (++j < 3);
+ ++i;
+ if (mode & (010000 >> i)) {
+ *p = mode_chars[3 + k + (i >> 1)];
+ }
+ } while (i < 3);
+
+ /* Note: We don't bother with nul termination because bss initialization
+ * should have taken care of that for us. If the user scribbled in buf
+ * memory, they deserve whatever happens. But we'll at least assert. */
+ assert(buf[10] == 0);
+
+ return buf;
+}
+
+#endif
diff --git a/libbb/module_syscalls.c b/libbb/module_syscalls.c
index 6bfff207f..8fe9e525c 100644
--- a/libbb/module_syscalls.c
+++ b/libbb/module_syscalls.c
@@ -51,7 +51,7 @@ _syscall5(int, init_module, void *, first, void *, second, void *, third,
#warning -> The query_module system call is being stubbed out...
int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret)
{
- error_msg("\n\nTo make this application work, you will need to recompile\n"
+ bb_error_msg("\n\nTo make this application work, you will need to recompile\n"
"with a kernel supporting the query_module system call. -Erik\n");
errno=ENOSYS;
return -1;
diff --git a/libbb/mtab.c b/libbb/mtab.c
index c521b1e05..54905c724 100644
--- a/libbb/mtab.c
+++ b/libbb/mtab.c
@@ -27,21 +27,20 @@
#include <mntent.h>
#include "libbb.h"
-extern const char mtab_file[]; /* Defined in utility.c */
static const int MS_RDONLY = 1; /* Mount read-only. */
void erase_mtab(const char *name)
{
struct mntent entries[20];
int count = 0;
- FILE *mountTable = setmntent(mtab_file, "r");
+ FILE *mountTable = setmntent(bb_path_mtab_file, "r");
struct mntent *m;
/* Check if reading the mtab file failed */
if (mountTable == 0
/* Bummer. fall back on trying the /proc filesystem */
&& (mountTable = setmntent("/proc/mounts", "r")) == 0) {
- perror_msg("%s", mtab_file);
+ bb_perror_msg(bb_path_mtab_file);
return;
}
@@ -55,7 +54,7 @@ void erase_mtab(const char *name)
count++;
}
endmntent(mountTable);
- if ((mountTable = setmntent(mtab_file, "w"))) {
+ if ((mountTable = setmntent(bb_path_mtab_file, "w"))) {
int i;
for (i = 0; i < count; i++) {
@@ -69,17 +68,17 @@ void erase_mtab(const char *name)
}
endmntent(mountTable);
} else if (errno != EROFS)
- perror_msg("%s", mtab_file);
+ bb_perror_msg(bb_path_mtab_file);
}
void write_mtab(char *blockDevice, char *directory,
char *filesystemType, long flags, char *string_flags)
{
- FILE *mountTable = setmntent(mtab_file, "a+");
+ FILE *mountTable = setmntent(bb_path_mtab_file, "a+");
struct mntent m;
if (mountTable == 0) {
- perror_msg("%s", mtab_file);
+ bb_perror_msg(bb_path_mtab_file);
return;
}
if (mountTable) {
diff --git a/libbb/mtab_file.c b/libbb/mtab_file.c
index 2124e0144..898e2fa89 100644
--- a/libbb/mtab_file.c
+++ b/libbb/mtab_file.c
@@ -26,9 +26,9 @@
/* Busybox mount uses either /proc/mounts or /etc/mtab to
* get the list of currently mounted filesystems */
#if defined CONFIG_FEATURE_MTAB_SUPPORT
-const char mtab_file[] = CONFIG_FEATURE_MTAB_FILENAME;
+const char bb_path_mtab_file[] = CONFIG_FEATURE_MTAB_FILENAME;
#else
-const char mtab_file[] = "/proc/mounts";
+const char bb_path_mtab_file[] = "/proc/mounts";
#endif
diff --git a/libbb/my_getgrnam.c b/libbb/my_getgrnam.c
index f80d3f824..eb5b58174 100644
--- a/libbb/my_getgrnam.c
+++ b/libbb/my_getgrnam.c
@@ -33,7 +33,7 @@ long my_getgrnam(const char *name)
mygroup = getgrnam(name);
if (mygroup==NULL)
- error_msg_and_die("unknown group name: %s", name);
+ bb_error_msg_and_die("unknown group name: %s", name);
return (mygroup->gr_gid);
}
diff --git a/libbb/my_getpwnam.c b/libbb/my_getpwnam.c
index 04951a4d0..ada2ffb56 100644
--- a/libbb/my_getpwnam.c
+++ b/libbb/my_getpwnam.c
@@ -33,7 +33,7 @@ long my_getpwnam(const char *name)
myuser = getpwnam(name);
if (myuser==NULL)
- error_msg_and_die("unknown user name: %s", name);
+ bb_error_msg_and_die("unknown user name: %s", name);
return myuser->pw_uid;
}
diff --git a/libbb/my_getpwnamegid.c b/libbb/my_getpwnamegid.c
index 07e02c1cf..06071c9f2 100644
--- a/libbb/my_getpwnamegid.c
+++ b/libbb/my_getpwnamegid.c
@@ -35,11 +35,11 @@ long my_getpwnamegid(const char *name)
myuser=getpwnam(name);
if (myuser==NULL)
- error_msg_and_die("unknown user name: %s", name);
+ bb_error_msg_and_die("unknown user name: %s", name);
mygroup = getgrgid(myuser->pw_gid);
if (mygroup==NULL)
- error_msg_and_die("unknown gid %ld", (long)myuser->pw_gid);
+ bb_error_msg_and_die("unknown gid %ld", (long)myuser->pw_gid);
return mygroup->gr_gid;
}
diff --git a/libbb/obscure.c b/libbb/obscure.c
index 588ef5af6..1a99b7cf9 100644
--- a/libbb/obscure.c
+++ b/libbb/obscure.c
@@ -143,7 +143,7 @@ password_check(const char *old, const char *newval, const struct passwd *pwdp)
return "too simple";
msg = NULL;
- newmono = str_lower(xstrdup(newval));
+ newmono = str_lower(bb_xstrdup(newval));
lenwrap = strlen(old) * 2 + 1;
wrapped = (char *) xmalloc(lenwrap);
str_lower(strcpy(wrapped, old));
@@ -208,8 +208,8 @@ obscure_msg(const char *old, const char *newval, const struct passwd *pwdp)
if (oldlen <= maxlen && newlen <= maxlen)
return NULL;
- new1 = (char *) xstrdup(newval);
- old1 = (char *) xstrdup(old);
+ new1 = (char *) bb_xstrdup(newval);
+ old1 = (char *) bb_xstrdup(old);
if (newlen > maxlen)
new1[maxlen] = '\0';
if (oldlen > maxlen)
diff --git a/libbb/parse_mode.c b/libbb/parse_mode.c
index ba34ea929..49573dfbb 100644
--- a/libbb/parse_mode.c
+++ b/libbb/parse_mode.c
@@ -1,134 +1,177 @@
/* vi: set sw=4 ts=4: */
/*
- * Utility routines.
+ * parse_mode implementation for busybox
*
- * Copyright (C) many different people. If you wrote this, please
- * acknowledge your work.
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
*/
-#include <stdio.h>
+/* http://www.opengroup.org/onlinepubs/007904975/utilities/chmod.html */
+
#include <stdlib.h>
+#include <assert.h>
+#include <sys/stat.h>
#include "libbb.h"
+#define FILEMODEBITS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
-/* This function parses the sort of string you might pass
- * to chmod (i.e., [ugoa]{+|-|=}[rwxst] ) and returns the
- * correct mode described by the string. */
-extern int parse_mode(const char *s, mode_t * theMode)
+extern int bb_parse_mode(const char *s, mode_t *current_mode)
{
- static const mode_t group_set[] = {
+ static const mode_t who_mask[] = {
+ S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO, /* a */
S_ISUID | S_IRWXU, /* u */
S_ISGID | S_IRWXG, /* g */
- S_IRWXO, /* o */
- S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO /* a */
+ S_IRWXO /* o */
};
- static const mode_t mode_set[] = {
+ static const mode_t perm_mask[] = {
S_IRUSR | S_IRGRP | S_IROTH, /* r */
S_IWUSR | S_IWGRP | S_IWOTH, /* w */
S_IXUSR | S_IXGRP | S_IXOTH, /* x */
+ S_IXUSR | S_IXGRP | S_IXOTH, /* X -- special -- see below */
S_ISUID | S_ISGID, /* s */
S_ISVTX /* t */
};
- static const char group_chars[] = "ugoa";
- static const char mode_chars[] = "rwxst";
+ static const char who_chars[] = "augo";
+ static const char perm_chars[] = "rwxXst";
const char *p;
- mode_t andMode =
- S_ISVTX | S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO;
- mode_t orMode = 0;
- mode_t mode;
- mode_t groups;
- char type;
- char c;
+ mode_t wholist;
+ mode_t permlist;
+ mode_t mask;
+ mode_t new_mode;
+ char op;
+
+ assert(s);
+
+ if (((unsigned int)(*s - '0')) < 8) {
+ unsigned long tmp;
+ char *e;
- if (s==NULL) {
- return (FALSE);
+ tmp = strtol(s, &e, 8);
+ if (*e || (tmp > 0xffffU)) { /* Check range and trailing chars. */
+ return 0;
+ }
+ *current_mode = tmp;
+ return 1;
}
- do {
- mode = 0;
- groups = 0;
- NEXT_GROUP:
- if ((c = *s++) == '\0') {
- return -1;
+ mask = umask(0);
+ umask(mask);
+
+ new_mode = *current_mode;
+
+ /* Note: We allow empty clauses, and hence empty modes.
+ * We treat an empty mode as no change to perms. */
+
+ while (*s) { /* Process clauses. */
+
+ if (*s == ',') { /* We allow empty clauses. */
+ ++s;
+ continue;
}
- for (p=group_chars ; *p ; p++) {
- if (*p == c) {
- groups |= group_set[(int)(p-group_chars)];
- goto NEXT_GROUP;
+
+ /* Get a wholist. */
+ wholist = 0;
+
+ WHO_LIST:
+ p = who_chars;
+ do {
+ if (*p == *s) {
+ wholist |= who_mask[(int)(p-who_chars)];
+ if (!*++s) {
+ return 0;
+ }
+ goto WHO_LIST;
}
- }
- switch (c) {
- case '=':
- case '+':
- case '-':
- type = c;
- if (groups == 0) { /* The default is "all" */
- groups |= S_ISUID | S_ISGID | S_ISVTX
- | S_IRWXU | S_IRWXG | S_IRWXO;
+ } while (*++p);
+
+ do { /* Process action list. */
+ if ((*s != '+') && (*s != '-')) {
+ if (*s != '=') {
+ return 0;
}
- break;
- default:
- if ((c < '0') || (c > '7') || (mode | groups)) {
- return (FALSE);
- } else {
- *theMode = strtol(--s, NULL, 8);
- return (TRUE);
+ /* Since op is '=', clear all bits corresponding to the
+ * wholist, of all file bits if wholist is empty. */
+ permlist = ~FILEMODEBITS;
+ if (wholist) {
+ permlist = ~wholist;
}
- }
+ new_mode &= permlist;
+ }
+ op = *s++;
+
+ /* Check for permcopy. */
+ p = who_chars + 1; /* Skip 'a' entry. */
+ do {
+ if (*p == *s) {
+ int i = 0;
+ permlist = who_mask[(int)(p-who_chars)]
+ & (S_IRWXU | S_IRWXG | S_IRWXO)
+ & new_mode;
+ do {
+ if (permlist & perm_mask[i]) {
+ permlist |= perm_mask[i];
+ }
+ } while (++i < 3);
+ ++s;
+ goto GOT_ACTION;
+ }
+ } while (*++p);
- NEXT_MODE:
- if (((c = *s++) != '\0') && (c != ',')) {
- for (p=mode_chars ; *p ; p++) {
- if (*p == c) {
- mode |= mode_set[(int)(p-mode_chars)];
- goto NEXT_MODE;
+ /* It was not a permcopy, so get a permlist. */
+ permlist = 0;
+
+ PERM_LIST:
+ p = perm_chars;
+ do {
+ if (*p == *s) {
+ if ((*p != 'X')
+ || (new_mode & (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH))
+ ) {
+ permlist |= perm_mask[(int)(p-perm_chars)];
+ }
+ if (!*++s) {
+ break;
+ }
+ goto PERM_LIST;
+ }
+ } while (*++p);
+
+ GOT_ACTION:
+ if (permlist) { /* The permlist was nonempty. */
+ mode_t tmp = ~mask;
+ if (wholist) {
+ tmp = wholist;
+ }
+ permlist &= tmp;
+
+ if (op == '-') {
+ new_mode &= ~permlist;
+ } else {
+ new_mode |= permlist;
}
}
- break; /* We're done so break out of loop.*/
- }
- switch (type) {
- case '=':
- andMode &= ~(groups); /* Now fall through. */
- case '+':
- orMode |= mode & groups;
- break;
- case '-':
- andMode &= ~(mode & groups);
- orMode &= ~(mode & groups);
- break;
- }
- } while (c == ',');
+ } while (*s && (*s != ','));
+ }
- *theMode &= andMode;
- *theMode |= orMode;
+ *current_mode = new_mode;
- return TRUE;
+ return 1;
}
-
-/* END CODE */
-/*
-Local Variables:
-c-file-style: "linux"
-c-basic-offset: 4
-tab-width: 4
-End:
-*/
diff --git a/libbb/parse_number.c b/libbb/parse_number.c
index 755a357ad..92ad6a216 100644
--- a/libbb/parse_number.c
+++ b/libbb/parse_number.c
@@ -1,70 +1,64 @@
/* vi: set sw=4 ts=4: */
/*
- * Utility routines.
+ * bb_xparse_number implementation for busybox
*
- * Copyright (C) many different people. If you wrote this, please
- * acknowledge your work.
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
- * USA
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
*/
-#include <stdio.h>
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <errno.h>
+#include <assert.h>
#include "libbb.h"
-
-unsigned long parse_number(const char *numstr,
- const struct suffix_mult *suffixes)
+extern
+unsigned long bb_xparse_number(const char *numstr,
+ const struct suffix_mult *suffixes)
{
- const struct suffix_mult *sm;
- unsigned long int ret;
- int len;
- char *end;
+ unsigned long int r;
+ char *e;
+ int old_errno;
- ret = strtoul(numstr, &end, 10);
- if (numstr == end)
- error_msg_and_die("invalid number `%s'", numstr);
- while (end[0] != '\0') {
- sm = suffixes;
- while ( sm != 0 ) {
- if(sm->suffix) {
- len = strlen(sm->suffix);
- if (strncmp(sm->suffix, end, len) == 0) {
- ret *= sm->mult;
- end += len;
- break;
+ /* Since this is a lib function, we're not allowed to reset errno to 0.
+ * Doing so could break an app that is deferring checking of errno.
+ * So, save the old value so that we can restore it if successful. */
+ old_errno = errno;
+ errno = 0;
+ r = strtoul(numstr, &e, 10);
+
+ if ((numstr != e) && !errno) {
+ errno = old_errno; /* Ok. So restore errno. */
+ if (!*e) {
+ return r;
+ }
+ if (suffixes) {
+ assert(suffixes->suffix); /* No nul suffixes. */
+ do {
+ if (strcmp(suffixes->suffix, e) == 0) {
+ if (ULONG_MAX / suffixes->mult < r) { /* Overflow! */
+ break;
+ }
+ return r * suffixes->mult;
}
- sm++;
-
- } else
- sm = 0;
+ ++suffixes;
+ } while (suffixes->suffix);
}
- if (sm == 0)
- error_msg_and_die("invalid number `%s'", numstr);
}
- return ret;
+ bb_error_msg_and_die("invalid number `%s'", numstr);
}
-
-
-/* END CODE */
-/*
-Local Variables:
-c-file-style: "linux"
-c-basic-offset: 4
-tab-width: 4
-End:
-*/
diff --git a/libbb/perror_msg.c b/libbb/perror_msg.c
index 8c57b0d16..f32c1c8fe 100644
--- a/libbb/perror_msg.c
+++ b/libbb/perror_msg.c
@@ -25,12 +25,12 @@
#include <stdlib.h>
#include "libbb.h"
-extern void perror_msg(const char *s, ...)
+extern void bb_perror_msg(const char *s, ...)
{
va_list p;
va_start(p, s);
- vperror_msg(s, p);
+ bb_vperror_msg(s, p);
va_end(p);
}
diff --git a/libbb/perror_msg_and_die.c b/libbb/perror_msg_and_die.c
index 9004925cc..57a21136d 100644
--- a/libbb/perror_msg_and_die.c
+++ b/libbb/perror_msg_and_die.c
@@ -25,14 +25,14 @@
#include <stdlib.h>
#include "libbb.h"
-extern void perror_msg_and_die(const char *s, ...)
+extern void bb_perror_msg_and_die(const char *s, ...)
{
va_list p;
va_start(p, s);
- vperror_msg(s, p);
+ bb_vperror_msg(s, p);
va_end(p);
- exit(EXIT_FAILURE);
+ exit(bb_default_error_retval);
}
diff --git a/libbb/perror_nomsg.c b/libbb/perror_nomsg.c
new file mode 100644
index 000000000..464cb86c4
--- /dev/null
+++ b/libbb/perror_nomsg.c
@@ -0,0 +1,30 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * bb_perror_nomsg implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stddef.h>
+#include <libbb.h>
+
+extern void bb_perror_nomsg(void)
+{
+ /* Ignore the gcc warning about a null format string. */
+ bb_perror_msg(NULL);
+}
diff --git a/libbb/perror_nomsg_and_die.c b/libbb/perror_nomsg_and_die.c
new file mode 100644
index 000000000..bab228455
--- /dev/null
+++ b/libbb/perror_nomsg_and_die.c
@@ -0,0 +1,30 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * bb_perror_nomsg_and_die implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stddef.h>
+#include "libbb.h"
+
+extern void bb_perror_nomsg_and_die(void)
+{
+ /* Ignore the gcc warning about a null format string. */
+ bb_perror_msg_and_die(NULL);
+}
diff --git a/libbb/print_file.c b/libbb/print_file.c
index cdd60e7a0..8417c10d3 100644
--- a/libbb/print_file.c
+++ b/libbb/print_file.c
@@ -21,39 +21,50 @@
#include <stdio.h>
#include <stdlib.h>
-#include <sys/stat.h>
#include "libbb.h"
-
-extern void print_file(FILE *file)
+extern void bb_xprint_and_close_file(FILE *file)
{
- fflush(stdout);
- if (copyfd(fileno(file), fileno(stdout), 0) == -1) {
- exit(EXIT_FAILURE);
+ bb_xfflush_stdout();
+ /* Note: Do not use STDOUT_FILENO here, as this is a lib routine
+ * and the calling code may have reassigned stdout. */
+ if (bb_copyfd(fileno(file), fileno(stdout), 0) == -1) {
+ /* bb_copyfd outputs any needed messages, so just die. */
+ exit(bb_default_error_retval);
}
+ /* Note: Since we're reading, don't bother checking the return value
+ * of fclose(). The only possible failure is EINTR which
+ * should already have been taken care of. */
fclose(file);
}
-extern int print_file_by_name(char *filename)
+/* Returns:
+ * 0 if successful
+ * -1 if 'filename' does not exist or is a directory
+ * exits with default error code if an error occurs
+ */
+
+extern int bb_xprint_file_by_name(const char *filename)
{
+ FILE *f;
+
+#if 0
+ /* This check shouldn't be necessary for linux, but is left
+ * here disabled just in case. */
struct stat statBuf;
- int status = TRUE;
- if(is_directory(filename, TRUE, &statBuf)==TRUE) {
- error_msg("%s: Is directory", filename);
- status = FALSE;
- } else {
- FILE *f = wfopen(filename, "r");
- if(f!=NULL)
- print_file(f);
- else
- status = FALSE;
+ if(is_directory(filename, TRUE, &statBuf)) {
+ bb_error_msg("%s: Is directory", filename);
+ } else
+#endif
+ if ((f = bb_wfopen(filename, "r")) != NULL) {
+ bb_xprint_and_close_file(f);
+ return 0;
}
- return status;
+ return -1;
}
-
/* END CODE */
/*
Local Variables:
diff --git a/libbb/printf.c b/libbb/printf.c
new file mode 100644
index 000000000..686257699
--- /dev/null
+++ b/libbb/printf.c
@@ -0,0 +1,177 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * *printf implementations for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* Mar 12, 2003 Manuel Novoa III
+ *
+ * While fwrite(), fputc(), fputs(), etc. all set the stream error flag
+ * on failure, the *printf functions are unique in that they can fail
+ * for reasons not related to the actual output itself. Among the possible
+ * reasons for failure which don't set the streams error indicator,
+ * SUSv3 lists EILSEQ, EINVAL, and ENOMEM.
+ *
+ * In some cases, it would be desireable to have a group of *printf()
+ * functions available that _always_ set the stream error indicator on
+ * failure. That would allow us to defer error checking until applet
+ * exit. Unfortunately, there is no standard way of setting a streams
+ * error indicator... even though we can clear it with clearerr().
+ *
+ * Therefore, we have to resort to implementation dependent code. Feel
+ * free to send patches for stdio implementations where the following
+ * fails.
+ *
+ * NOTE: None of this is threadsafe. As busybox is a nonthreaded app,
+ * that isn't currently an issue.
+ */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include "libbb.h"
+
+#if defined(__UCLIBC__)
+
+# if defined(__FLAG_ERROR)
+/* Using my newer stdio implementation. Unlocked macros are:
+ * #define __CLEARERR(stream) \
+ ((stream)->modeflags &= ~(__FLAG_EOF|__FLAG_ERROR), (void)0)
+ * #define __FEOF(stream) ((stream)->modeflags & __FLAG_EOF)
+ * #define __FERROR(stream) ((stream)->modeflags & __FLAG_ERROR)
+ */
+#define SET_FERROR_UNLOCKED(S) ((S)->modeflags |= __FLAG_ERROR)
+
+#elif defined(__MODE_ERR)
+/* Using either the original stdio implementation (from dev86) or
+ * my original stdio rewrite. Macros were:
+ * #define ferror(fp) (((fp)->mode&__MODE_ERR) != 0)
+ * #define feof(fp) (((fp)->mode&__MODE_EOF) != 0)
+ * #define clearerr(fp) ((fp)->mode &= ~(__MODE_EOF|__MODE_ERR),0)
+ */
+#define SET_FERROR_UNLOCKED(S) ((S)->mode |= __MODE_ERR)
+
+#else
+#error unknown uClibc stdio implemenation!
+#endif
+
+#elif defined(__GLIBC__)
+
+# if defined(_STDIO_USES_IOSTREAM)
+/* Apparently using the newer libio implementation, with associated defines:
+ * #define _IO_feof_unlocked(__fp) (((__fp)->_flags & _IO_EOF_SEEN) != 0)
+ * #define _IO_ferror_unlocked(__fp) (((__fp)->_flags & _IO_ERR_SEEN) != 0)
+ */
+#define SET_FERROR_UNLOCKED(S) ((S)->_flags |= _IO_ERR_SEEN)
+
+# else
+/* Assume the older version of glibc which used a bitfield entry
+ * as a stream error flag. The associated defines were:
+ * #define __clearerr(stream) ((stream)->__error = (stream)->__eof = 0)
+ * #define feof_unlocked(stream) ((stream)->__eof != 0)
+ * #define ferror_unlocked(stream) ((stream)->__error != 0)
+ */
+#define SET_FERROR_UNLOCKED(S) ((S)->__error = 1)
+
+# endif
+
+#elif defined(__NEWLIB_H__)
+/* I honestly don't know if there are different versions of stdio in
+ * newlibs history. Anyway, here's what's current.
+ * #define __sfeof(p) (((p)->_flags & __SEOF) != 0)
+ * #define __sferror(p) (((p)->_flags & __SERR) != 0)
+ * #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF)))
+ */
+#define SET_FERROR_UNLOCKED(S) ((S)->_flags |= __SERR)
+
+#elif defined(__dietlibc__)
+/*
+ * WARNING!!! dietlibc is quite buggy. WARNING!!!
+ *
+ * Some example bugs as of March 12, 2003...
+ * 1) fputc() doesn't set the error indicator on failure.
+ * 2) freopen() doesn't maintain the same stream object, contary to
+ * standards. This makes it useless in its primary role of
+ * reassociating stdin/stdout/stderr.
+ * 3) printf() often fails to correctly format output when conversions
+ * involve padding. It is also practically useless for floating
+ * point output.
+ *
+ * But, if you're determined to use it anyway, (as of the current version)
+ * you can extract the information you need from dietstdio.h. See the
+ * other library implementations for examples.
+ */
+#error dietlibc is currently not supported. Please see the commented source.
+
+#else /* some other lib */
+/* Please see the comments for the above supported libaries for examples
+ * of what is required to support your stdio implementation.
+ */
+#error Your stdio library is currently not supported. Please see the commented source.
+#endif
+
+#ifdef L_vfprintf
+extern int bb_vfprintf(FILE * __restrict stream,
+ const char * __restrict format,
+ va_list arg)
+{
+ int rv;
+
+ if ((rv = vfprintf(stream, format, arg)) < 0) {
+ SET_FERROR_UNLOCKED(stream);
+ }
+
+ return rv;
+}
+#endif
+
+#ifdef L_vprintf
+extern int bb_vprintf(const char * __restrict format, va_list arg)
+{
+ return bb_vfprintf(stdout, format, arg);
+}
+#endif
+
+#ifdef L_fprintf
+extern int bb_fprintf(FILE * __restrict stream,
+ const char * __restrict format, ...)
+{
+ va_list arg;
+ int rv;
+
+ va_start(arg, format);
+ rv = bb_vfprintf(stream, format, arg);
+ va_end(arg);
+
+ return rv;
+}
+#endif
+
+#ifdef L_printf
+extern int bb_printf(const char * __restrict format, ...)
+{
+ va_list arg;
+ int rv;
+
+ va_start(arg, format);
+ rv = bb_vfprintf(stdout, format, arg);
+ va_end(arg);
+
+ return rv;
+}
+#endif
diff --git a/libbb/process_escape_sequence.c b/libbb/process_escape_sequence.c
index 9a16f80ab..ef2717bdd 100644
--- a/libbb/process_escape_sequence.c
+++ b/libbb/process_escape_sequence.c
@@ -2,7 +2,7 @@
/*
* Utility routines.
*
- * Copyright (C) Manuel Nova III <mnovoa3@bellsouth.net>
+ * Copyright (C) Manuel Novoa III <mjn3@codepoet.org>
* and Vladimir Oleynik <dzo@simtreas.ru>
*
* This program is free software; you can redistribute it and/or modify
@@ -26,9 +26,7 @@
#include <limits.h>
#include "libbb.h"
-
-
-char process_escape_sequence(const char **ptr)
+char bb_process_escape_sequence(const char **ptr)
{
static const char charmap[] = {
'a', 'b', 'f', 'n', 'r', 't', 'v', '\\', 0,
@@ -36,40 +34,43 @@ char process_escape_sequence(const char **ptr)
const char *p;
const char *q;
- int num_digits;
+ unsigned int num_digits;
+ unsigned int r;
unsigned int n;
n = 0;
q = *ptr;
- for ( num_digits = 0 ; num_digits < 3 ; ++num_digits) {
- if ((*q < '0') || (*q > '7')) { /* not a digit? */
- break;
+ num_digits = 0;
+ do {
+ if (((unsigned int)(*q - '0')) <= 7) {
+ r = n * 8 + (*q - '0');
+ if (r <= UCHAR_MAX) {
+ n = r;
+ ++q;
+ if (++num_digits < 3) {
+ continue;
+ }
+ }
}
- n = n * 8 + (*q++ - '0');
- }
+ break;
+ } while (1);
if (num_digits == 0) { /* mnemonic escape sequence? */
- for (p=charmap ; *p ; p++) {
+ p = charmap;
+ do {
if (*p == *q) {
q++;
break;
}
- }
+ } while (*++p);
n = *(p+(sizeof(charmap)/2));
}
- /* doesn't hurt to fall through to here from mnemonic case */
- if (n > UCHAR_MAX) { /* is octal code too big for a char? */
- n /= 8; /* adjust value and */
- --q; /* back up one char */
- }
-
*ptr = q;
return (char) n;
}
-
/* END CODE */
/*
Local Variables:
diff --git a/libbb/procps.c b/libbb/procps.c
index fcc9c2d3a..a513f3f7f 100644
--- a/libbb/procps.c
+++ b/libbb/procps.c
@@ -34,7 +34,7 @@ extern procps_status_t * procps_scan(int save_user_arg0)
if (!dir) {
dir = opendir("/proc");
if(!dir)
- error_msg_and_die("Can't open /proc");
+ bb_error_msg_and_die("Can't open /proc");
}
for(;;) {
if((entry = readdir(dir)) == NULL) {
diff --git a/libbb/read_package_field.c b/libbb/read_package_field.c
index 867b198ba..42628f35c 100644
--- a/libbb/read_package_field.c
+++ b/libbb/read_package_field.c
@@ -102,10 +102,10 @@ int read_package_field(const char *package_buffer, char **field_name, char **fie
if (name_length == 0) {
*field_name = NULL;
} else {
- *field_name = xstrndup(&package_buffer[offset_name_start], name_length);
+ *field_name = bb_xstrndup(&package_buffer[offset_name_start], name_length);
}
if (value_length > 0) {
- *field_value = xstrndup(&package_buffer[offset_value_start], value_length);
+ *field_value = bb_xstrndup(&package_buffer[offset_value_start], value_length);
} else {
*field_value = NULL;
}
diff --git a/libbb/recursive_action.c b/libbb/recursive_action.c
index 8f9cc2f91..a4a4a7be3 100644
--- a/libbb/recursive_action.c
+++ b/libbb/recursive_action.c
@@ -60,10 +60,10 @@ int recursive_action(const char *fileName,
if (status < 0) {
#ifdef DEBUG_RECURS_ACTION
- error_msg("status=%d followLinks=%d TRUE=%d",
+ bb_error_msg("status=%d followLinks=%d TRUE=%d",
status, followLinks, TRUE);
#endif
- perror_msg("%s", fileName);
+ bb_perror_msg("%s", fileName);
return FALSE;
}
@@ -89,14 +89,14 @@ int recursive_action(const char *fileName,
if (dirAction != NULL && ! depthFirst) {
status = dirAction(fileName, &statbuf, userData);
if (! status) {
- perror_msg("%s", fileName);
+ bb_perror_msg("%s", fileName);
return FALSE;
} else if (status == SKIP)
return TRUE;
}
dir = opendir(fileName);
if (!dir) {
- perror_msg("%s", fileName);
+ bb_perror_msg("%s", fileName);
return FALSE;
}
status = TRUE;
@@ -117,7 +117,7 @@ int recursive_action(const char *fileName,
closedir(dir);
if (dirAction != NULL && depthFirst) {
if (! dirAction(fileName, &statbuf, userData)) {
- perror_msg("%s", fileName);
+ bb_perror_msg("%s", fileName);
return FALSE;
}
}
diff --git a/libbb/remove_file.c b/libbb/remove_file.c
index 988b09124..65708a252 100644
--- a/libbb/remove_file.c
+++ b/libbb/remove_file.c
@@ -37,7 +37,7 @@ extern int remove_file(const char *path, int flags)
if (lstat(path, &path_stat) < 0) {
if (errno != ENOENT) {
- perror_msg("unable to stat `%s'", path);
+ bb_perror_msg("unable to stat `%s'", path);
return -1;
}
@@ -46,7 +46,7 @@ extern int remove_file(const char *path, int flags)
if (!path_exists) {
if (!(flags & FILEUTILS_FORCE)) {
- perror_msg("cannot remove `%s'", path);
+ bb_perror_msg("cannot remove `%s'", path);
return -1;
}
return 0;
@@ -58,21 +58,21 @@ extern int remove_file(const char *path, int flags)
int status = 0;
if (!(flags & FILEUTILS_RECUR)) {
- error_msg("%s: is a directory", path);
+ bb_error_msg("%s: is a directory", path);
return -1;
}
if ((!(flags & FILEUTILS_FORCE) && access(path, W_OK) < 0 &&
isatty(0)) ||
(flags & FILEUTILS_INTERACTIVE)) {
- fprintf(stderr, "%s: descend into directory `%s'? ", applet_name,
+ fprintf(stderr, "%s: descend into directory `%s'? ", bb_applet_name,
path);
- if (!ask_confirmation())
+ if (!bb_ask_confirmation())
return 0;
}
if ((dp = opendir(path)) == NULL) {
- perror_msg("unable to open `%s'", path);
+ bb_perror_msg("unable to open `%s'", path);
return -1;
}
@@ -90,18 +90,18 @@ extern int remove_file(const char *path, int flags)
}
if (closedir(dp) < 0) {
- perror_msg("unable to close `%s'", path);
+ bb_perror_msg("unable to close `%s'", path);
return -1;
}
if (flags & FILEUTILS_INTERACTIVE) {
- fprintf(stderr, "%s: remove directory `%s'? ", applet_name, path);
- if (!ask_confirmation())
+ fprintf(stderr, "%s: remove directory `%s'? ", bb_applet_name, path);
+ if (!bb_ask_confirmation())
return status;
}
if (rmdir(path) < 0) {
- perror_msg("unable to remove `%s'", path);
+ bb_perror_msg("unable to remove `%s'", path);
return -1;
}
@@ -111,13 +111,13 @@ extern int remove_file(const char *path, int flags)
!S_ISLNK(path_stat.st_mode) &&
isatty(0)) ||
(flags & FILEUTILS_INTERACTIVE)) {
- fprintf(stderr, "%s: remove `%s'? ", applet_name, path);
- if (!ask_confirmation())
+ fprintf(stderr, "%s: remove `%s'? ", bb_applet_name, path);
+ if (!bb_ask_confirmation())
return 0;
}
if (unlink(path) < 0) {
- perror_msg("unable to remove `%s'", path);
+ bb_perror_msg("unable to remove `%s'", path);
return -1;
}
diff --git a/libbb/run_parts.c b/libbb/run_parts.c
index 7829a84ba..58645660b 100644
--- a/libbb/run_parts.c
+++ b/libbb/run_parts.c
@@ -69,7 +69,7 @@ extern int run_parts(char **args, const unsigned char test_mode)
if (test_mode & 2) {
return(2);
}
- perror_msg_and_die("failed to open directory %s", arg0);
+ bb_perror_msg_and_die("failed to open directory %s", arg0);
}
for (i = 0; i < entries; i++) {
@@ -77,7 +77,7 @@ extern int run_parts(char **args, const unsigned char test_mode)
filename = concat_path_file(arg0, namelist[i]->d_name);
if (stat(filename, &st) < 0) {
- perror_msg_and_die("failed to stat component %s", filename);
+ bb_perror_msg_and_die("failed to stat component %s", filename);
}
if (S_ISREG(st.st_mode) && !access(filename, X_OK)) {
if (test_mode & 1) {
@@ -89,7 +89,7 @@ extern int run_parts(char **args, const unsigned char test_mode)
int pid;
if ((pid = vfork()) < 0) {
- perror_msg_and_die("failed to fork");
+ bb_perror_msg_and_die("failed to fork");
} else if (!pid) {
args[0] = filename;
execv(filename, args);
@@ -100,19 +100,19 @@ extern int run_parts(char **args, const unsigned char test_mode)
waitpid(pid, &result, 0);
if(exec_errno) {
errno = exec_errno;
- perror_msg_and_die("failed to exec %s", filename);
+ bb_perror_msg_and_die("failed to exec %s", filename);
}
if (WIFEXITED(result) && WEXITSTATUS(result)) {
- perror_msg("%s exited with return code %d", filename, WEXITSTATUS(result));
+ bb_perror_msg("%s exited with return code %d", filename, WEXITSTATUS(result));
exitstatus = 1;
} else if (WIFSIGNALED(result)) {
- perror_msg("%s exited because of uncaught signal %d", filename, WTERMSIG(result));
+ bb_perror_msg("%s exited because of uncaught signal %d", filename, WTERMSIG(result));
exitstatus = 1;
}
}
}
else if (!S_ISDIR(st.st_mode)) {
- error_msg("component %s is not an executable plain file", filename);
+ bb_error_msg("component %s is not an executable plain file", filename);
exitstatus = 1;
}
diff --git a/libbb/run_shell.c b/libbb/run_shell.c
index b26eba115..d154b9852 100644
--- a/libbb/run_shell.c
+++ b/libbb/run_shell.c
@@ -57,11 +57,11 @@ void run_shell ( const char *shell, int loginshell, const char *command, const c
else
args = (const char **) xmalloc (sizeof (char *) * 4 );
- args [0] = get_last_path_component ( xstrdup ( shell ));
+ args [0] = bb_get_last_path_component ( bb_xstrdup ( shell ));
if ( loginshell ) {
char *args0;
- bb_asprintf ( &args0, "-%s", args [0] );
+ bb_xasprintf ( &args0, "-%s", args [0] );
args [0] = args0;
}
@@ -75,6 +75,6 @@ void run_shell ( const char *shell, int loginshell, const char *command, const c
}
args [argno] = 0;
execv ( shell, (char **) args );
- perror_msg_and_die ( "cannot run %s", shell );
+ bb_perror_msg_and_die ( "cannot run %s", shell );
}
diff --git a/libbb/setup_environment.c b/libbb/setup_environment.c
index dc171fa1f..30d317cea 100644
--- a/libbb/setup_environment.c
+++ b/libbb/setup_environment.c
@@ -45,7 +45,7 @@
static void xsetenv ( const char *key, const char *value )
{
if ( setenv ( key, value, 1 ))
- error_msg_and_die ( "out of memory" );
+ bb_error_msg_and_die ( "out of memory" );
}
void setup_environment ( const char *shell, int loginshell, int changeenv, const struct passwd *pw )
@@ -62,7 +62,7 @@ void setup_environment ( const char *shell, int loginshell, int changeenv, const
if ( chdir ( pw-> pw_dir )) {
if ( chdir ( "/" )) {
syslog ( LOG_WARNING, "unable to cd to %s' for user %s'\n", pw-> pw_dir, pw-> pw_name );
- error_msg_and_die ( "cannot cd to home directory or /" );
+ bb_error_msg_and_die ( "cannot cd to home directory or /" );
}
fputs ( "warning: cannot change to home directory\n", stderr );
}
diff --git a/libbb/simplify_path.c b/libbb/simplify_path.c
index 7b2a1ca51..743133cd1 100644
--- a/libbb/simplify_path.c
+++ b/libbb/simplify_path.c
@@ -1,8 +1,8 @@
/* vi: set sw=4 ts=4: */
/*
- * simplify_path implementation for busybox
+ * bb_simplify_path implementation for busybox
*
- * Copyright (C) 2001 Manuel Novoa III <mjn3@opensource.lineo.com>
+ * Copyright (C) 2001 Manuel Novoa III <mjn3@codepoet.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -21,15 +21,14 @@
*/
#include <stdlib.h>
-
#include "libbb.h"
-char *simplify_path(const char *path)
+char *bb_simplify_path(const char *path)
{
char *s, *start, *p;
if (path[0] == '/')
- start = xstrdup(path);
+ start = bb_xstrdup(path);
else {
s = xgetcwd(NULL);
start = concat_path_file(s, path);
diff --git a/libbb/skip_whitespace.c b/libbb/skip_whitespace.c
new file mode 100644
index 000000000..bf049a2d2
--- /dev/null
+++ b/libbb/skip_whitespace.c
@@ -0,0 +1,33 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * skip_whitespace implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <ctype.h>
+#include "libbb.h"
+
+extern const char *bb_skip_whitespace(const char *s)
+{
+ while (isspace(*s)) {
+ ++s;
+ }
+
+ return s;
+}
diff --git a/libbb/speed_table.c b/libbb/speed_table.c
new file mode 100644
index 000000000..b04429e91
--- /dev/null
+++ b/libbb/speed_table.c
@@ -0,0 +1,130 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * compact speed_t <-> speed functions for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <termios.h>
+#include "libbb.h"
+
+struct speed_map {
+ unsigned short speed;
+ unsigned short value;
+};
+
+static const struct speed_map speeds[] = {
+ {B0, 0},
+ {B50, 50},
+ {B75, 75},
+ {B110, 110},
+ {B134, 134},
+ {B150, 150},
+ {B200, 200},
+ {B300, 300},
+ {B600, 600},
+ {B1200, 1200},
+ {B1800, 1800},
+ {B2400, 2400},
+ {B4800, 4800},
+ {B9600, 9600},
+#ifdef B19200
+ {B19200, 19200},
+#elif defined(EXTA)
+ {EXTA, 19200},
+#endif
+#ifdef B38400
+ {B38400, 38400/256 + 0x8000U},
+#elif defined(EXTB)
+ {EXTB, 38400/256 + 0x8000U},
+#endif
+#ifdef B57600
+ {B57600, 57600/256 + 0x8000U},
+#endif
+#ifdef B115200
+ {B115200, 115200/256 + 0x8000U},
+#endif
+#ifdef B230400
+ {B230400, 230400/256 + 0x8000U},
+#endif
+#ifdef B460800
+ {B460800, 460800/256 + 0x8000U},
+#endif
+};
+
+static const int NUM_SPEEDS = (sizeof(speeds) / sizeof(struct speed_map));
+
+unsigned long bb_baud_to_value(speed_t speed)
+{
+ int i = 0;
+
+ do {
+ if (speed == speeds[i].speed) {
+ if (speeds[i].value & 0x8000U) {
+ return ((unsigned long) (speeds[i].value) & 0x7fffU) * 256;
+ }
+ return speeds[i].value;
+ }
+ } while (++i < NUM_SPEEDS);
+
+ return 0;
+}
+
+speed_t bb_value_to_baud(unsigned long value)
+{
+ int i = 0;
+
+ do {
+ if (value == bb_baud_to_value(speeds[i].speed)) {
+ return speeds[i].speed;
+ }
+ } while (++i < NUM_SPEEDS);
+
+ return (speed_t) - 1;
+}
+
+#if 0
+/* testing code */
+#include <stdio.h>
+
+int main(void)
+{
+ unsigned long v;
+ speed_t s;
+
+ for (v = 0 ; v < 500000 ; v++) {
+ s = bb_value_to_baud(v);
+ if (s == (speed_t) -1) {
+ continue;
+ }
+ printf("v = %lu -- s = %0lo\n", v, (unsigned long) s);
+ }
+
+ printf("-------------------------------\n");
+
+ for (s = 0 ; s < 010017+1 ; s++) {
+ v = bb_baud_to_value(s);
+ if (!v) {
+ continue;
+ }
+ printf("v = %lu -- s = %0lo\n", v, (unsigned long) s);
+ }
+
+ return 0;
+}
+#endif
diff --git a/libbb/syscalls.c b/libbb/syscalls.c
index 91e97b178..8d8c689f1 100644
--- a/libbb/syscalls.c
+++ b/libbb/syscalls.c
@@ -53,7 +53,7 @@ int pivot_root(const char * new_root,const char * put_old)
* you will need to recompile with a kernel supporting the
* pivot_root system call.
*/
- error_msg("\n\nTo make this application work, you will need to recompile\n"
+ bb_error_msg("\n\nTo make this application work, you will need to recompile\n"
"with a kernel supporting the pivot_root system call. -Erik\n");
errno=ENOSYS;
return -1;
@@ -91,7 +91,7 @@ int umount2(const char * special_file, int flags)
* you will need to recompile with a kernel supporting the
* umount2 system call.
*/
- error_msg("\n\nTo make this application work, you will need to recompile\n"
+ bb_error_msg("\n\nTo make this application work, you will need to recompile\n"
"with a kernel supporting the umount2 system call. -Erik\n");
errno=ENOSYS;
return -1;
diff --git a/libbb/syslog_msg_with_name.c b/libbb/syslog_msg_with_name.c
index 6474da459..bd3f44824 100644
--- a/libbb/syslog_msg_with_name.c
+++ b/libbb/syslog_msg_with_name.c
@@ -32,7 +32,7 @@ void syslog_msg_with_name(const char *name, int facility, int pri, const char *m
void syslog_msg(int facility, int pri, const char *msg)
{
- syslog_msg_with_name(applet_name, facility, pri, msg);
+ syslog_msg_with_name(bb_applet_name, facility, pri, msg);
}
/* END CODE */
diff --git a/libbb/verror_msg.c b/libbb/verror_msg.c
index 21cde2047..4612bf378 100644
--- a/libbb/verror_msg.c
+++ b/libbb/verror_msg.c
@@ -25,10 +25,10 @@
#include <stdlib.h>
#include "libbb.h"
-extern void verror_msg(const char *s, va_list p)
+extern void bb_verror_msg(const char *s, va_list p)
{
fflush(stdout);
- fprintf(stderr, "%s: ", applet_name);
+ fprintf(stderr, "%s: ", bb_applet_name);
vfprintf(stderr, s, p);
}
diff --git a/libbb/vherror_msg.c b/libbb/vherror_msg.c
index 67db17fe4..eb341bf84 100644
--- a/libbb/vherror_msg.c
+++ b/libbb/vherror_msg.c
@@ -26,11 +26,11 @@
#include "libbb.h"
-extern void vherror_msg(const char *s, va_list p)
+extern void bb_vherror_msg(const char *s, va_list p)
{
if(s == 0)
s = "";
- verror_msg(s, p);
+ bb_verror_msg(s, p);
if (*s)
fputs(": ", stderr);
herror("");
diff --git a/libbb/vperror_msg.c b/libbb/vperror_msg.c
index 7da5bae0a..febe4e22e 100644
--- a/libbb/vperror_msg.c
+++ b/libbb/vperror_msg.c
@@ -25,11 +25,11 @@
#include <stdlib.h>
#include "libbb.h"
-extern void vperror_msg(const char *s, va_list p)
+extern void bb_vperror_msg(const char *s, va_list p)
{
int err=errno;
if(s == 0) s = "";
- verror_msg(s, p);
+ bb_verror_msg(s, p);
if (*s) s = ": ";
fprintf(stderr, "%s%s\n", s, strerror(err));
}
diff --git a/libbb/warn_ignoring_args.c b/libbb/warn_ignoring_args.c
new file mode 100644
index 000000000..223831fd1
--- /dev/null
+++ b/libbb/warn_ignoring_args.c
@@ -0,0 +1,30 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * warn_ingoring_args implementations for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <libbb.h>
+
+extern void bb_warn_ignoring_args(int n)
+{
+ if (n) {
+ bb_perror_msg("ignoring all arguments");
+ }
+}
diff --git a/libbb/wfopen.c b/libbb/wfopen.c
index f58ec90c0..22f22b373 100644
--- a/libbb/wfopen.c
+++ b/libbb/wfopen.c
@@ -23,11 +23,11 @@
#include <errno.h>
#include "libbb.h"
-FILE *wfopen(const char *path, const char *mode)
+FILE *bb_wfopen(const char *path, const char *mode)
{
FILE *fp;
if ((fp = fopen(path, mode)) == NULL) {
- perror_msg("%s", path);
+ bb_perror_msg("%s", path);
errno = 0;
}
return fp;
diff --git a/libbb/wfopen_input.c b/libbb/wfopen_input.c
new file mode 100644
index 000000000..bff6606b5
--- /dev/null
+++ b/libbb/wfopen_input.c
@@ -0,0 +1,54 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * wfopen_input implementation for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* A number of applets need to open a file for reading, where the filename
+ * is a command line arg. Since often that arg is '-' (meaning stdin),
+ * we avoid testing everywhere by consolidating things in this routine.
+ *
+ * Note: We also consider "" to main stdin (for 'cmp' at least).
+ */
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <libbb.h>
+
+FILE *bb_wfopen_input(const char *filename)
+{
+ FILE *fp = stdin;
+
+ if ((filename != bb_msg_standard_input)
+ && filename[0] && ((filename[0] != '-') || filename[1])
+ ) {
+#if 0
+ /* This check shouldn't be necessary for linux, but is left
+ * here disabled just in case. */
+ struct stat stat_buf;
+ if (is_directory(filename, 1, &stat_buf)) {
+ bb_error_msg("%s: Is a directory", filename);
+ return NULL;
+ }
+#endif
+ fp = bb_wfopen(filename, "r");
+ }
+
+ return fp;
+}
diff --git a/libbb/xconnect.c b/libbb/xconnect.c
index bc6505a40..2945d760f 100644
--- a/libbb/xconnect.c
+++ b/libbb/xconnect.c
@@ -30,7 +30,7 @@ int xconnect(const char *host, const char *port)
hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo(host, port, &hints, &res);
if (error||!res)
- perror_msg_and_die(gai_strerror(error));
+ bb_perror_msg_and_die(gai_strerror(error));
addr_info=res;
while (res) {
s=socket(res->ai_family, res->ai_socktype, res->ai_protocol);
@@ -50,7 +50,7 @@ int xconnect(const char *host, const char *port)
freeaddrinfo(addr_info);
if (error < 0)
{
- perror_msg_and_die("Unable to connect to remote host (%s)", host);
+ bb_perror_msg_and_die("Unable to connect to remote host (%s)", host);
}
return s;
#else
@@ -72,7 +72,7 @@ int xconnect(const char *host, const char *port)
if (connect(s, (struct sockaddr *)&s_addr, sizeof s_addr) < 0)
{
- perror_msg_and_die("Unable to connect to remote host (%s)", host);
+ bb_perror_msg_and_die("Unable to connect to remote host (%s)", host);
}
return s;
#endif
diff --git a/libbb/xfuncs.c b/libbb/xfuncs.c
index 820a0d7cc..43e8aef0c 100644
--- a/libbb/xfuncs.c
+++ b/libbb/xfuncs.c
@@ -30,31 +30,38 @@
#ifndef DMALLOC
+#ifdef L_xmalloc
extern void *xmalloc(size_t size)
{
void *ptr = malloc(size);
if (ptr == NULL && size != 0)
- error_msg_and_die(memory_exhausted);
+ bb_error_msg_and_die(bb_msg_memory_exhausted);
return ptr;
}
+#endif
+#ifdef L_xrealloc
extern void *xrealloc(void *ptr, size_t size)
{
ptr = realloc(ptr, size);
if (ptr == NULL && size != 0)
- error_msg_and_die(memory_exhausted);
+ bb_error_msg_and_die(bb_msg_memory_exhausted);
return ptr;
}
+#endif
+#ifdef L_xcalloc
extern void *xcalloc(size_t nmemb, size_t size)
{
void *ptr = calloc(nmemb, size);
if (ptr == NULL && nmemb != 0 && size != 0)
- error_msg_and_die(memory_exhausted);
+ bb_error_msg_and_die(bb_msg_memory_exhausted);
return ptr;
}
+#endif
-extern char * xstrdup (const char *s) {
+#ifdef L_xstrdup
+extern char * bb_xstrdup (const char *s) {
char *t;
if (s == NULL)
@@ -63,79 +70,121 @@ extern char * xstrdup (const char *s) {
t = strdup (s);
if (t == NULL)
- error_msg_and_die(memory_exhausted);
+ bb_error_msg_and_die(bb_msg_memory_exhausted);
return t;
}
#endif
+#endif /* DMALLOC */
-extern char * xstrndup (const char *s, int n) {
+#ifdef L_xstrndup
+extern char * bb_xstrndup (const char *s, int n) {
char *t;
if (s == NULL)
- error_msg_and_die("xstrndup bug");
+ bb_error_msg_and_die("bb_xstrndup bug");
t = xmalloc(++n);
return safe_strncpy(t,s,n);
}
+#endif
-FILE *xfopen(const char *path, const char *mode)
+#ifdef L_xfopen
+FILE *bb_xfopen(const char *path, const char *mode)
{
FILE *fp;
if ((fp = fopen(path, mode)) == NULL)
- perror_msg_and_die("%s", path);
+ bb_perror_msg_and_die("%s", path);
return fp;
}
+#endif
-extern int xopen(const char *pathname, int flags)
+#ifdef L_xopen
+extern int bb_xopen(const char *pathname, int flags)
{
int ret;
ret = open(pathname, flags, 0777);
if (ret == -1) {
- perror_msg_and_die("%s", pathname);
+ bb_perror_msg_and_die("%s", pathname);
}
return ret;
}
+#endif
-extern ssize_t xread(int fd, void *buf, size_t count)
+#ifdef L_xread
+extern ssize_t bb_xread(int fd, void *buf, size_t count)
{
ssize_t size;
size = read(fd, buf, count);
if (size == -1) {
- perror_msg_and_die("Read error");
+ bb_perror_msg_and_die("Read error");
}
return(size);
}
+#endif
-extern void xread_all(int fd, void *buf, size_t count)
+#ifdef L_xread_all
+extern void bb_xread_all(int fd, void *buf, size_t count)
{
ssize_t size;
- size = xread(fd, buf, count);
- if (size != count) {
- error_msg_and_die("Short read");
+ while (count) {
+ if ((size = bb_xread(fd, buf, count)) == 0) { /* EOF */
+ bb_error_msg_and_die("Short read");
+ }
+ count -= size;
}
return;
}
+#endif
-extern unsigned char xread_char(int fd)
+#ifdef L_xread_char
+extern unsigned char bb_xread_char(int fd)
{
char tmp;
- xread_all(fd, &tmp, 1);
+ bb_xread_all(fd, &tmp, 1);
return(tmp);
}
+#endif
+
+#ifdef L_xferror
+extern void bb_xferror(FILE *fp, const char *fn)
+{
+ if (ferror(fp)) {
+ bb_error_msg_and_die("%s", fn);
+ }
+}
+#endif
+
+#ifdef L_xferror_stdout
+extern void bb_xferror_stdout(void)
+{
+ bb_xferror(stdout, bb_msg_standard_output);
+}
+#endif
+
+#ifdef L_xfflush_stdout
+extern void bb_xfflush_stdout(void)
+{
+ if (fflush(stdout)) {
+ bb_perror_msg_and_die(bb_msg_standard_output);
+ }
+}
+#endif
+#ifdef L_strlen
/* Stupid gcc always includes its own builtin strlen()... */
#undef strlen
-size_t xstrlen(const char *string)
+size_t bb_strlen(const char *string)
{
return(strlen(string));
}
+#endif
/* END CODE */
/*
diff --git a/libbb/xgetcwd.c b/libbb/xgetcwd.c
index 54e9785ed..85a5c4125 100644
--- a/libbb/xgetcwd.c
+++ b/libbb/xgetcwd.c
@@ -40,7 +40,7 @@ xgetcwd (char *cwd)
if (ret == NULL) {
free (cwd);
- perror_msg("getcwd()");
+ bb_perror_msg("getcwd()");
return NULL;
}
diff --git a/libbb/xgethostbyname.c b/libbb/xgethostbyname.c
index b71979701..6b2dff711 100644
--- a/libbb/xgethostbyname.c
+++ b/libbb/xgethostbyname.c
@@ -29,7 +29,7 @@ struct hostent *xgethostbyname(const char *name)
struct hostent *retval;
if ((retval = gethostbyname(name)) == NULL)
- herror_msg_and_die("%s", name);
+ bb_herror_msg_and_die("%s", name);
return retval;
}
diff --git a/libbb/xgethostbyname2.c b/libbb/xgethostbyname2.c
index f4cbb6a56..3a16ae4dc 100644
--- a/libbb/xgethostbyname2.c
+++ b/libbb/xgethostbyname2.c
@@ -30,7 +30,7 @@ struct hostent *xgethostbyname2(const char *name, int af)
struct hostent *retval;
if ((retval = gethostbyname2(name, af)) == NULL)
- herror_msg_and_die("%s", name);
+ bb_herror_msg_and_die("%s", name);
return retval;
}
diff --git a/libbb/xgetlarg.c b/libbb/xgetlarg.c
index 598b0b3d6..06e776dc9 100644
--- a/libbb/xgetlarg.c
+++ b/libbb/xgetlarg.c
@@ -9,6 +9,7 @@
#include <getopt.h>
#include <errno.h>
#include <assert.h>
+#include <ctype.h>
#include "busybox.h"
@@ -19,10 +20,16 @@ extern long bb_xgetlarg(char *arg, int base, long lower, long upper)
int errno_save = errno;
assert(arg!=NULL);
+
+ /* Don't allow leading whitespace. */
+ if ((isspace)(*arg)) { /* Use an actual funciton call for minimal size. */
+ bb_show_usage();
+ }
+
errno = 0;
result = strtol(arg, &endptr, base);
- if (errno != 0 || *endptr!='\0' || result < lower || result > upper)
- show_usage();
+ if (errno != 0 || *endptr!='\0' || endptr==arg || result < lower || result > upper)
+ bb_show_usage();
errno = errno_save;
return result;
}
diff --git a/libbb/xgetularg.c b/libbb/xgetularg.c
new file mode 100644
index 000000000..d743520c3
--- /dev/null
+++ b/libbb/xgetularg.c
@@ -0,0 +1,160 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * xgetularg* implementations for busybox
+ *
+ * Copyright (C) 2003 Manuel Novoa III <mjn3@codepoet.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <ctype.h>
+#include <errno.h>
+#include <assert.h>
+#include "libbb.h"
+
+#ifdef L_xgetularg_bnd_sfx
+extern
+unsigned long bb_xgetularg_bnd_sfx(const char *arg, int base,
+ unsigned long lower,
+ unsigned long upper,
+ const struct suffix_mult *suffixes)
+{
+ unsigned long r;
+ int old_errno;
+ char *e;
+
+ assert(arg);
+
+ /* Disallow '-' and any leading whitespace. Speed isn't critical here
+ * since we're parsing commandline args. So make sure we get the
+ * actual isspace function rather than a larger macro implementaion. */
+ if ((*arg == '-') || (isspace)(*arg)) {
+ bb_show_usage();
+ }
+
+ /* Since this is a lib function, we're not allowed to reset errno to 0.
+ * Doing so could break an app that is deferring checking of errno.
+ * So, save the old value so that we can restore it if successful. */
+ old_errno = errno;
+ errno = 0;
+ r = strtoul(arg, &e, base);
+ /* Do the initial validity check. Note: The standards do not
+ * guarantee that errno is set if no digits were found. So we
+ * must test for this explicitly. */
+ if (errno || (arg == e)) { /* error or no digits */
+ bb_show_usage();
+ }
+ errno = old_errno; /* Ok. So restore errno. */
+
+ /* Do optional suffix parsing. Allow 'empty' suffix tables.
+ * Note that we also all nul suffixes with associated multipliers,
+ * to allow for scaling of the arg by some default multiplier. */
+
+ if (suffixes) {
+ while (suffixes->suffix) {
+ if (strcmp(suffixes->suffix, e) == 0) {
+ if (ULONG_MAX / suffixes->mult < r) { /* Overflow! */
+ bb_show_usage();
+ }
+ ++e;
+ r *= suffixes->mult;
+ break;
+ }
+ ++suffixes;
+ }
+ }
+
+ /* Finally, check for illegal trailing chars and range limits. */
+ /* Note: although we allow leading space (via stroul), trailing space
+ * is an error. It would be easy enough to allow though if desired. */
+ if (*e || (r < lower) || (r > upper)) {
+ bb_show_usage();
+ }
+
+ return r;
+}
+#endif
+
+#ifdef L_xgetlarg_bnd_sfx
+extern
+long bb_xgetlarg_bnd_sfx(const char *arg, int base,
+ long lower,
+ long upper,
+ const struct suffix_mult *suffixes)
+{
+ unsigned long u = LONG_MAX;
+ long r;
+ const char *p = arg;
+
+ if ((*p == '-') && (p[1] != '+')) {
+ ++p;
+#if LONG_MAX == (-(LONG_MIN + 1))
+ ++u; /* two's complement */
+#endif
+ }
+
+ r = bb_xgetularg_bnd_sfx(p, base, 0, u, suffixes);
+
+ if (*arg == '-') {
+ r = -r;
+ }
+
+ if ((r < lower) || (r > upper)) {
+ bb_show_usage();
+ }
+
+ return r;
+}
+#endif
+
+#ifdef L_getlarg10_sfx
+extern
+long bb_xgetlarg10_sfx(const char *arg, const struct suffix_mult *suffixes)
+{
+ return bb_xgetlarg_bnd_sfx(arg, 10, LONG_MIN, LONG_MAX, suffixes);
+}
+#endif
+
+#ifdef L_xgetularg_bnd
+extern
+unsigned long bb_xgetularg_bnd(const char *arg, int base,
+ unsigned long lower,
+ unsigned long upper)
+{
+ return bb_xgetularg_bnd_sfx(arg, base, lower, upper, NULL);
+}
+#endif
+
+#ifdef L_xgetularg10_bnd
+extern
+unsigned long bb_xgetularg10_bnd(const char *arg,
+ unsigned long lower,
+ unsigned long upper)
+{
+ return bb_xgetularg_bnd(arg, 10, lower, upper);
+}
+#endif
+
+#ifdef L_xgetularg10
+extern
+unsigned long bb_xgetularg10(const char *arg)
+{
+ return bb_xgetularg10_bnd(arg, 0, ULONG_MAX);
+}
+#endif
diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c
index 9944b5129..b8cfe617a 100644
--- a/libbb/xreadlink.c
+++ b/libbb/xreadlink.c
@@ -24,7 +24,7 @@ extern char *xreadlink(const char *path)
buf = xrealloc(buf, bufsize += GROWBY);
readsize = readlink(path, buf, bufsize); /* 1st try */
if (readsize == -1) {
- perror_msg("%s", path);
+ bb_perror_msg("%s", path);
return NULL;
}
}
diff --git a/libbb/xregcomp.c b/libbb/xregcomp.c
index 07cf779d1..56746ac53 100644
--- a/libbb/xregcomp.c
+++ b/libbb/xregcomp.c
@@ -34,7 +34,7 @@ void xregcomp(regex_t *preg, const char *regex, int cflags)
int errmsgsz = regerror(ret, preg, NULL, 0);
char *errmsg = xmalloc(errmsgsz);
regerror(ret, preg, errmsg, errmsgsz);
- error_msg_and_die("xregcomp: %s", errmsg);
+ bb_error_msg_and_die("xregcomp: %s", errmsg);
}
}