From 87a40a1775f5267eb6dc2937abd641d302abf739 Mon Sep 17 00:00:00 2001 From: Vicente Date: Tue, 6 Aug 2013 14:44:58 +0200 Subject: [PATCH] Busybox: Upgrade to 1.21.1 (stable). lsof active. --- release/src/router/busybox/Config.in | 15 +- release/src/router/busybox/Makefile | 5 +- release/src/router/busybox/Makefile.flags | 16 +- release/src/router/busybox/archival/cpio.c | 30 +- release/src/router/busybox/archival/dpkg.c | 19 +- release/src/router/busybox/archival/gzip.c | 16 +- .../archival/libarchive/decompress_gunzip.c | 4 +- .../archival/libarchive/decompress_uncompress.c | 34 +- .../busybox/archival/libarchive/decompress_unxz.c | 47 +- .../libarchive/filter_accept_reject_list.c | 8 +- .../busybox/archival/libarchive/get_header_tar.c | 6 +- .../router/busybox/archival/libarchive/lzo1x_9x.c | 12 +- .../router/busybox/archival/libarchive/lzo1x_c.c | 2 +- .../router/busybox/archival/libarchive/lzo1x_d.c | 2 +- release/src/router/busybox/archival/lzop.c | 10 +- release/src/router/busybox/archival/tar.c | 50 +- release/src/router/busybox/archival/unzip.c | 149 +-- release/src/router/busybox/config_base | 6 + release/src/router/busybox/config_nc | 1021 -------------------- .../router/busybox/configs/TEST_nommu_defconfig | 1 - .../router/busybox/configs/TEST_noprintf_defconfig | 1 - .../src/router/busybox/configs/TEST_rh9_defconfig | 1 - .../src/router/busybox/configs/android2_defconfig | 1 - .../src/router/busybox/configs/android_defconfig | 1 - .../router/busybox/configs/android_ndk_defconfig | 29 +- .../src/router/busybox/configs/cygwin_defconfig | 1 - .../src/router/busybox/configs/freebsd_defconfig | 1 - .../src/router/busybox/console-tools/loadfont.c | 2 +- .../src/router/busybox/console-tools/setlogcons.c | 7 +- release/src/router/busybox/coreutils/Config.src | 12 +- release/src/router/busybox/coreutils/Kbuild.src | 1 + release/src/router/busybox/coreutils/cal.c | 15 +- release/src/router/busybox/coreutils/chown.c | 4 +- release/src/router/busybox/coreutils/cut.c | 2 +- release/src/router/busybox/coreutils/df.c | 8 +- release/src/router/busybox/coreutils/du.c | 4 + release/src/router/busybox/coreutils/id.c | 2 +- release/src/router/busybox/coreutils/ln.c | 28 +- release/src/router/busybox/coreutils/ls.c | 4 +- .../src/router/busybox/coreutils/md5_sha1_sum.c | 19 +- release/src/router/busybox/coreutils/mkdir.c | 3 +- release/src/router/busybox/coreutils/mknod.c | 2 +- release/src/router/busybox/coreutils/mv.c | 19 +- release/src/router/busybox/coreutils/od_bloaty.c | 6 +- release/src/router/busybox/coreutils/rmdir.c | 8 +- release/src/router/busybox/coreutils/sort.c | 2 +- release/src/router/busybox/coreutils/stat.c | 68 +- release/src/router/busybox/coreutils/stty.c | 2 +- release/src/router/busybox/coreutils/sum.c | 4 +- release/src/router/busybox/coreutils/test.c | 2 +- release/src/router/busybox/debianutils/mktemp.c | 40 +- release/src/router/busybox/debianutils/run_parts.c | 15 +- release/src/router/busybox/e2fsprogs/Kbuild.src | 2 +- release/src/router/busybox/e2fsprogs/fsck.c | 4 +- release/src/router/busybox/e2fsprogs/lsattr.c | 2 +- release/src/router/busybox/e2fsprogs/tune2fs.c | 822 ++-------------- release/src/router/busybox/editors/awk.c | 40 +- release/src/router/busybox/editors/diff.c | 2 +- release/src/router/busybox/editors/sed.c | 130 ++- release/src/router/busybox/editors/vi.c | 213 ++-- release/src/router/busybox/examples/mdev.conf | 10 +- release/src/router/busybox/examples/mdev_fat.conf | 9 +- release/src/router/busybox/findutils/find.c | 39 +- release/src/router/busybox/findutils/grep.c | 39 +- release/src/router/busybox/include/applets.src.h | 42 +- release/src/router/busybox/include/bb_archive.h | 7 +- release/src/router/busybox/include/bb_e2fs_defs.h | 43 +- release/src/router/busybox/include/busybox.h | 4 +- release/src/router/busybox/include/grp_.h | 24 +- release/src/router/busybox/include/libbb.h | 52 +- release/src/router/busybox/include/platform.h | 16 +- release/src/router/busybox/include/pwd_.h | 24 +- release/src/router/busybox/include/shadow_.h | 14 +- release/src/router/busybox/init/init.c | 2 +- release/src/router/busybox/libbb/Config.src | 10 + release/src/router/busybox/libbb/Kbuild.src | 1 + release/src/router/busybox/libbb/appletlib.c | 28 +- .../src/router/busybox/libbb/correct_password.c | 9 +- release/src/router/busybox/libbb/get_shell_name.c | 2 +- release/src/router/busybox/libbb/hash_md5_sha.c | 294 +++++- release/src/router/busybox/libbb/inet_common.c | 4 +- release/src/router/busybox/libbb/kernel_version.c | 11 +- release/src/router/busybox/libbb/lineedit.c | 9 +- release/src/router/busybox/libbb/loop.c | 6 +- release/src/router/busybox/libbb/make_directory.c | 7 +- .../src/router/busybox/libbb/missing_syscalls.c | 42 + release/src/router/busybox/libbb/procps.c | 6 +- release/src/router/busybox/libbb/read_key.c | 15 +- release/src/router/busybox/libbb/remove_file.c | 2 +- .../src/router/busybox/libbb/safe_gethostname.c | 22 - release/src/router/busybox/libbb/selinux_common.c | 2 +- .../src/router/busybox/libbb/setup_environment.c | 8 +- release/src/router/busybox/libbb/signals.c | 6 +- release/src/router/busybox/libbb/udp_io.c | 7 +- .../src/router/busybox/libbb/xatonum_template.c | 2 +- release/src/router/busybox/libbb/xfuncs_printf.c | 4 +- release/src/router/busybox/libpwdgrp/pwd_grp.c | 14 +- .../router/busybox/loginutils/add-remove-shell.c | 4 +- release/src/router/busybox/loginutils/adduser.c | 22 +- release/src/router/busybox/loginutils/getty.c | 9 +- release/src/router/busybox/loginutils/login.c | 3 +- release/src/router/busybox/loginutils/passwd.c | 1 + release/src/router/busybox/loginutils/su.c | 3 +- release/src/router/busybox/mailutils/sendmail.c | 7 +- release/src/router/busybox/miscutils/crond.c | 2 +- release/src/router/busybox/miscutils/dc.c | 20 +- release/src/router/busybox/miscutils/devfsd.c | 56 +- release/src/router/busybox/miscutils/fbsplash.c | 34 +- release/src/router/busybox/miscutils/flashcp.c | 3 +- release/src/router/busybox/miscutils/hdparm.c | 6 +- release/src/router/busybox/miscutils/last.c | 4 +- release/src/router/busybox/miscutils/last_fancy.c | 16 +- release/src/router/busybox/miscutils/less.c | 6 +- release/src/router/busybox/miscutils/nandwrite.c | 14 +- release/src/router/busybox/miscutils/rx.c | 4 +- release/src/router/busybox/miscutils/time.c | 3 +- release/src/router/busybox/miscutils/watchdog.c | 3 + release/src/router/busybox/modutils/depmod.c | 6 +- release/src/router/busybox/modutils/modinfo.c | 25 +- .../src/router/busybox/modutils/modprobe-small.c | 11 +- release/src/router/busybox/modutils/rmmod.c | 2 +- release/src/router/busybox/networking/Config.src | 8 +- release/src/router/busybox/networking/arp.c | 14 +- release/src/router/busybox/networking/brctl.c | 16 +- release/src/router/busybox/networking/ether-wake.c | 14 +- release/src/router/busybox/networking/ftpd.c | 3 +- release/src/router/busybox/networking/httpd.c | 8 +- .../src/router/busybox/networking/httpd_indexcgi.c | 1 + release/src/router/busybox/networking/httpd_ssi.c | 2 +- release/src/router/busybox/networking/ifconfig.c | 169 ++-- release/src/router/busybox/networking/ifenslave.c | 4 +- release/src/router/busybox/networking/ifplugd.c | 8 +- release/src/router/busybox/networking/ifupdown.c | 26 +- release/src/router/busybox/networking/inetd.c | 8 +- release/src/router/busybox/networking/interface.c | 31 +- .../busybox/networking/libiproute/ipaddress.c | 10 +- .../router/busybox/networking/libiproute/iprule.c | 14 +- .../busybox/networking/libiproute/iptunnel.c | 2 +- .../busybox/networking/libiproute/ll_proto.c | 108 ++- release/src/router/busybox/networking/nc.c | 2 +- release/src/router/busybox/networking/netstat.c | 2 +- release/src/router/busybox/networking/ntpd.c | 67 +- .../src/router/busybox/networking/ntpd_simple.c | 3 +- release/src/router/busybox/networking/ping.c | 2 +- release/src/router/busybox/networking/route.c | 20 +- release/src/router/busybox/networking/tc.c | 5 +- release/src/router/busybox/networking/telnet.c | 55 +- release/src/router/busybox/networking/telnetd.c | 1 + release/src/router/busybox/networking/tftp.c | 64 +- release/src/router/busybox/networking/traceroute.c | 17 +- .../src/router/busybox/networking/udhcp/Config.src | 18 +- .../src/router/busybox/networking/udhcp/Kbuild.src | 2 + .../src/router/busybox/networking/udhcp/common.c | 93 +- .../src/router/busybox/networking/udhcp/common.h | 20 +- .../networking/udhcp/{common.c => common_old.c} | 0 .../networking/udhcp/{common.h => common_old.h} | 0 .../src/router/busybox/networking/udhcp/d6_dhcpc.c | 27 +- .../src/router/busybox/networking/udhcp/dhcpc.c | 552 +++++++---- .../src/router/busybox/networking/udhcp/dhcpc.h | 1 - .../networking/udhcp/{dhcpc.c => dhcpc_old.c} | 4 +- .../networking/udhcp/{dhcpc.h => dhcpc_old.h} | 0 .../src/router/busybox/networking/udhcp/dhcpd.c | 8 +- .../src/router/busybox/networking/udhcp/socket.c | 10 +- release/src/router/busybox/networking/wget.c | 171 ++-- release/src/router/busybox/printutils/lpr.c | 36 +- release/src/router/busybox/procps/Config.src | 54 -- release/src/router/busybox/procps/nmeter.c | 2 +- release/src/router/busybox/procps/powertop.c | 6 +- release/src/router/busybox/procps/ps.c | 6 +- release/src/router/busybox/procps/sysctl.c | 34 +- release/src/router/busybox/procps/top.c | 163 +++- release/src/router/busybox/runit/chpst.c | 1 + release/src/router/busybox/runit/runsv.c | 2 +- release/src/router/busybox/runit/svlogd.c | 4 +- release/src/router/busybox/scripts/kconfig/mconf.c | 18 +- release/src/router/busybox/selinux/chcon.c | 20 +- release/src/router/busybox/selinux/runcon.c | 10 +- release/src/router/busybox/selinux/sestatus.c | 2 +- release/src/router/busybox/selinux/setfiles.c | 19 +- release/src/router/busybox/shell/ash.c | 118 ++- .../busybox/shell/ash_test/ash-redir/redirA.right | 2 + .../busybox/shell/ash_test/ash-redir/redirA.tests | 11 + release/src/router/busybox/shell/hush.c | 10 +- release/src/router/busybox/shell/math.c | 2 +- release/src/router/busybox/shell/shell_common.c | 3 +- release/src/router/busybox/shell/shell_common.h | 2 +- release/src/router/busybox/sysklogd/Config.src | 16 + release/src/router/busybox/sysklogd/klogd.c | 10 +- release/src/router/busybox/sysklogd/syslogd.c | 81 +- release/src/router/busybox/testsuite/awk.tests | 19 + release/src/router/busybox/testsuite/du/du-k-works | 1 + release/src/router/busybox/testsuite/grep.tests | 12 + release/src/router/busybox/testsuite/mdev.tests | 22 +- .../src/router/busybox/testsuite/mkfs.minix.tests | 10 +- release/src/router/busybox/testsuite/mount.tests | 27 +- release/src/router/busybox/testsuite/sed.tests | 19 +- release/src/router/busybox/testsuite/sha3sum.tests | 3 + release/src/router/busybox/util-linux/Config.src | 17 + release/src/router/busybox/util-linux/acpid.c | 3 +- release/src/router/busybox/util-linux/dmesg.c | 13 +- release/src/router/busybox/util-linux/fbset.c | 26 +- release/src/router/busybox/util-linux/fdformat.c | 2 +- release/src/router/busybox/util-linux/fdisk.c | 2 +- release/src/router/busybox/util-linux/fdisk_osf.c | 5 +- release/src/router/busybox/util-linux/flock.c | 2 +- release/src/router/busybox/util-linux/fsck_minix.c | 67 +- release/src/router/busybox/util-linux/getopt.c | 2 +- release/src/router/busybox/util-linux/ipcrm.c | 6 +- release/src/router/busybox/util-linux/ipcs.c | 256 ++--- release/src/router/busybox/util-linux/lspci.c | 6 +- release/src/router/busybox/util-linux/mdev.c | 572 ++++++++--- release/src/router/busybox/util-linux/mount.c | 143 ++- release/src/router/busybox/util-linux/rdate.c | 23 +- .../src/router/busybox/util-linux/readprofile.c | 16 +- .../router/busybox/util-linux/volume_id/Kbuild.src | 1 + .../router/busybox/util-linux/volume_id/btrfs.c | 1 + .../router/busybox/util-linux/volume_id/exfat.c | 1 - .../src/router/busybox/util-linux/volume_id/ext.c | 180 ++-- .../busybox/util-linux/volume_id/get_devname.c | 6 +- .../src/router/busybox/util-linux/volume_id/hfs.c | 27 +- .../busybox/util-linux/volume_id/linux_raid.c | 6 +- .../router/busybox/util-linux/volume_id/nilfs.c | 96 ++ .../src/router/busybox/util-linux/volume_id/ntfs.c | 6 +- .../router/busybox/util-linux/volume_id/squashfs.c | 49 + .../src/router/busybox/util-linux/volume_id/udf.c | 2 +- .../busybox/util-linux/volume_id/unused_msdos.c | 2 +- .../util-linux/volume_id/unused_silicon_raid.c | 2 +- .../src/router/busybox/util-linux/volume_id/util.c | 59 +- .../busybox/util-linux/volume_id/volume_id.c | 6 + .../util-linux/volume_id/volume_id_internal.h | 17 +- 230 files changed, 4080 insertions(+), 3959 deletions(-) delete mode 100644 release/src/router/busybox/config_nc rewrite release/src/router/busybox/e2fsprogs/tune2fs.c (97%) create mode 100644 release/src/router/busybox/libbb/missing_syscalls.c copy release/src/router/busybox/networking/udhcp/{common.c => common_old.c} (100%) copy release/src/router/busybox/networking/udhcp/{common.h => common_old.h} (100%) copy release/src/router/busybox/networking/udhcp/{dhcpc.c => dhcpc_old.c} (99%) copy release/src/router/busybox/networking/udhcp/{dhcpc.h => dhcpc_old.h} (100%) create mode 100644 release/src/router/busybox/shell/ash_test/ash-redir/redirA.right create mode 100644 release/src/router/busybox/shell/ash_test/ash-redir/redirA.tests create mode 100644 release/src/router/busybox/testsuite/sha3sum.tests rewrite release/src/router/busybox/util-linux/volume_id/ext.c (63%) create mode 100644 release/src/router/busybox/util-linux/volume_id/nilfs.c create mode 100644 release/src/router/busybox/util-linux/volume_id/squashfs.c diff --git a/release/src/router/busybox/Config.in b/release/src/router/busybox/Config.in index 17bdc895ac..03c2d032f2 100644 --- a/release/src/router/busybox/Config.in +++ b/release/src/router/busybox/Config.in @@ -310,7 +310,18 @@ config FEATURE_PIDFILE default y help This option makes some applets (e.g. crond, syslogd, inetd) write - a pidfile in /var/run. Some applications rely on them. + a pidfile at the configured PID_FILE_PATH. It has no effect + on applets which require pidfiles to run. + +config PID_FILE_PATH + string "Path to directory for pidfile" + default "/var/run" + depends on FEATURE_PIDFILE + help + This is the default path where pidfiles are created. Applets which + allow you to set the pidfile path on the command line will override + this value. The option has no effect on applets that require you to + specify a pidfile path. config FEATURE_SUID bool "Support for SUID/SGID handling" @@ -321,7 +332,7 @@ config FEATURE_SUID root-level operations even when run by ordinary users (for example, mounting of user mounts in fstab needs this). - Busybox will automatically drop priviledges for applets + Busybox will automatically drop privileges for applets that don't need root access. If you are really paranoid and don't want to do this, build two diff --git a/release/src/router/busybox/Makefile b/release/src/router/busybox/Makefile index 8d5ea165f3..f47cb39671 100644 --- a/release/src/router/busybox/Makefile +++ b/release/src/router/busybox/Makefile @@ -1,6 +1,6 @@ VERSION = 1 -PATCHLEVEL = 20 -SUBLEVEL = 2 +PATCHLEVEL = 21 +SUBLEVEL = 1 EXTRAVERSION = NAME = Unnamed @@ -297,6 +297,7 @@ NM = $(CROSS_COMPILE)nm STRIP = $(CROSS_COMPILE)strip OBJCOPY = $(CROSS_COMPILE)objcopy OBJDUMP = $(CROSS_COMPILE)objdump +PKG_CONFIG ?= $(CROSS_COMPILE)pkg-config AWK = awk GENKSYMS = scripts/genksyms/genksyms DEPMOD = /sbin/depmod diff --git a/release/src/router/busybox/Makefile.flags b/release/src/router/busybox/Makefile.flags index e2ce6291e5..7cbe06996b 100644 --- a/release/src/router/busybox/Makefile.flags +++ b/release/src/router/busybox/Makefile.flags @@ -25,6 +25,7 @@ CFLAGS += $(call cc-option,-Wstrict-prototypes,) CFLAGS += $(call cc-option,-Wunused -Wunused-parameter,) CFLAGS += $(call cc-option,-Wunused-function -Wunused-value,) CFLAGS += $(call cc-option,-Wmissing-prototypes -Wmissing-declarations,) +CFLAGS += $(call cc-option,-Wno-format-security,) # warn about C99 declaration after statement CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) # If you want to add more -Wsomething above, make sure that it is @@ -52,6 +53,9 @@ CFLAGS += $(call cc-option,-fno-builtin-strlen -finline-limit=0 -fomit-frame-poi CFLAGS += $(call cc-option,-fno-guess-branch-probability,) CFLAGS += $(call cc-option,-funsigned-char -shared-libgcc,) CFLAGS += $(call cc-option,-falign-functions=1 -falign-jumps=1 -falign-labels=1 -falign-loops=1,) +# Defeat .eh_frame bloat (gcc 4.6.3 x86-32 defconfig: 20% smaller busybox binary): +CFLAGS += $(call cc-option,-fno-unwind-tables,) +CFLAGS += $(call cc-option,-fno-asynchronous-unwind-tables,) # FIXME: These warnings are at least partially to be concerned about and should # be fixed.. @@ -74,6 +78,12 @@ ARCH_FPIC ?= -fpic ARCH_FPIE ?= -fpie ARCH_PIE ?= -pie +# Usage: $(eval $(call pkg_check_modules,VARIABLE-PREFIX,MODULES)) +define pkg_check_modules +$(1)_CFLAGS := $(shell $(PKG_CONFIG) $(PKG_CONFIG_FLAGS) --cflags $(2)) +$(1)_LIBS := $(shell $(PKG_CONFIG) $(PKG_CONFIG_FLAGS) --libs $(2)) +endef + ifeq ($(CONFIG_BUILD_LIBBUSYBOX),y) # on i386: 14% smaller libbusybox.so # (code itself is 9% bigger, we save on relocs/PLT/GOT) @@ -85,6 +95,7 @@ endif ifeq ($(CONFIG_STATIC),y) CFLAGS_busybox += -static +PKG_CONFIG_FLAGS += --static endif ifeq ($(CONFIG_PIE),y) @@ -127,7 +138,10 @@ LDLIBS += pam pam_misc pthread endif ifeq ($(CONFIG_SELINUX),y) -LDLIBS += selinux sepol +SELINUX_PC_MODULES = libselinux libsepol +$(eval $(call pkg_check_modules,SELINUX,$(SELINUX_PC_MODULES))) +CPPFLAGS += $(SELINUX_CFLAGS) +LDLIBS += $(if $(SELINUX_LIBS),$(SELINUX_LIBS:-l%=%),$(SELINUX_PC_MODULES:lib%=%)) endif ifeq ($(CONFIG_EFENCE),y) diff --git a/release/src/router/busybox/archival/cpio.c b/release/src/router/busybox/archival/cpio.c index 98cc18fa07..699c6dbb75 100644 --- a/release/src/router/busybox/archival/cpio.c +++ b/release/src/router/busybox/archival/cpio.c @@ -253,24 +253,24 @@ static NOINLINE int cpio_o(void) } bytes += printf("070701" - "%08X%08X%08X%08X%08X%08X%08X" - "%08X%08X%08X%08X" /* GNU cpio uses uppercase hex */ + "%08X%08X%08X%08X%08X%08X%08X" + "%08X%08X%08X%08X" /* GNU cpio uses uppercase hex */ /* strlen+1: */ "%08X" /* chksum: */ "00000000" /* (only for "070702" files) */ /* name,NUL: */ "%s%c", - (unsigned)(uint32_t) st.st_ino, - (unsigned)(uint32_t) st.st_mode, - (unsigned)(uint32_t) st.st_uid, - (unsigned)(uint32_t) st.st_gid, - (unsigned)(uint32_t) st.st_nlink, - (unsigned)(uint32_t) st.st_mtime, - (unsigned)(uint32_t) st.st_size, - (unsigned)(uint32_t) major(st.st_dev), - (unsigned)(uint32_t) minor(st.st_dev), - (unsigned)(uint32_t) major(st.st_rdev), - (unsigned)(uint32_t) minor(st.st_rdev), - (unsigned)(strlen(name) + 1), - name, '\0'); + (unsigned)(uint32_t) st.st_ino, + (unsigned)(uint32_t) st.st_mode, + (unsigned)(uint32_t) st.st_uid, + (unsigned)(uint32_t) st.st_gid, + (unsigned)(uint32_t) st.st_nlink, + (unsigned)(uint32_t) st.st_mtime, + (unsigned)(uint32_t) st.st_size, + (unsigned)(uint32_t) major(st.st_dev), + (unsigned)(uint32_t) minor(st.st_dev), + (unsigned)(uint32_t) major(st.st_rdev), + (unsigned)(uint32_t) minor(st.st_rdev), + (unsigned)(strlen(name) + 1), + name, '\0'); bytes = cpio_pad4(bytes); if (st.st_size) { diff --git a/release/src/router/busybox/archival/dpkg.c b/release/src/router/busybox/archival/dpkg.c index bf9e9992c1..ed86f3355d 100644 --- a/release/src/router/busybox/archival/dpkg.c +++ b/release/src/router/busybox/archival/dpkg.c @@ -1026,8 +1026,8 @@ static int check_deps(deb_file_t **deb_file, int deb_start /*, int dep_max_count if (package_edge->type == EDGE_CONFLICTS) { const unsigned package_num = search_package_hashtable(package_edge->name, - package_edge->version, - package_edge->operator); + package_edge->version, + package_edge->operator); int result = 0; if (package_hashtable[package_num] != NULL) { status_num = search_status_hashtable(name_hashtable[package_hashtable[package_num]->name]); @@ -1114,7 +1114,7 @@ static int check_deps(deb_file_t **deb_file, int deb_start /*, int dep_max_count */ if (root_of_alternatives && package_edge->type != root_of_alternatives->type - 1) bb_error_msg_and_die("fatal error, package dependencies corrupt: %d != %d - 1", - package_edge->type, root_of_alternatives->type); + package_edge->type, root_of_alternatives->type); if (package_hashtable[package_num] != NULL) result = !package_satisfies_dependency(package_num, package_edge->type); @@ -1665,20 +1665,25 @@ static void unpack_package(deb_file_t *deb_file) archive_handle = init_archive_deb_ar(deb_file->filename); init_archive_deb_data(archive_handle); archive_handle->dpkg__sub_archive->accept = conffile_list; + /* Why ARCHIVE_REMEMBER_NAMES? + * We want names collected in ->passed list even if conffile_list + * is NULL (otherwise get_header_tar may optimize name saving out): + */ + archive_handle->dpkg__sub_archive->ah_flags |= ARCHIVE_REMEMBER_NAMES | ARCHIVE_UNLINK_OLD; archive_handle->dpkg__sub_archive->filter = filter_rename_config; archive_handle->dpkg__sub_archive->action_data = data_extract_all_prefix; archive_handle->dpkg__sub_archive->dpkg__buffer = (char*)"/"; /* huh? */ - archive_handle->dpkg__sub_archive->ah_flags |= ARCHIVE_UNLINK_OLD; unpack_ar_archive(archive_handle); /* Create the list file */ list_filename = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, "list"); out_stream = xfopen_for_write(list_filename); + archive_handle->dpkg__sub_archive->passed = llist_rev(archive_handle->dpkg__sub_archive->passed); while (archive_handle->dpkg__sub_archive->passed) { + char *filename = llist_pop(&archive_handle->dpkg__sub_archive->passed); /* the leading . has been stripped by data_extract_all_prefix already */ - fputs(archive_handle->dpkg__sub_archive->passed->data, out_stream); - fputc('\n', out_stream); - archive_handle->dpkg__sub_archive->passed = archive_handle->dpkg__sub_archive->passed->link; + fprintf(out_stream, "%s\n", filename); + free(filename); } fclose(out_stream); diff --git a/release/src/router/busybox/archival/gzip.c b/release/src/router/busybox/archival/gzip.c index 80db4f9699..31ccab3cd7 100644 --- a/release/src/router/busybox/archival/gzip.c +++ b/release/src/router/busybox/archival/gzip.c @@ -1179,7 +1179,7 @@ static void gen_codes(ct_data * tree, int max_code) * must be all ones. */ Assert(code + G2.bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1, - "inconsistent bit counts"); + "inconsistent bit counts"); Tracev((stderr, "\ngen_codes: max_code %d ", max_code)); for (n = 0; n <= max_code; n++) { @@ -1527,9 +1527,9 @@ static int ct_tally(int dist, int lc) } out_length >>= 3; Trace((stderr, - "\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", - G2.last_lit, G2.last_dist, in_length, out_length, - 100L - out_length * 100L / in_length)); + "\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ", + G2.last_lit, G2.last_dist, in_length, out_length, + 100L - out_length * 100L / in_length)); if (G2.last_dist < G2.last_lit / 2 && out_length < in_length / 2) return 1; } @@ -1621,9 +1621,9 @@ static ulg flush_block(char *buf, ulg stored_len, int eof) static_lenb = (G2.static_len + 3 + 7) >> 3; Trace((stderr, - "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", - opt_lenb, G2.opt_len, static_lenb, G2.static_len, stored_len, - G2.last_lit, G2.last_dist)); + "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ", + opt_lenb, G2.opt_len, static_lenb, G2.static_len, stored_len, + G2.last_lit, G2.last_dist)); if (static_lenb <= opt_lenb) opt_lenb = static_lenb; @@ -1661,7 +1661,7 @@ static ulg flush_block(char *buf, ulg stored_len, int eof) } else { send_bits((DYN_TREES << 1) + eof, 3); send_all_trees(G2.l_desc.max_code + 1, G2.d_desc.max_code + 1, - max_blindex + 1); + max_blindex + 1); compress_block((ct_data *) G2.dyn_ltree, (ct_data *) G2.dyn_dtree); G2.compressed_len += 3 + G2.opt_len; } diff --git a/release/src/router/busybox/archival/libarchive/decompress_gunzip.c b/release/src/router/busybox/archival/libarchive/decompress_gunzip.c index 2d5ab3eb3f..4e6b138c3c 100644 --- a/release/src/router/busybox/archival/libarchive/decompress_gunzip.c +++ b/release/src/router/busybox/archival/libarchive/decompress_gunzip.c @@ -293,8 +293,8 @@ static unsigned fill_bitbuffer(STATE_PARAM unsigned bitbuffer, unsigned *current * m: maximum lookup bits, returns actual */ static int huft_build(const unsigned *b, const unsigned n, - const unsigned s, const unsigned short *d, - const unsigned char *e, huft_t **t, unsigned *m) + const unsigned s, const unsigned short *d, + const unsigned char *e, huft_t **t, unsigned *m) { unsigned a; /* counter for codes of length k */ unsigned c[BMAX + 1]; /* bit length count table */ diff --git a/release/src/router/busybox/archival/libarchive/decompress_uncompress.c b/release/src/router/busybox/archival/libarchive/decompress_uncompress.c index e9bbfb9bd8..53c27080f2 100644 --- a/release/src/router/busybox/archival/libarchive/decompress_uncompress.c +++ b/release/src/router/busybox/archival/libarchive/decompress_uncompress.c @@ -78,7 +78,6 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) IF_DESKTOP(long long total_written = 0;) IF_DESKTOP(long long) int retval = -1; unsigned char *stackp; - long code; int finchar; long oldcode; long incode; @@ -143,8 +142,10 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) /* As above, initialize the first 256 entries in the table. */ /*clear_tab_prefixof(); - done by xzalloc */ - for (code = 255; code >= 0; --code) { - tab_suffixof(code) = (unsigned char) code; + { + int i; + for (i = 255; i >= 0; --i) + tab_suffixof(i) = (unsigned char) i; } do { @@ -175,6 +176,8 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) (insize << 3) - (n_bits - 1)); while (inbits > posbits) { + long code; + if (free_ent > maxcode) { posbits = ((posbits - 1) + @@ -191,13 +194,12 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) } { unsigned char *p = &inbuf[posbits >> 3]; - - code = ((((long) (p[0])) | ((long) (p[1]) << 8) | - ((long) (p[2]) << 16)) >> (posbits & 0x7)) & bitmask; + code = ((p[0] + | ((long) (p[1]) << 8) + | ((long) (p[2]) << 16)) >> (posbits & 0x7)) & bitmask; } posbits += n_bits; - if (oldcode == -1) { if (code >= 256) bb_error_msg_and_die("corrupted data"); /* %ld", code); */ @@ -226,15 +228,16 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) /* Special case for KwKwK string. */ if (code >= free_ent) { if (code > free_ent) { +/* unsigned char *p; posbits -= n_bits; p = &inbuf[posbits >> 3]; - bb_error_msg ("insize:%d posbits:%d inbuf:%02X %02X %02X %02X %02X (%d)", - insize, posbits, p[-1], p[0], p[1], p[2], p[3], - (posbits & 07)); + insize, posbits, p[-1], p[0], p[1], p[2], p[3], + (posbits & 07)); +*/ bb_error_msg("corrupted data"); goto err; } @@ -244,7 +247,7 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) } /* Generate output characters in reverse order */ - while ((long) code >= (long) 256) { + while (code >= 256) { if (stackp <= &htabof(0)) bb_error_msg_and_die("corrupted data"); *--stackp = tab_suffixof(code); @@ -285,11 +288,10 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) } /* Generate the new entry. */ - code = free_ent; - if (code < maxmaxcode) { - tab_prefixof(code) = (unsigned short) oldcode; - tab_suffixof(code) = (unsigned char) finchar; - free_ent = code + 1; + if (free_ent < maxmaxcode) { + tab_prefixof(free_ent) = (unsigned short) oldcode; + tab_suffixof(free_ent) = (unsigned char) finchar; + free_ent++; } /* Remember previous code. */ diff --git a/release/src/router/busybox/archival/libarchive/decompress_unxz.c b/release/src/router/busybox/archival/libarchive/decompress_unxz.c index 79b48a152e..986b7b191b 100644 --- a/release/src/router/busybox/archival/libarchive/decompress_unxz.c +++ b/release/src/router/busybox/archival/libarchive/decompress_unxz.c @@ -30,8 +30,8 @@ static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc) /* We use arch-optimized unaligned accessors */ #define get_unaligned_le32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_LE32(v); }) #define get_unaligned_be32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_BE32(v); }) -#define put_unaligned_le32(val, buf) move_to_unaligned16(buf, SWAP_LE32(val)) -#define put_unaligned_be32(val, buf) move_to_unaligned16(buf, SWAP_BE32(val)) +#define put_unaligned_le32(val, buf) move_to_unaligned32(buf, SWAP_LE32(val)) +#define put_unaligned_be32(val, buf) move_to_unaligned32(buf, SWAP_BE32(val)) #include "unxz/xz_dec_bcj.c" #include "unxz/xz_dec_lzma2.c" @@ -40,6 +40,7 @@ static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc) IF_DESKTOP(long long) int FAST_FUNC unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) { + enum xz_ret xz_result; struct xz_buf iobuf; struct xz_dec *state; unsigned char *membuf; @@ -63,9 +64,8 @@ unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) /* Limit memory usage to about 64 MiB. */ state = xz_dec_init(XZ_DYNALLOC, 64*1024*1024); + xz_result = X_OK; while (1) { - enum xz_ret r; - if (iobuf.in_pos == iobuf.in_size) { int rd = safe_read(src_fd, membuf, BUFSIZ); if (rd < 0) { @@ -73,28 +73,57 @@ unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) total = -1; break; } + if (rd == 0 && xz_result == XZ_STREAM_END) + break; iobuf.in_size = rd; iobuf.in_pos = 0; } + if (xz_result == XZ_STREAM_END) { + /* + * Try to start decoding next concatenated stream. + * Stream padding must always be a multiple of four + * bytes to preserve four-byte alignment. To keep the + * code slightly smaller, we aren't as strict here as + * the .xz spec requires. We just skip all zero-bytes + * without checking the alignment and thus can accept + * files that aren't valid, e.g. the XZ utils test + * files bad-0pad-empty.xz and bad-0catpad-empty.xz. + */ + do { + if (membuf[iobuf.in_pos] != 0) { + xz_dec_reset(state); + goto do_run; + } + iobuf.in_pos++; + } while (iobuf.in_pos < iobuf.in_size); + } + do_run: // bb_error_msg(">in pos:%d size:%d out pos:%d size:%d", // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size); - r = xz_dec_run(state, &iobuf); + xz_result = xz_dec_run(state, &iobuf); // bb_error_msg("accept, key); /* Fail if an accept list was specified and the key wasnt in there */ - if ((accept_entry == NULL) && archive_handle->accept) { - return EXIT_FAILURE; + if (archive_handle->accept) { + accept_entry = find_list_entry2(archive_handle->accept, key); + if (!accept_entry) { + return EXIT_FAILURE; + } } /* Accepted */ diff --git a/release/src/router/busybox/archival/libarchive/get_header_tar.c b/release/src/router/busybox/archival/libarchive/get_header_tar.c index b168653d80..bc09756ba3 100644 --- a/release/src/router/busybox/archival/libarchive/get_header_tar.c +++ b/release/src/router/busybox/archival/libarchive/get_header_tar.c @@ -452,9 +452,11 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) if (cp) *cp = '\0'; archive_handle->action_data(archive_handle); - if (archive_handle->accept || archive_handle->reject) + if (archive_handle->accept || archive_handle->reject + || (archive_handle->ah_flags & ARCHIVE_REMEMBER_NAMES) + ) { llist_add_to(&archive_handle->passed, file_header->name); - else /* Caller isn't interested in list of unpacked files */ + } else /* Caller isn't interested in list of unpacked files */ free(file_header->name); } else { data_skip(archive_handle); diff --git a/release/src/router/busybox/archival/libarchive/lzo1x_9x.c b/release/src/router/busybox/archival/libarchive/lzo1x_9x.c index 4832051559..897132987c 100644 --- a/release/src/router/busybox/archival/libarchive/lzo1x_9x.c +++ b/release/src/router/busybox/archival/libarchive/lzo1x_9x.c @@ -644,7 +644,7 @@ static int len_of_coded_match(unsigned m_len, unsigned m_off, unsigned lit) static int min_gain(unsigned ahead, unsigned lit1, - unsigned lit2, int l1, int l2, int l3) + unsigned lit2, int l1, int l2, int l3) { int lazy_match_min_gain = 0; @@ -673,7 +673,7 @@ static int min_gain(unsigned ahead, unsigned lit1, #if defined(SWD_BEST_OFF) static void better_match(const lzo_swd_p swd, - unsigned *m_len, unsigned *m_off) + unsigned *m_len, unsigned *m_off) { if (*m_len <= M2_MIN_LEN) return; @@ -914,8 +914,8 @@ int lzo1x_999_compress_level(const uint8_t *in, unsigned in_len, compression_level -= 7; return lzo1x_999_compress_internal(in, in_len, out, out_len, wrkmem, - c[compression_level].good_length, - c[compression_level].max_lazy, - c[compression_level].max_chain, - c[compression_level].use_best_off); + c[compression_level].good_length, + c[compression_level].max_lazy, + c[compression_level].max_chain, + c[compression_level].use_best_off); } diff --git a/release/src/router/busybox/archival/libarchive/lzo1x_c.c b/release/src/router/busybox/archival/libarchive/lzo1x_c.c index cc86f74b10..8c77072ab8 100644 --- a/release/src/router/busybox/archival/libarchive/lzo1x_c.c +++ b/release/src/router/busybox/archival/libarchive/lzo1x_c.c @@ -15,7 +15,7 @@ The LZO library 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 + 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 diff --git a/release/src/router/busybox/archival/libarchive/lzo1x_d.c b/release/src/router/busybox/archival/libarchive/lzo1x_d.c index 348a85510b..9bc1270da8 100644 --- a/release/src/router/busybox/archival/libarchive/lzo1x_d.c +++ b/release/src/router/busybox/archival/libarchive/lzo1x_d.c @@ -15,7 +15,7 @@ The LZO library 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 + 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 diff --git a/release/src/router/busybox/archival/lzop.c b/release/src/router/busybox/archival/lzop.c index fbe08417df..56003d4214 100644 --- a/release/src/router/busybox/archival/lzop.c +++ b/release/src/router/busybox/archival/lzop.c @@ -14,7 +14,7 @@ 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 + 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 @@ -116,7 +116,7 @@ static NOINLINE int lzo1x_optimize(uint8_t *in, unsigned in_len, unsigned nl; unsigned long o_m1_a = 0, o_m1_b = 0, o_m2 = 0, o_m3_a = 0, o_m3_b = 0; -// LZO_UNUSED(wrkmem); +// LZO_UNUSED(wrkmem); *out_len = 0; @@ -346,11 +346,11 @@ static NOINLINE int lzo1x_optimize(uint8_t *in, unsigned in_len, return LZO_E_EOF_NOT_FOUND; eof_found: -// LZO_UNUSED(o_m1_a); LZO_UNUSED(o_m1_b); LZO_UNUSED(o_m2); -// LZO_UNUSED(o_m3_a); LZO_UNUSED(o_m3_b); +// LZO_UNUSED(o_m1_a); LZO_UNUSED(o_m1_b); LZO_UNUSED(o_m2); +// LZO_UNUSED(o_m3_a); LZO_UNUSED(o_m3_b); *out_len = pd(op, out); return (ip == ip_end ? LZO_E_OK : - (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); } /**********************************************************************/ diff --git a/release/src/router/busybox/archival/tar.c b/release/src/router/busybox/archival/tar.c index cf972c24c6..f46f7bb7a6 100644 --- a/release/src/router/busybox/archival/tar.c +++ b/release/src/router/busybox/archival/tar.c @@ -60,8 +60,8 @@ #if !ENABLE_FEATURE_SEAMLESS_GZ && !ENABLE_FEATURE_SEAMLESS_BZ2 /* Do not pass gzip flag to writeTarFile() */ -#define writeTarFile(tar_fd, verboseFlag, dereferenceFlag, include, exclude, gzip) \ - writeTarFile(tar_fd, verboseFlag, dereferenceFlag, include, exclude) +#define writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude, gzip) \ + writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude) #endif @@ -333,13 +333,13 @@ static int writeTarHeader(struct TarBallInfo *tbInfo, && (filesize <= 0x3fffffffffffffffffffffffLL) #endif ) { - /* GNU tar uses "base-256 encoding" for very large numbers. - * Encoding is binary, with highest bit always set as a marker - * and sign in next-highest bit: - * 80 00 .. 00 - zero - * bf ff .. ff - largest positive number - * ff ff .. ff - minus 1 - * c0 00 .. 00 - smallest negative number + /* GNU tar uses "base-256 encoding" for very large numbers. + * Encoding is binary, with highest bit always set as a marker + * and sign in next-highest bit: + * 80 00 .. 00 - zero + * bf ff .. ff - largest positive number + * ff ff .. ff - minus 1 + * c0 00 .. 00 - smallest negative number */ char *p8 = header.size + sizeof(header.size); do { @@ -598,7 +598,7 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip) /* gcc 4.2.1 inlines it, making code bigger */ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, - int dereferenceFlag, const llist_t *include, + int recurseFlags, const llist_t *include, const llist_t *exclude, int gzip) { int errorFlag = FALSE; @@ -621,8 +621,7 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, /* Read the directory/files and iterate over them one at a time */ while (include) { - if (!recursive_action(include->data, ACTION_RECURSE | - (dereferenceFlag ? ACTION_FOLLOWLINKS : 0), + if (!recursive_action(include->data, recurseFlags, writeFileToTarball, writeFileToTarball, &tbInfo, 0) ) { errorFlag = TRUE; @@ -662,7 +661,7 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, } #else int writeTarFile(int tar_fd, int verboseFlag, - int dereferenceFlag, const llist_t *include, + int recurseFlags, const llist_t *include, const llist_t *exclude, int gzip); #endif /* FEATURE_TAR_CREATE */ @@ -694,6 +693,7 @@ static llist_t *append_file_list_to_list(llist_t *list) //usage: "-[" IF_FEATURE_TAR_CREATE("c") "xt" //usage: IF_FEATURE_SEAMLESS_Z("Z") //usage: IF_FEATURE_SEAMLESS_GZ("z") +//usage: IF_FEATURE_SEAMLESS_XZ("J") //usage: IF_FEATURE_SEAMLESS_BZ2("j") //usage: IF_FEATURE_SEAMLESS_LZMA("a") //usage: IF_FEATURE_TAR_CREATE("h") @@ -720,6 +720,9 @@ static llist_t *append_file_list_to_list(llist_t *list) //usage: IF_FEATURE_SEAMLESS_GZ( //usage: "\n z (De)compress using gzip" //usage: ) +//usage: IF_FEATURE_SEAMLESS_XZ( +//usage: "\n J (De)compress using xz" +//usage: ) //usage: IF_FEATURE_SEAMLESS_BZ2( //usage: "\n j (De)compress using bzip2" //usage: ) @@ -749,6 +752,7 @@ static llist_t *append_file_list_to_list(llist_t *list) // o no-same-owner // p same-permissions // k keep-old +// no-recursion // numeric-owner // no-same-permissions // overwrite @@ -765,9 +769,11 @@ enum { IF_FEATURE_TAR_FROM( OPTBIT_INCLUDE_FROM,) IF_FEATURE_TAR_FROM( OPTBIT_EXCLUDE_FROM,) IF_FEATURE_SEAMLESS_GZ( OPTBIT_GZIP ,) - IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) // 16th bit + IF_FEATURE_SEAMLESS_XZ( OPTBIT_XZ ,) // 16th bit + IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) #if ENABLE_FEATURE_TAR_LONG_OPTIONS + OPTBIT_NORECURSION, IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) OPTBIT_NUMERIC_OWNER, OPTBIT_NOPRESERVE_PERM, @@ -789,14 +795,16 @@ enum { OPT_INCLUDE_FROM = IF_FEATURE_TAR_FROM( (1 << OPTBIT_INCLUDE_FROM)) + 0, // T OPT_EXCLUDE_FROM = IF_FEATURE_TAR_FROM( (1 << OPTBIT_EXCLUDE_FROM)) + 0, // X OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z + OPT_XZ = IF_FEATURE_SEAMLESS_XZ( (1 << OPTBIT_XZ )) + 0, // J OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m + OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite - OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_COMPRESS), + OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_XZ | OPT_COMPRESS), }; #if ENABLE_FEATURE_TAR_LONG_OPTIONS static const char tar_longopts[] ALIGN1 = @@ -829,12 +837,16 @@ static const char tar_longopts[] ALIGN1 = # if ENABLE_FEATURE_SEAMLESS_GZ "gzip\0" No_argument "z" # endif +# if ENABLE_FEATURE_SEAMLESS_XZ + "xz\0" No_argument "J" +# endif # if ENABLE_FEATURE_SEAMLESS_Z "compress\0" No_argument "Z" # endif # if ENABLE_FEATURE_TAR_NOPRESERVE_TIME "touch\0" No_argument "m" # endif + "no-recursion\0" No_argument "\xfa" # if ENABLE_FEATURE_TAR_TO_COMMAND "to-command\0" Required_argument "\xfb" # endif @@ -921,6 +933,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) IF_FEATURE_SEAMLESS_LZMA("a" ) IF_FEATURE_TAR_FROM( "T:X:") IF_FEATURE_SEAMLESS_GZ( "z" ) + IF_FEATURE_SEAMLESS_XZ( "J" ) IF_FEATURE_SEAMLESS_Z( "Z" ) IF_FEATURE_TAR_NOPRESERVE_TIME("m") , &base_dir // -C dir @@ -1050,7 +1063,9 @@ int tar_main(int argc UNUSED_PARAM, char **argv) zipMode = 2; #endif /* NB: writeTarFile() closes tar_handle->src_fd */ - return writeTarFile(tar_handle->src_fd, verboseFlag, opt & OPT_DEREFERENCE, + return writeTarFile(tar_handle->src_fd, verboseFlag, + (opt & OPT_DEREFERENCE ? ACTION_FOLLOWLINKS : 0) + | (opt & OPT_NORECURSION ? 0 : ACTION_RECURSE), tar_handle->accept, tar_handle->reject, zipMode); } @@ -1071,6 +1086,9 @@ int tar_main(int argc UNUSED_PARAM, char **argv) if (opt & OPT_LZMA) USE_FOR_MMU(xformer = unpack_lzma_stream;) USE_FOR_NOMMU(xformer_prog = "unlzma";) + if (opt & OPT_XZ) + USE_FOR_MMU(xformer = unpack_xz_stream;) + USE_FOR_NOMMU(xformer_prog = "unxz";) open_transformer_with_sig(tar_handle->src_fd, xformer, xformer_prog); /* Can't lseek over pipes */ diff --git a/release/src/router/busybox/archival/unzip.c b/release/src/router/busybox/archival/unzip.c index 3c76cdafcf..046027cc69 100644 --- a/release/src/router/busybox/archival/unzip.c +++ b/release/src/router/busybox/archival/unzip.c @@ -20,16 +20,16 @@ */ //usage:#define unzip_trivial_usage -//usage: "[-opts[modifiers]] FILE[.zip] [LIST] [-x XLIST] [-d DIR]" +//usage: "[-lnopq] FILE[.zip] [FILE]... [-x FILE...] [-d DIR]" //usage:#define unzip_full_usage "\n\n" -//usage: "Extract files from ZIP archives\n" -//usage: "\n -l List archive contents (with -q for short form)" -//usage: "\n -n Never overwrite files (default)" +//usage: "Extract FILEs from ZIP archive\n" +//usage: "\n -l List contents (with -q for short form)" +//usage: "\n -n Never overwrite files (default: ask)" //usage: "\n -o Overwrite" -//usage: "\n -p Send output to stdout" +//usage: "\n -p Print to stdout" //usage: "\n -q Quiet" -//usage: "\n -x XLST Exclude these files" -//usage: "\n -d DIR Extract files into DIR" +//usage: "\n -x FILE Exclude FILEs" +//usage: "\n -d DIR Extract into DIR" #include "libbb.h" #include "bb_archive.h" @@ -277,6 +277,7 @@ int unzip_main(int argc, char **argv) IF_NOT_DESKTOP(const) smallint verbose = 0; smallint listing = 0; smallint overwrite = O_PROMPT; + smallint x_opt_seen; #if ENABLE_DESKTOP uint32_t cdf_offset; #endif @@ -290,7 +291,6 @@ int unzip_main(int argc, char **argv) llist_t *zreject = NULL; char *base_dir = NULL; int i, opt; - int opt_range = 0; char key_buf[80]; struct stat stat_buf; @@ -335,81 +335,81 @@ int unzip_main(int argc, char **argv) * 204372 1 file */ + x_opt_seen = 0; /* '-' makes getopt return 1 for non-options */ while ((opt = getopt(argc, argv, "-d:lnopqxv")) != -1) { - switch (opt_range) { - case 0: /* Options */ - switch (opt) { - case 'l': /* List */ - listing = 1; - break; + switch (opt) { + case 'd': /* Extract to base directory */ + base_dir = optarg; + break; - case 'n': /* Never overwrite existing files */ - overwrite = O_NEVER; - break; + case 'l': /* List */ + listing = 1; + break; - case 'o': /* Always overwrite existing files */ - overwrite = O_ALWAYS; - break; + case 'n': /* Never overwrite existing files */ + overwrite = O_NEVER; + break; - case 'p': /* Extract files to stdout and fall through to set verbosity */ - dst_fd = STDOUT_FILENO; + case 'o': /* Always overwrite existing files */ + overwrite = O_ALWAYS; + break; - case 'q': /* Be quiet */ - quiet++; - break; + case 'p': /* Extract files to stdout and fall through to set verbosity */ + dst_fd = STDOUT_FILENO; - case 'v': /* Verbose list */ - IF_DESKTOP(verbose++;) - listing = 1; - break; + case 'q': /* Be quiet */ + quiet++; + break; - case 1: /* The zip file */ - /* +5: space for ".zip" and NUL */ - src_fn = xmalloc(strlen(optarg) + 5); - strcpy(src_fn, optarg); - opt_range++; - break; + case 'v': /* Verbose list */ + IF_DESKTOP(verbose++;) + listing = 1; + break; - default: - bb_show_usage(); - } + case 'x': + x_opt_seen = 1; break; - case 1: /* Include files */ - if (opt == 1) { + case 1: + if (!src_fn) { + /* The zip file */ + /* +5: space for ".zip" and NUL */ + src_fn = xmalloc(strlen(optarg) + 5); + strcpy(src_fn, optarg); + } else if (!x_opt_seen) { + /* Include files */ llist_add_to(&zaccept, optarg); - break; - } - if (opt == 'd') { - base_dir = optarg; - opt_range += 2; - break; - } - if (opt == 'x') { - opt_range++; - break; - } - bb_show_usage(); - - case 2 : /* Exclude files */ - if (opt == 1) { + } else { + /* Exclude files */ llist_add_to(&zreject, optarg); - break; } - if (opt == 'd') { /* Extract to base directory */ - base_dir = optarg; - opt_range++; - break; - } - /* fall through */ + break; default: bb_show_usage(); } } - if (src_fn == NULL) { +#ifndef __GLIBC__ + /* + * This code is needed for non-GNU getopt + * which doesn't understand "-" in option string. + * The -x option won't work properly in this case: + * "unzip a.zip q -x w e" will be interpreted as + * "unzip a.zip q w e -x" = "unzip a.zip q w e" + */ + argv += optind; + if (argv[0]) { + /* +5: space for ".zip" and NUL */ + src_fn = xmalloc(strlen(argv[0]) + 5); + strcpy(src_fn, argv[0]); + while (*++argv) + llist_add_to(&zaccept, *argv); + } +#endif + + if (!src_fn) { bb_show_usage(); } @@ -420,17 +420,20 @@ int unzip_main(int argc, char **argv) if (overwrite == O_PROMPT) overwrite = O_NEVER; } else { - static const char extn[][5] = {"", ".zip", ".ZIP"}; - int orig_src_fn_len = strlen(src_fn); - int src_fd = -1; + static const char extn[][5] = { ".zip", ".ZIP" }; + char *ext = src_fn + strlen(src_fn); + int src_fd; - for (i = 0; (i < 3) && (src_fd == -1); i++) { - strcpy(src_fn + orig_src_fn_len, extn[i]); + i = 0; + for (;;) { src_fd = open(src_fn, O_RDONLY); - } - if (src_fd == -1) { - src_fn[orig_src_fn_len] = '\0'; - bb_error_msg_and_die("can't open %s, %s.zip, %s.ZIP", src_fn, src_fn, src_fn); + if (src_fd >= 0) + break; + if (++i > 2) { + *ext = '\0'; + bb_error_msg_and_die("can't open %s[.zip]", src_fn); + } + strcpy(ext, extn[i - 1]); } xmove_fd(src_fd, zip_fd); } @@ -596,7 +599,7 @@ int unzip_main(int argc, char **argv) printf(" creating: %s\n", dst_fn); } unzip_create_leading_dirs(dst_fn); - if (bb_make_directory(dst_fn, dir_mode, 0)) { + if (bb_make_directory(dst_fn, dir_mode, FILEUTILS_IGNORE_CHMOD_ERR)) { xfunc_die(); } } else { diff --git a/release/src/router/busybox/config_base b/release/src/router/busybox/config_base index 301096957b..f14cdd97e4 100644 --- a/release/src/router/busybox/config_base +++ b/release/src/router/busybox/config_base @@ -43,6 +43,7 @@ CONFIG_FEATURE_DEVPTS=y # CONFIG_FEATURE_WTMP is not set # CONFIG_FEATURE_UTMP is not set CONFIG_FEATURE_PIDFILE=y +CONFIG_PID_FILE_PATH="/var/run" CONFIG_FEATURE_SUID=y # CONFIG_FEATURE_SUID_CONFIG is not set # CONFIG_FEATURE_SUID_CONFIG_QUIET is not set @@ -97,6 +98,7 @@ CONFIG_PREFIX="./_install" # CONFIG_FEATURE_RTMINMAX is not set CONFIG_PASSWORD_MINLEN=6 CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 CONFIG_FEATURE_FAST_TOP=y # CONFIG_FEATURE_ETC_NETWORKS is not set CONFIG_FEATURE_USE_TERMIOS=y @@ -264,6 +266,7 @@ CONFIG_RMDIR=y # CONFIG_SHA1SUM is not set # CONFIG_SHA256SUM is not set # CONFIG_SHA512SUM is not set +# CONFIG_SHA3SUM is not set CONFIG_SLEEP=y CONFIG_FEATURE_FANCY_SLEEP=y # CONFIG_FEATURE_FLOAT_SLEEP is not set @@ -620,6 +623,7 @@ CONFIG_FEATURE_VOLUMEID_EXFAT=y CONFIG_FEATURE_VOLUMEID_HFS=y # CONFIG_FEATURE_VOLUMEID_JFS is not set # CONFIG_FEATURE_VOLUMEID_XFS is not set +# CONFIG_FEATURE_VOLUMEID_NILFS is not set CONFIG_FEATURE_VOLUMEID_NTFS=y # CONFIG_FEATURE_VOLUMEID_ISO9660 is not set # CONFIG_FEATURE_VOLUMEID_UDF is not set @@ -846,6 +850,7 @@ CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y # CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set CONFIG_DHCPD_LEASES_FILE="" CONFIG_UDHCPC=y +# CONFIG_UDHCPC_OLD is not set # CONFIG_FEATURE_UDHCPC_ARPING is not set CONFIG_FEATURE_UDHCP_PORT=y CONFIG_UDHCP_DEBUG=0 @@ -1018,6 +1023,7 @@ CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=256 CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 # CONFIG_LOGREAD is not set # CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_FEATURE_KMSG_SYSLOG is not set CONFIG_KLOGD=y CONFIG_FEATURE_KLOGD_KLOGCTL=y CONFIG_LOGGER=y diff --git a/release/src/router/busybox/config_nc b/release/src/router/busybox/config_nc deleted file mode 100644 index a6310d00d0..0000000000 --- a/release/src/router/busybox/config_nc +++ /dev/null @@ -1,1021 +0,0 @@ -# -# Automatically generated make config: don't edit -# Busybox version: 1.20.2 -# Mon Jan 21 02:12:11 2013 - -# -CONFIG_HAVE_DOT_CONFIG=y - -# -# Busybox Settings -# - -# -# General Configuration -# -# CONFIG_DESKTOP is not set -# CONFIG_EXTRA_COMPAT is not set -# CONFIG_INCLUDE_SUSv2 is not set -# CONFIG_USE_PORTABLE_CODE is not set -CONFIG_PLATFORM_LINUX=y -CONFIG_FEATURE_BUFFERS_USE_MALLOC=y -# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set -# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set -CONFIG_SHOW_USAGE=y -# CONFIG_FEATURE_COMPRESS_USAGE is not set -# CONFIG_FEATURE_INSTALLER is not set -# CONFIG_INSTALL_NO_USR is not set -# CONFIG_LOCALE_SUPPORT is not set -CONFIG_UNICODE_SUPPORT=y -# CONFIG_UNICODE_USING_LOCALE is not set -# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set -CONFIG_SUBST_WCHAR=0 -CONFIG_LAST_SUPPORTED_WCHAR=0 -# CONFIG_UNICODE_COMBINING_WCHARS is not set -# CONFIG_UNICODE_WIDE_WCHARS is not set -# CONFIG_UNICODE_BIDI_SUPPORT is not set -# CONFIG_UNICODE_NEUTRAL_TABLE is not set -# CONFIG_UNICODE_PRESERVE_BROKEN is not set -CONFIG_LONG_OPTS=y -CONFIG_FEATURE_DEVPTS=y -# CONFIG_FEATURE_CLEAN_UP is not set -# CONFIG_FEATURE_WTMP is not set -# CONFIG_FEATURE_UTMP is not set -CONFIG_FEATURE_PIDFILE=y -CONFIG_FEATURE_SUID=y -# CONFIG_FEATURE_SUID_CONFIG is not set -# CONFIG_FEATURE_SUID_CONFIG_QUIET is not set -# CONFIG_SELINUX is not set -# CONFIG_FEATURE_PREFER_APPLETS is not set -CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" -CONFIG_FEATURE_SYSLOG=y -# CONFIG_FEATURE_HAVE_RPC is not set - -# -# Build Options -# -# CONFIG_STATIC is not set -# CONFIG_PIE is not set -# CONFIG_NOMMU is not set -# CONFIG_BUILD_LIBBUSYBOX is not set -# CONFIG_FEATURE_INDIVIDUAL is not set -# CONFIG_FEATURE_SHARED_BUSYBOX is not set -CONFIG_LFS=y -CONFIG_CROSS_COMPILER_PREFIX="mipsel-uclibc-" -CONFIG_SYSROOT="" -CONFIG_EXTRA_CFLAGS="" -CONFIG_EXTRA_LDFLAGS="" -CONFIG_EXTRA_LDLIBS="" - -# -# Debugging Options -# -# CONFIG_DEBUG is not set -# CONFIG_DEBUG_PESSIMIZE is not set -# CONFIG_WERROR is not set -CONFIG_NO_DEBUG_LIB=y -# CONFIG_DMALLOC is not set -# CONFIG_EFENCE is not set - -# -# Installation Options ("make install" behavior) -# -CONFIG_INSTALL_APPLET_SYMLINKS=y -# CONFIG_INSTALL_APPLET_HARDLINKS is not set -# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set -# CONFIG_INSTALL_APPLET_DONT is not set -# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set -# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set -# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set -CONFIG_PREFIX="./_install" - -# -# Busybox Library Tuning -# -# CONFIG_FEATURE_SYSTEMD is not set -# CONFIG_FEATURE_RTMINMAX is not set -CONFIG_PASSWORD_MINLEN=6 -CONFIG_MD5_SMALL=1 -CONFIG_FEATURE_FAST_TOP=y -# CONFIG_FEATURE_ETC_NETWORKS is not set -CONFIG_FEATURE_USE_TERMIOS=y -CONFIG_FEATURE_EDITING=y -CONFIG_FEATURE_EDITING_MAX_LEN=1024 -# CONFIG_FEATURE_EDITING_VI is not set -CONFIG_FEATURE_EDITING_HISTORY=50 -CONFIG_FEATURE_EDITING_SAVEHISTORY=y -# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set -# CONFIG_FEATURE_REVERSE_SEARCH is not set -CONFIG_FEATURE_TAB_COMPLETION=y -# CONFIG_FEATURE_USERNAME_COMPLETION is not set -CONFIG_FEATURE_EDITING_FANCY_PROMPT=y -# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set -CONFIG_FEATURE_NON_POSIX_CP=y -# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set -CONFIG_FEATURE_COPYBUF_KB=4 -CONFIG_FEATURE_SKIP_ROOTFS=y -# CONFIG_MONOTONIC_SYSCALL is not set -CONFIG_IOCTL_HEX2STR_ERROR=y -# CONFIG_FEATURE_HWIB is not set - -# -# Applets -# - -# -# Archival Utilities -# -# CONFIG_FEATURE_SEAMLESS_XZ is not set -# CONFIG_FEATURE_SEAMLESS_LZMA is not set -CONFIG_FEATURE_SEAMLESS_BZ2=y -CONFIG_FEATURE_SEAMLESS_GZ=y -# CONFIG_FEATURE_SEAMLESS_Z is not set -# CONFIG_AR is not set -# CONFIG_FEATURE_AR_LONG_FILENAMES is not set -# CONFIG_FEATURE_AR_CREATE is not set -# CONFIG_BUNZIP2 is not set -# CONFIG_BZIP2 is not set -# CONFIG_CPIO is not set -# CONFIG_FEATURE_CPIO_O is not set -# CONFIG_FEATURE_CPIO_P is not set -# CONFIG_DPKG is not set -# CONFIG_DPKG_DEB is not set -# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set -CONFIG_GUNZIP=y -CONFIG_GZIP=y -# CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set -CONFIG_GZIP_FAST=0 -# CONFIG_LZOP is not set -# CONFIG_LZOP_COMPR_HIGH is not set -# CONFIG_RPM2CPIO is not set -# CONFIG_RPM is not set -CONFIG_TAR=y -CONFIG_FEATURE_TAR_CREATE=y -# CONFIG_FEATURE_TAR_AUTODETECT is not set -CONFIG_FEATURE_TAR_FROM=y -CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y -# CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY is not set -CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y -# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set -# CONFIG_FEATURE_TAR_TO_COMMAND is not set -# CONFIG_FEATURE_TAR_UNAME_GNAME is not set -# CONFIG_FEATURE_TAR_NOPRESERVE_TIME is not set -# CONFIG_FEATURE_TAR_SELINUX is not set -# CONFIG_UNCOMPRESS is not set -# CONFIG_UNLZMA is not set -# CONFIG_FEATURE_LZMA_FAST is not set -# CONFIG_LZMA is not set -# CONFIG_UNXZ is not set -# CONFIG_XZ is not set -CONFIG_UNZIP=y - -# -# Coreutils -# -CONFIG_BASENAME=y -CONFIG_CAT=y -CONFIG_DATE=y -CONFIG_FEATURE_DATE_ISOFMT=y -# CONFIG_FEATURE_DATE_NANO is not set -CONFIG_FEATURE_DATE_COMPAT=y -# CONFIG_HOSTID is not set -# CONFIG_ID is not set -# CONFIG_GROUPS is not set -CONFIG_TEST=y -CONFIG_FEATURE_TEST_64=y -CONFIG_TOUCH=y -# CONFIG_FEATURE_TOUCH_SUSV3 is not set -CONFIG_TR=y -# CONFIG_FEATURE_TR_CLASSES is not set -# CONFIG_FEATURE_TR_EQUIV is not set -# CONFIG_BASE64 is not set -# CONFIG_WHO is not set -# CONFIG_USERS is not set -# CONFIG_CAL is not set -# CONFIG_CATV is not set -# CONFIG_CHGRP is not set -CONFIG_CHMOD=y -CONFIG_CHOWN=y -# CONFIG_FEATURE_CHOWN_LONG_OPTIONS is not set -CONFIG_CHROOT=y -# CONFIG_CKSUM is not set -# CONFIG_COMM is not set -CONFIG_CP=y -# CONFIG_FEATURE_CP_LONG_OPTIONS is not set -CONFIG_CUT=y -CONFIG_DD=y -CONFIG_FEATURE_DD_SIGNAL_HANDLING=y -# CONFIG_FEATURE_DD_THIRD_STATUS_LINE is not set -CONFIG_FEATURE_DD_IBS_OBS=y -CONFIG_DF=y -# CONFIG_FEATURE_DF_FANCY is not set -CONFIG_DIRNAME=y -# CONFIG_DOS2UNIX is not set -# CONFIG_UNIX2DOS is not set -CONFIG_DU=y -CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y -CONFIG_ECHO=y -CONFIG_FEATURE_FANCY_ECHO=y -CONFIG_ENV=y -# CONFIG_FEATURE_ENV_LONG_OPTIONS is not set -# CONFIG_EXPAND is not set -# CONFIG_FEATURE_EXPAND_LONG_OPTIONS is not set -CONFIG_EXPR=y -CONFIG_EXPR_MATH_SUPPORT_64=y -# CONFIG_FALSE is not set -# CONFIG_FOLD is not set -CONFIG_HEAD=y -CONFIG_FEATURE_FANCY_HEAD=y -# CONFIG_INSTALL is not set -# CONFIG_FEATURE_INSTALL_LONG_OPTIONS is not set -CONFIG_LN=y -# CONFIG_LOGNAME is not set -CONFIG_LS=y -CONFIG_FEATURE_LS_FILETYPES=y -CONFIG_FEATURE_LS_FOLLOWLINKS=y -CONFIG_FEATURE_LS_RECURSIVE=y -CONFIG_FEATURE_LS_SORTFILES=y -CONFIG_FEATURE_LS_TIMESTAMPS=y -CONFIG_FEATURE_LS_USERNAME=y -CONFIG_MD5SUM=y -CONFIG_MKDIR=y -# CONFIG_FEATURE_MKDIR_LONG_OPTIONS is not set -CONFIG_MV=y -# CONFIG_FEATURE_MV_LONG_OPTIONS is not set -CONFIG_NOHUP=y -# CONFIG_OD is not set -# CONFIG_PRINTENV is not set -CONFIG_PRINTF=y -CONFIG_PWD=y -# CONFIG_READLINK is not set -# CONFIG_FEATURE_READLINK_FOLLOW is not set -# CONFIG_REALPATH is not set -CONFIG_RM=y -CONFIG_RMDIR=y -# CONFIG_FEATURE_RMDIR_LONG_OPTIONS is not set -# CONFIG_SEQ is not set -# CONFIG_SHA1SUM is not set -# CONFIG_SHA256SUM is not set -# CONFIG_SHA512SUM is not set -CONFIG_SLEEP=y -CONFIG_FEATURE_FANCY_SLEEP=y -# CONFIG_FEATURE_FLOAT_SLEEP is not set -CONFIG_SORT=y -# CONFIG_SPLIT is not set -# CONFIG_FEATURE_SPLIT_FANCY is not set -# CONFIG_STAT is not set -# CONFIG_FEATURE_STAT_FORMAT is not set -# CONFIG_STTY is not set -# CONFIG_SUM is not set -CONFIG_SYNC=y -# CONFIG_TAC is not set -CONFIG_TAIL=y -CONFIG_FEATURE_FANCY_TAIL=y -# CONFIG_TEE is not set -# CONFIG_FEATURE_TEE_USE_BLOCK_IO is not set -CONFIG_TOUCH=y -CONFIG_TRUE=y -# CONFIG_TTY is not set -CONFIG_UNAME=y -# CONFIG_UNEXPAND is not set -# CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set -# CONFIG_UNIQ is not set -CONFIG_USLEEP=y -# CONFIG_UUDECODE is not set -# CONFIG_UUENCODE is not set -CONFIG_WC=y -CONFIG_FEATURE_WC_LARGE=y -# CONFIG_WHOAMI is not set -# CONFIG_YES is not set - -# -# Common options for cp and mv -# -CONFIG_FEATURE_PRESERVE_HARDLINKS=y - -# -# Common options for ls, more and telnet -# -CONFIG_FEATURE_AUTOWIDTH=y - -# -# Common options for df, du, ls -# -CONFIG_FEATURE_HUMAN_READABLE=y - -# -# Common options for md5sum, sha1sum, sha256sum, sha512sum -# -# CONFIG_FEATURE_MD5_SHA1_SUM_CHECK is not set - -# -# Console Utilities -# -# CONFIG_CHVT is not set -# CONFIG_FGCONSOLE is not set -# CONFIG_DEALLOCVT is not set -# CONFIG_DUMPKMAP is not set -# CONFIG_KBD_MODE is not set -# CONFIG_LOADFONT is not set -# CONFIG_LOADKMAP is not set -# CONFIG_OPENVT is not set -# CONFIG_RESET is not set -# CONFIG_RESIZE is not set -# CONFIG_FEATURE_RESIZE_PRINT is not set -# CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set -# CONFIG_SETFONT is not set -# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set -CONFIG_DEFAULT_SETFONT_DIR="" -# CONFIG_SETKEYCODES is not set -# CONFIG_SETLOGCONS is not set -# CONFIG_SHOWKEY is not set -# CONFIG_FEATURE_LOADFONT_PSF2 is not set -# CONFIG_FEATURE_LOADFONT_RAW is not set - -# -# Debian Utilities -# -# CONFIG_MKTEMP is not set -# CONFIG_PIPE_PROGRESS is not set -# CONFIG_RUN_PARTS is not set -# CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set -# CONFIG_FEATURE_RUN_PARTS_FANCY is not set -# CONFIG_START_STOP_DAEMON is not set -# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set -# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set -CONFIG_WHICH=y - -# -# Editors -# -# CONFIG_PATCH is not set -CONFIG_AWK=y -CONFIG_FEATURE_AWK_LIBM=y -CONFIG_CMP=y -# CONFIG_DIFF is not set -# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set -# CONFIG_FEATURE_DIFF_DIR is not set -# CONFIG_ED is not set -CONFIG_SED=y -CONFIG_VI=y -CONFIG_FEATURE_VI_MAX_LEN=4096 -# CONFIG_FEATURE_VI_8BIT is not set -CONFIG_FEATURE_VI_COLON=y -CONFIG_FEATURE_VI_YANKMARK=y -CONFIG_FEATURE_VI_SEARCH=y -# CONFIG_FEATURE_VI_REGEX_SEARCH is not set -CONFIG_FEATURE_VI_USE_SIGNALS=y -CONFIG_FEATURE_VI_DOT_CMD=y -CONFIG_FEATURE_VI_READONLY=y -CONFIG_FEATURE_VI_SETOPTS=y -CONFIG_FEATURE_VI_SET=y -CONFIG_FEATURE_VI_WIN_RESIZE=y -CONFIG_FEATURE_VI_ASK_TERMINAL=y -# CONFIG_FEATURE_VI_OPTIMIZE_CURSOR is not set -CONFIG_FEATURE_ALLOW_EXEC=y - -# -# Finding Utilities -# -CONFIG_FIND=y -CONFIG_FEATURE_FIND_PRINT0=y -# CONFIG_FEATURE_FIND_MTIME is not set -# CONFIG_FEATURE_FIND_MMIN is not set -# CONFIG_FEATURE_FIND_PERM is not set -# CONFIG_FEATURE_FIND_TYPE is not set -# CONFIG_FEATURE_FIND_XDEV is not set -# CONFIG_FEATURE_FIND_MAXDEPTH is not set -# CONFIG_FEATURE_FIND_NEWER is not set -# CONFIG_FEATURE_FIND_INUM is not set -CONFIG_FEATURE_FIND_EXEC=y -# CONFIG_FEATURE_FIND_USER is not set -# CONFIG_FEATURE_FIND_GROUP is not set -CONFIG_FEATURE_FIND_NOT=y -# CONFIG_FEATURE_FIND_DEPTH is not set -# CONFIG_FEATURE_FIND_PAREN is not set -# CONFIG_FEATURE_FIND_SIZE is not set -# CONFIG_FEATURE_FIND_PRUNE is not set -# CONFIG_FEATURE_FIND_DELETE is not set -# CONFIG_FEATURE_FIND_PATH is not set -# CONFIG_FEATURE_FIND_REGEX is not set -# CONFIG_FEATURE_FIND_CONTEXT is not set -# CONFIG_FEATURE_FIND_LINKS is not set -CONFIG_GREP=y -CONFIG_FEATURE_GREP_EGREP_ALIAS=y -CONFIG_FEATURE_GREP_FGREP_ALIAS=y -CONFIG_FEATURE_GREP_CONTEXT=y -# CONFIG_XARGS is not set -# CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION is not set -# CONFIG_FEATURE_XARGS_SUPPORT_QUOTES is not set -# CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT is not set -# CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM is not set - -# -# Init Utilities -# -# CONFIG_BOOTCHARTD is not set -# CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set -# CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set -# CONFIG_HALT is not set -# CONFIG_FEATURE_CALL_TELINIT is not set -CONFIG_TELINIT_PATH="" -# CONFIG_INIT is not set -# CONFIG_FEATURE_USE_INITTAB is not set -# CONFIG_FEATURE_KILL_REMOVED is not set -CONFIG_FEATURE_KILL_DELAY=0 -# CONFIG_FEATURE_INIT_SCTTY is not set -# CONFIG_FEATURE_INIT_SYSLOG is not set -# CONFIG_FEATURE_EXTRA_QUIET is not set -# CONFIG_FEATURE_INIT_COREDUMPS is not set -# CONFIG_FEATURE_INITRD is not set -CONFIG_INIT_TERMINAL_TYPE="" -# CONFIG_MESG is not set -# CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP is not set - -# -# Login/Password Management Utilities -# -# CONFIG_ADD_SHELL is not set -# CONFIG_REMOVE_SHELL is not set -CONFIG_FEATURE_SHADOWPASSWDS=y -CONFIG_USE_BB_PWD_GRP=y -CONFIG_USE_BB_SHADOW=y -# CONFIG_USE_BB_CRYPT is not set -# CONFIG_USE_BB_CRYPT_SHA is not set -# CONFIG_ADDUSER is not set -# CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set -# CONFIG_FEATURE_CHECK_NAMES is not set -CONFIG_FIRST_SYSTEM_ID=0 -CONFIG_LAST_SYSTEM_ID=0 -# CONFIG_ADDGROUP is not set -# CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set -# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set -# CONFIG_DELUSER is not set -# CONFIG_DELGROUP is not set -# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set -# CONFIG_GETTY is not set -CONFIG_LOGIN=y -# CONFIG_LOGIN_SESSION_AS_CHILD is not set -# CONFIG_PAM is not set -# CONFIG_LOGIN_SCRIPTS is not set -# CONFIG_FEATURE_NOLOGIN is not set -# CONFIG_FEATURE_SECURETTY is not set -# CONFIG_PASSWD is not set -# CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set -# CONFIG_CRYPTPW is not set -# CONFIG_CHPASSWD is not set -# CONFIG_SU is not set -# CONFIG_FEATURE_SU_SYSLOG is not set -# CONFIG_FEATURE_SU_CHECKS_SHELLS is not set -# CONFIG_SULOGIN is not set -# CONFIG_VLOCK is not set - -# -# Linux Ext2 FS Progs -# -# CONFIG_CHATTR is not set -# CONFIG_FSCK is not set -# CONFIG_LSATTR is not set - -# -# Linux Module Utilities -# -# CONFIG_MODINFO is not set -# CONFIG_MODPROBE_SMALL is not set -# CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE is not set -# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set -CONFIG_INSMOD=y -CONFIG_RMMOD=y -CONFIG_LSMOD=y -CONFIG_MODPROBE=y -# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set -# CONFIG_DEPMOD is not set - -# -# Options common to multiple modutils -# -# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set -# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set -# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set -# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set -# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set -# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set -CONFIG_FEATURE_CHECK_TAINTED_MODULE=y -# CONFIG_FEATURE_MODUTILS_ALIAS is not set -# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set -CONFIG_DEFAULT_MODULES_DIR="/lib/modules" -CONFIG_DEFAULT_DEPMOD_FILE="/lib/modules/modules.dep" - -# -# Linux System Utilities -# -# CONFIG_BLOCKDEV is not set -# CONFIG_REV is not set -# CONFIG_ACPID is not set -# CONFIG_FEATURE_ACPID_COMPAT is not set -CONFIG_BLKID=y -# CONFIG_FEATURE_BLKID_TYPE is not set -CONFIG_DMESG=y -CONFIG_FEATURE_DMESG_PRETTY=y -# CONFIG_FBSET is not set -# CONFIG_FEATURE_FBSET_FANCY is not set -# CONFIG_FEATURE_FBSET_READMODE is not set -# CONFIG_FDFLUSH is not set -# CONFIG_FDFORMAT is not set -# CONFIG_FEATURE_AIX_LABEL is not set -# CONFIG_FEATURE_SGI_LABEL is not set -# CONFIG_FEATURE_SUN_LABEL is not set -# CONFIG_FEATURE_OSF_LABEL is not set -CONFIG_FEATURE_GPT_LABEL=y -# CONFIG_FEATURE_FDISK_ADVANCED is not set -# CONFIG_FINDFS is not set -# CONFIG_FREERAMDISK is not set -# CONFIG_FSCK_MINIX is not set -# CONFIG_MKFS_EXT2 is not set -# CONFIG_MKFS_MINIX is not set -# CONFIG_FEATURE_MINIX2 is not set -# CONFIG_MKFS_REISER is not set -# CONFIG_GETOPT is not set -# CONFIG_FEATURE_GETOPT_LONG is not set -# CONFIG_HEXDUMP is not set -# CONFIG_FEATURE_HEXDUMP_REVERSE is not set -# CONFIG_HD is not set -# CONFIG_HWCLOCK is not set -# CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS is not set -# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set -# CONFIG_IPCRM is not set -# CONFIG_IPCS is not set -# CONFIG_LOSETUP is not set -# CONFIG_LSPCI is not set -# CONFIG_MDEV is not set -# CONFIG_FEATURE_MDEV_CONF is not set -# CONFIG_FEATURE_MDEV_RENAME is not set -# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set -# CONFIG_FEATURE_MDEV_EXEC is not set -# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set -CONFIG_FEATURE_MKSWAP_UUID=y -CONFIG_MORE=y -CONFIG_MOUNT=y -# CONFIG_FEATURE_MOUNT_FAKE is not set -# CONFIG_FEATURE_MOUNT_VERBOSE is not set -CONFIG_FEATURE_MOUNT_HELPERS=y -CONFIG_FEATURE_MOUNT_LABEL=y -# CONFIG_FEATURE_MOUNT_NFS is not set -CONFIG_FEATURE_MOUNT_CIFS=y -CONFIG_FEATURE_MOUNT_FLAGS=y -CONFIG_FEATURE_MOUNT_FSTAB=y -# CONFIG_PIVOT_ROOT is not set -# CONFIG_RDATE is not set -# CONFIG_RDEV is not set -# CONFIG_READPROFILE is not set -# CONFIG_RTCWAKE is not set -# CONFIG_SCRIPT is not set -# CONFIG_SCRIPTREPLAY is not set -# CONFIG_SETARCH is not set -CONFIG_SWAPONOFF=y -# CONFIG_FEATURE_SWAPON_PRI is not set -# CONFIG_SWITCH_ROOT is not set -CONFIG_UMOUNT=y -# CONFIG_FEATURE_UMOUNT_ALL is not set - -# -# Common options for mount/umount -# -CONFIG_FEATURE_MOUNT_LOOP=y -CONFIG_FEATURE_MOUNT_LOOP_CREATE=y -# CONFIG_FEATURE_MTAB_SUPPORT is not set -CONFIG_VOLUMEID=y - -# -# Filesystem/Volume identification -# -CONFIG_FEATURE_VOLUMEID_EXT=y -# CONFIG_FEATURE_VOLUMEID_BTRFS is not set -# CONFIG_FEATURE_VOLUMEID_REISERFS is not set -CONFIG_FEATURE_VOLUMEID_FAT=y -CONFIG_FEATURE_VOLUMEID_HFS=y -# CONFIG_FEATURE_VOLUMEID_JFS is not set -# CONFIG_FEATURE_VOLUMEID_XFS is not set -CONFIG_FEATURE_VOLUMEID_NTFS=y -# CONFIG_FEATURE_VOLUMEID_ISO9660 is not set -# CONFIG_FEATURE_VOLUMEID_UDF is not set -# CONFIG_FEATURE_VOLUMEID_LUKS is not set -CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y -# CONFIG_FEATURE_VOLUMEID_CRAMFS is not set -# CONFIG_FEATURE_VOLUMEID_ROMFS is not set -# CONFIG_FEATURE_VOLUMEID_SYSV is not set -# CONFIG_FEATURE_VOLUMEID_OCFS2 is not set -# CONFIG_FEATURE_VOLUMEID_LINUXRAID is not set - -# -# Miscellaneous Utilities -# -# CONFIG_CONSPY is not set -# CONFIG_NANDWRITE is not set -# CONFIG_NANDDUMP is not set -# CONFIG_SETSERIAL is not set -# CONFIG_UBIATTACH is not set -# CONFIG_UBIDETACH is not set -# CONFIG_UBIMKVOL is not set -# CONFIG_UBIRMVOL is not set -# CONFIG_UBIRSVOL is not set -# CONFIG_UBIUPDATEVOL is not set -# CONFIG_ADJTIMEX is not set -# CONFIG_BBCONFIG is not set -# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set -# CONFIG_BEEP is not set -CONFIG_FEATURE_BEEP_FREQ=0 -CONFIG_FEATURE_BEEP_LENGTH_MS=0 -# CONFIG_CHAT is not set -# CONFIG_FEATURE_CHAT_NOFAIL is not set -# CONFIG_FEATURE_CHAT_TTY_HIFI is not set -# CONFIG_FEATURE_CHAT_IMPLICIT_CR is not set -# CONFIG_FEATURE_CHAT_SWALLOW_OPTS is not set -# CONFIG_FEATURE_CHAT_SEND_ESCAPES is not set -# CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set -# CONFIG_FEATURE_CHAT_CLR_ABORT is not set -# CONFIG_CHRT is not set -CONFIG_CROND=y -# CONFIG_FEATURE_CROND_D is not set -# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set -CONFIG_FEATURE_CROND_DIR="/var/spool/cron" -# CONFIG_CRONTAB is not set -# CONFIG_DC is not set -# CONFIG_FEATURE_DC_LIBM is not set -# CONFIG_DEVFSD is not set -# CONFIG_DEVFSD_MODLOAD is not set -# CONFIG_DEVFSD_FG_NP is not set -# CONFIG_DEVFSD_VERBOSE is not set -# CONFIG_DEVMEM is not set -# CONFIG_EJECT is not set -# CONFIG_FEATURE_EJECT_SCSI is not set -# CONFIG_FBSPLASH is not set -# CONFIG_FLASHCP is not set -# CONFIG_FLASH_LOCK is not set -# CONFIG_FLASH_UNLOCK is not set -# CONFIG_FLASH_ERASEALL is not set -# CONFIG_IONICE is not set -# CONFIG_INOTIFYD is not set -# CONFIG_LAST is not set -# CONFIG_FEATURE_LAST_SMALL is not set -# CONFIG_FEATURE_LAST_FANCY is not set -CONFIG_LESS=y -CONFIG_FEATURE_LESS_MAXLINES=9999999 -# CONFIG_FEATURE_LESS_BRACKETS is not set -# CONFIG_FEATURE_LESS_FLAGS is not set -# CONFIG_FEATURE_LESS_MARKS is not set -# CONFIG_FEATURE_LESS_REGEXP is not set -# CONFIG_FEATURE_LESS_WINCH is not set -# CONFIG_FEATURE_LESS_DASHCMD is not set -# CONFIG_FEATURE_LESS_LINENUMS is not set -# CONFIG_HDPARM is not set -# CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set -# CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set -# CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF is not set -# CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set -# CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set -# CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set -# CONFIG_MAKEDEVS is not set -# CONFIG_FEATURE_MAKEDEVS_LEAF is not set -# CONFIG_FEATURE_MAKEDEVS_TABLE is not set -# CONFIG_MAN is not set -# CONFIG_MICROCOM is not set -# CONFIG_MOUNTPOINT is not set -# CONFIG_MT is not set -# CONFIG_RAIDAUTORUN is not set -# CONFIG_READAHEAD is not set -# CONFIG_RFKILL is not set -# CONFIG_RUNLEVEL is not set -# CONFIG_RX is not set -# CONFIG_SETSID is not set -CONFIG_STRINGS=y -# CONFIG_TASKSET is not set -# CONFIG_FEATURE_TASKSET_FANCY is not set -# CONFIG_TIME is not set -# CONFIG_TIMEOUT is not set -# CONFIG_TTYSIZE is not set -# CONFIG_VOLNAME is not set -# CONFIG_WALL is not set -# CONFIG_WATCHDOG is not set - -# -# Networking Utilities -# -# CONFIG_NBDCLIENT is not set -CONFIG_NC=y -# CONFIG_NC_SERVER is not set -CONFIG_NC_EXTRA=y -# CONFIG_NC_110_COMPAT is not set -# CONFIG_WHOIS is not set -# CONFIG_FEATURE_UNIX_LOCAL is not set -CONFIG_FEATURE_PREFER_IPV4_ADDRESS=y -# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set -CONFIG_ARP=y -CONFIG_ARPING=y -# CONFIG_BRCTL is not set -# CONFIG_FEATURE_BRCTL_FANCY is not set -# CONFIG_FEATURE_BRCTL_SHOW is not set -# CONFIG_DNSD is not set -CONFIG_ETHER_WAKE=y -# CONFIG_FAKEIDENTD is not set -# CONFIG_FTPD is not set -# CONFIG_FEATURE_FTP_WRITE is not set -# CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set -# CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set -# CONFIG_HOSTNAME is not set -# CONFIG_HTTPD is not set -# CONFIG_FEATURE_HTTPD_RANGES is not set -# CONFIG_FEATURE_HTTPD_USE_SENDFILE is not set -# CONFIG_FEATURE_HTTPD_SETUID is not set -# CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set -# CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set -# CONFIG_FEATURE_HTTPD_CGI is not set -# CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR is not set -# CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV is not set -# CONFIG_FEATURE_HTTPD_ENCODE_URL_STR is not set -# CONFIG_FEATURE_HTTPD_ERROR_PAGES is not set -# CONFIG_FEATURE_HTTPD_PROXY is not set -# CONFIG_FEATURE_HTTPD_GZIP is not set -CONFIG_IFCONFIG=y -CONFIG_FEATURE_IFCONFIG_STATUS=y -# CONFIG_FEATURE_IFCONFIG_SLIP is not set -# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set -CONFIG_FEATURE_IFCONFIG_HW=y -CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y -# CONFIG_IFENSLAVE is not set -# CONFIG_IFPLUGD is not set -# CONFIG_IFUPDOWN is not set -CONFIG_IFUPDOWN_IFSTATE_PATH="" -# CONFIG_FEATURE_IFUPDOWN_IP is not set -# CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN is not set -# CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN is not set -# CONFIG_FEATURE_IFUPDOWN_IPV4 is not set -# CONFIG_FEATURE_IFUPDOWN_IPV6 is not set -# CONFIG_FEATURE_IFUPDOWN_MAPPING is not set -# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set -# CONFIG_INETD is not set -# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO is not set -# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD is not set -# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME is not set -# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME is not set -# CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set -# CONFIG_FEATURE_INETD_RPC is not set -# CONFIG_IP is not set -# CONFIG_FEATURE_IP_ADDRESS is not set -# CONFIG_FEATURE_IP_LINK is not set -# CONFIG_FEATURE_IP_ROUTE is not set -# CONFIG_FEATURE_IP_TUNNEL is not set -# CONFIG_FEATURE_IP_RULE is not set -# CONFIG_FEATURE_IP_SHORT_FORMS is not set -# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set -# CONFIG_IPADDR is not set -# CONFIG_IPLINK is not set -# CONFIG_IPROUTE is not set -# CONFIG_IPTUNNEL is not set -# CONFIG_IPRULE is not set -# CONFIG_IPCALC is not set -# CONFIG_FEATURE_IPCALC_FANCY is not set -# CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set -# CONFIG_NAMEIF is not set -# CONFIG_FEATURE_NAMEIF_EXTENDED is not set -CONFIG_NETSTAT=y -CONFIG_FEATURE_NETSTAT_WIDE=y -# CONFIG_FEATURE_NETSTAT_PRG is not set -CONFIG_NSLOOKUP=y -CONFIG_NTPD=y -CONFIG_FEATURE_NTPD_SERVER=y -CONFIG_PING=y -CONFIG_FEATURE_FANCY_PING=y -CONFIG_PSCAN=y -CONFIG_ROUTE=y -# CONFIG_SLATTACH is not set -# CONFIG_TCPSVD is not set -CONFIG_TELNET=y -# CONFIG_FEATURE_TELNET_TTYPE is not set -# CONFIG_FEATURE_TELNET_AUTOLOGIN is not set -CONFIG_TELNETD=y -CONFIG_FEATURE_TELNETD_STANDALONE=y -# CONFIG_FEATURE_TELNETD_INETD_WAIT is not set -# CONFIG_TFTP is not set -# CONFIG_TFTPD is not set -# CONFIG_FEATURE_TFTP_GET is not set -# CONFIG_FEATURE_TFTP_PUT is not set -# CONFIG_FEATURE_TFTP_BLOCKSIZE is not set -# CONFIG_FEATURE_TFTP_PROGRESS_BAR is not set -# CONFIG_TFTP_DEBUG is not set -CONFIG_TRACEROUTE=y -CONFIG_FEATURE_TRACEROUTE_VERBOSE=y -CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE=y -CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y -# CONFIG_TUNCTL is not set -# CONFIG_FEATURE_TUNCTL_UG is not set -# CONFIG_UDHCPD is not set -# CONFIG_UDHCPC6 is not set -# CONFIG_DHCPRELAY is not set -# CONFIG_DUMPLEASES is not set -# CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY is not set -CONFIG_DHCPD_LEASES_FILE="" -CONFIG_UDHCPC=y -# CONFIG_FEATURE_UDHCPC_ARPING is not set -CONFIG_FEATURE_UDHCP_PORT=y -CONFIG_UDHCP_DEBUG=0 -CONFIG_FEATURE_UDHCP_8021Q=y -# CONFIG_FEATURE_UDHCP_RFC3397 is not set -CONFIG_UDHCPC_DEFAULT_SCRIPT="" -CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=924 -# CONFIG_DHCP6C is not set -# CONFIG_FEATURE_DHCP6_AUTH is not set -# CONFIG_DHCP6RELAY is not set -CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" -# CONFIG_UDPSVD is not set -CONFIG_VCONFIG=y -CONFIG_WGET=y -CONFIG_FEATURE_WGET_AUTHENTICATION=y -# CONFIG_FEATURE_WGET_LONG_OPTIONS is not set -CONFIG_FEATURE_WGET_TIMEOUT=y -# CONFIG_ZCIP is not set - -# -# Print Utilities -# -# CONFIG_LPD is not set -# CONFIG_LPR is not set -# CONFIG_LPQ is not set - -# -# Mail Utilities -# -# CONFIG_MAKEMIME is not set -CONFIG_FEATURE_MIME_CHARSET="" -# CONFIG_POPMAILDIR is not set -# CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set -# CONFIG_REFORMIME is not set -# CONFIG_FEATURE_REFORMIME_COMPAT is not set - -# -# Process Utilities -# -# CONFIG_IOSTAT is not set -# CONFIG_LSOF is not set -# CONFIG_MPSTAT is not set -# CONFIG_PMAP is not set -# CONFIG_POWERTOP is not set -# CONFIG_PSTREE is not set -# CONFIG_PWDX is not set -# CONFIG_SMEMCAP is not set -CONFIG_UPTIME=y -# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set -CONFIG_FREE=y -# CONFIG_FUSER is not set -CONFIG_KILL=y -CONFIG_KILLALL=y -# CONFIG_KILLALL5 is not set -# CONFIG_NMETER is not set -# CONFIG_PGREP is not set -CONFIG_PIDOF=y -# CONFIG_FEATURE_PIDOF_SINGLE is not set -# CONFIG_FEATURE_PIDOF_OMIT is not set -# CONFIG_PKILL is not set -CONFIG_PS=y -CONFIG_FEATURE_PS_WIDE=y -# CONFIG_FEATURE_PS_LONG is not set -# CONFIG_FEATURE_PS_TIME is not set -# CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS is not set -# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set -# CONFIG_RENICE is not set -# CONFIG_BB_SYSCTL is not set -CONFIG_TOP=y -CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y -CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y -# CONFIG_FEATURE_TOP_SMP_CPU is not set -# CONFIG_FEATURE_TOP_DECIMALS is not set -# CONFIG_FEATURE_TOP_SMP_PROCESS is not set -# CONFIG_FEATURE_TOPMEM is not set -# CONFIG_FEATURE_SHOW_THREADS is not set -CONFIG_WATCH=y - -# -# Runit Utilities -# -# CONFIG_RUNSV is not set -# CONFIG_RUNSVDIR is not set -# CONFIG_FEATURE_RUNSVDIR_LOG is not set -# CONFIG_SV is not set -CONFIG_SV_DEFAULT_SERVICE_DIR="" -# CONFIG_SVLOGD is not set -# CONFIG_CHPST is not set -# CONFIG_SETUIDGID is not set -# CONFIG_ENVUIDGID is not set -# CONFIG_ENVDIR is not set -# CONFIG_SOFTLIMIT is not set -# CONFIG_CHCON is not set -# CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set -# CONFIG_GETENFORCE is not set -# CONFIG_GETSEBOOL is not set -# CONFIG_LOAD_POLICY is not set -# CONFIG_MATCHPATHCON is not set -# CONFIG_RESTORECON is not set -# CONFIG_RUNCON is not set -# CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set -# CONFIG_SELINUXENABLED is not set -# CONFIG_SETENFORCE is not set -# CONFIG_SETFILES is not set -# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set -# CONFIG_SETSEBOOL is not set -# CONFIG_SESTATUS is not set - -# -# Shells -# -CONFIG_ASH=y -CONFIG_ASH_BASH_COMPAT=y -# CONFIG_ASH_IDLE_TIMEOUT is not set -# CONFIG_ASH_JOB_CONTROL is not set -CONFIG_ASH_ALIAS=y -# CONFIG_ASH_GETOPTS is not set -# CONFIG_ASH_BUILTIN_ECHO is not set -# CONFIG_ASH_BUILTIN_PRINTF is not set -# CONFIG_ASH_BUILTIN_TEST is not set -# CONFIG_ASH_CMDCMD is not set -# CONFIG_ASH_MAIL is not set -CONFIG_ASH_OPTIMIZE_FOR_SIZE=y -# CONFIG_ASH_RANDOM_SUPPORT is not set -# CONFIG_ASH_EXPAND_PRMT is not set -# CONFIG_CTTYHACK is not set -# CONFIG_HUSH is not set -# CONFIG_HUSH_BASH_COMPAT is not set -# CONFIG_HUSH_BRACE_EXPANSION is not set -# CONFIG_HUSH_HELP is not set -# CONFIG_HUSH_INTERACTIVE is not set -# CONFIG_HUSH_SAVEHISTORY is not set -# CONFIG_HUSH_JOB is not set -# CONFIG_HUSH_TICK is not set -# CONFIG_HUSH_IF is not set -# CONFIG_HUSH_LOOPS is not set -# CONFIG_HUSH_CASE is not set -# CONFIG_HUSH_FUNCTIONS is not set -# CONFIG_HUSH_LOCAL is not set -# CONFIG_HUSH_RANDOM_SUPPORT is not set -# CONFIG_HUSH_EXPORT_N is not set -# CONFIG_HUSH_MODE_X is not set -# CONFIG_MSH is not set -CONFIG_FEATURE_SH_IS_ASH=y -# CONFIG_FEATURE_SH_IS_HUSH is not set -# CONFIG_FEATURE_SH_IS_NONE is not set -# CONFIG_FEATURE_BASH_IS_ASH is not set -# CONFIG_FEATURE_BASH_IS_HUSH is not set -CONFIG_FEATURE_BASH_IS_NONE=y -CONFIG_SH_MATH_SUPPORT=y -# CONFIG_SH_MATH_SUPPORT_64 is not set -CONFIG_FEATURE_SH_EXTRA_QUIET=y -# CONFIG_FEATURE_SH_STANDALONE is not set -# CONFIG_FEATURE_SH_NOFORK is not set -# CONFIG_FEATURE_SH_HISTFILESIZE is not set - -# -# System Logging Utilities -# -CONFIG_SYSLOGD=y -CONFIG_FEATURE_ROTATE_LOGFILE=y -CONFIG_FEATURE_REMOTE_LOG=y -# CONFIG_FEATURE_SYSLOGD_DUP is not set -# CONFIG_FEATURE_SYSLOGD_CFG is not set -# CONFIG_FEATURE_IPC_SYSLOG is not set -CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 -# CONFIG_LOGREAD is not set -# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set -CONFIG_KLOGD=y -CONFIG_FEATURE_KLOGD_KLOGCTL=y -CONFIG_LOGGER=y -# CONFIG_FEATURE_2_4_MODULES is not set -CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT=y -# CONFIG_FEATURE_DEVFS is not set -CONFIG_MKNOD=y -CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=512 -CONFIG_SENDMAIL=y -CONFIG_FEATURE_SORT_BIG=y -CONFIG_FTPPUT=y -CONFIG_FTPGET=y -CONFIG_CLEAR=y -CONFIG_NICE=y -CONFIG_SETCONSOLE=y -CONFIG_MKFIFO=y -CONFIG_E2FSCK=y -CONFIG_MKE2FS=y -CONFIG_FDISK=y -CONFIG_FEATURE_FDISK_WRITABLE=y -CONFIG_MKFS_VFAT=y -CONFIG_MKSWAP=y -CONFIG_FLOCK=y -CONFIG_FSYNC=y -CONFIG_TUNE2FS=y -CONFIG_E2LABEL=y -CONFIG_LSUSB=y -CONFIG_FEATURE_WGET_STATUSBAR=y -CONFIG_FEATURE_VERBOSE_USAGE=y -CONFIG_FEATURE_IPV6=y -CONFIG_PING6=y -CONFIG_TRACEROUTE6=y -CONFIG_FEATURE_UDHCP_RFC5969=y -CONFIG_FEATURE_LS_COLOR=y -CONFIG_FEATURE_LS_COLOR_IS_DEFAULT=y diff --git a/release/src/router/busybox/configs/TEST_nommu_defconfig b/release/src/router/busybox/configs/TEST_nommu_defconfig index 15e12b1d26..b45afd9568 100644 --- a/release/src/router/busybox/configs/TEST_nommu_defconfig +++ b/release/src/router/busybox/configs/TEST_nommu_defconfig @@ -341,7 +341,6 @@ CONFIG_FEATURE_VI_READONLY=y CONFIG_FEATURE_VI_SETOPTS=y CONFIG_FEATURE_VI_SET=y CONFIG_FEATURE_VI_WIN_RESIZE=y -CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y CONFIG_FEATURE_ALLOW_EXEC=y # diff --git a/release/src/router/busybox/configs/TEST_noprintf_defconfig b/release/src/router/busybox/configs/TEST_noprintf_defconfig index f4338df711..809b60cd8f 100644 --- a/release/src/router/busybox/configs/TEST_noprintf_defconfig +++ b/release/src/router/busybox/configs/TEST_noprintf_defconfig @@ -346,7 +346,6 @@ CONFIG_FEATURE_VI_MAX_LEN=0 # CONFIG_FEATURE_VI_SET is not set # CONFIG_FEATURE_VI_WIN_RESIZE is not set # CONFIG_FEATURE_VI_ASK_TERMINAL is not set -# CONFIG_FEATURE_VI_OPTIMIZE_CURSOR is not set # CONFIG_FEATURE_ALLOW_EXEC is not set # diff --git a/release/src/router/busybox/configs/TEST_rh9_defconfig b/release/src/router/busybox/configs/TEST_rh9_defconfig index 193d8f615e..565b826d08 100644 --- a/release/src/router/busybox/configs/TEST_rh9_defconfig +++ b/release/src/router/busybox/configs/TEST_rh9_defconfig @@ -358,7 +358,6 @@ CONFIG_FEATURE_VI_READONLY=y CONFIG_FEATURE_VI_SETOPTS=y CONFIG_FEATURE_VI_SET=y CONFIG_FEATURE_VI_WIN_RESIZE=y -CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y CONFIG_FEATURE_ALLOW_EXEC=y # diff --git a/release/src/router/busybox/configs/android2_defconfig b/release/src/router/busybox/configs/android2_defconfig index b5166e0fc5..4dfbdb5266 100644 --- a/release/src/router/busybox/configs/android2_defconfig +++ b/release/src/router/busybox/configs/android2_defconfig @@ -363,7 +363,6 @@ CONFIG_FEATURE_VI_MAX_LEN=0 # CONFIG_FEATURE_VI_SET is not set # CONFIG_FEATURE_VI_WIN_RESIZE is not set # CONFIG_FEATURE_VI_ASK_TERMINAL is not set -# CONFIG_FEATURE_VI_OPTIMIZE_CURSOR is not set # CONFIG_AWK is not set # CONFIG_FEATURE_AWK_LIBM is not set CONFIG_CMP=y diff --git a/release/src/router/busybox/configs/android_defconfig b/release/src/router/busybox/configs/android_defconfig index a9a8d5e1f1..e35830e7fe 100644 --- a/release/src/router/busybox/configs/android_defconfig +++ b/release/src/router/busybox/configs/android_defconfig @@ -386,7 +386,6 @@ CONFIG_FEATURE_VI_SETOPTS=y CONFIG_FEATURE_VI_SET=y CONFIG_FEATURE_VI_WIN_RESIZE=y CONFIG_FEATURE_VI_ASK_TERMINAL=y -CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y CONFIG_AWK=y CONFIG_FEATURE_AWK_LIBM=y CONFIG_CMP=y diff --git a/release/src/router/busybox/configs/android_ndk_defconfig b/release/src/router/busybox/configs/android_ndk_defconfig index bf8827a584..01cc2dd156 100644 --- a/release/src/router/busybox/configs/android_ndk_defconfig +++ b/release/src/router/busybox/configs/android_ndk_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Busybox version: 1.20.0.git -# Fri Mar 2 16:53:26 2012 +# Busybox version: 1.21.0.git +# Mon May 28 21:51:18 2012 # CONFIG_HAVE_DOT_CONFIG=y @@ -20,11 +20,11 @@ CONFIG_PLATFORM_LINUX=y CONFIG_FEATURE_BUFFERS_USE_MALLOC=y # CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set # CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set -# CONFIG_SHOW_USAGE is not set -# CONFIG_FEATURE_VERBOSE_USAGE is not set -# CONFIG_FEATURE_COMPRESS_USAGE is not set -# CONFIG_FEATURE_INSTALLER is not set -# CONFIG_INSTALL_NO_USR is not set +CONFIG_SHOW_USAGE=y +CONFIG_FEATURE_VERBOSE_USAGE=y +CONFIG_FEATURE_COMPRESS_USAGE=y +CONFIG_FEATURE_INSTALLER=y +CONFIG_INSTALL_NO_USR=y # CONFIG_LOCALE_SUPPORT is not set # CONFIG_UNICODE_SUPPORT is not set # CONFIG_UNICODE_USING_LOCALE is not set @@ -36,7 +36,7 @@ CONFIG_LAST_SUPPORTED_WCHAR=0 # CONFIG_UNICODE_BIDI_SUPPORT is not set # CONFIG_UNICODE_NEUTRAL_TABLE is not set # CONFIG_UNICODE_PRESERVE_BROKEN is not set -# CONFIG_LONG_OPTS is not set +CONFIG_LONG_OPTS=y # CONFIG_FEATURE_DEVPTS is not set # CONFIG_FEATURE_CLEAN_UP is not set # CONFIG_FEATURE_UTMP is not set @@ -67,7 +67,6 @@ CONFIG_EXTRA_CFLAGS="-DANDROID -D__ANDROID__ -DSK_RELEASE -nostdlib -march=armv7 CONFIG_EXTRA_LDFLAGS="-Xlinker -z -Xlinker muldefs -nostdlib -Bdynamic -Xlinker -dynamic-linker -Xlinker /system/bin/linker -Xlinker -z -Xlinker nocopyreloc -Xlinker --no-undefined ${SYSROOT}/usr/lib/crtbegin_dynamic.o ${SYSROOT}/usr/lib/crtend_android.o" CONFIG_EXTRA_LDLIBS="dl m c gcc" - # # Debugging Options # @@ -112,7 +111,7 @@ CONFIG_FEATURE_EDITING_HISTORY=0 # CONFIG_FEATURE_EDITING_FANCY_PROMPT is not set # CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set # CONFIG_FEATURE_NON_POSIX_CP is not set -# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +CONFIG_FEATURE_VERBOSE_CP_MESSAGE=y CONFIG_FEATURE_COPYBUF_KB=4 # CONFIG_FEATURE_SKIP_ROOTFS is not set # CONFIG_MONOTONIC_SYSCALL is not set @@ -239,7 +238,7 @@ CONFIG_FEATURE_LS_RECURSIVE=y CONFIG_FEATURE_LS_SORTFILES=y CONFIG_FEATURE_LS_TIMESTAMPS=y CONFIG_FEATURE_LS_USERNAME=y -# CONFIG_FEATURE_LS_COLOR is not set +CONFIG_FEATURE_LS_COLOR=y # CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set CONFIG_MD5SUM=y CONFIG_MKDIR=y @@ -372,7 +371,6 @@ CONFIG_FEATURE_VI_SETOPTS=y CONFIG_FEATURE_VI_SET=y CONFIG_FEATURE_VI_WIN_RESIZE=y CONFIG_FEATURE_VI_ASK_TERMINAL=y -CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y CONFIG_AWK=y CONFIG_FEATURE_AWK_LIBM=y CONFIG_CMP=y @@ -516,7 +514,7 @@ CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set # CONFIG_FEATURE_MODUTILS_ALIAS is not set # CONFIG_FEATURE_MODUTILS_SYMBOLS is not set -CONFIG_DEFAULT_MODULES_DIR="/lib/modules" +CONFIG_DEFAULT_MODULES_DIR="/system/lib/modules" CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" # @@ -647,8 +645,8 @@ CONFIG_SETSERIAL=y # CONFIG_UBIRSVOL is not set # CONFIG_UBIUPDATEVOL is not set # CONFIG_ADJTIMEX is not set -# CONFIG_BBCONFIG is not set -# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +CONFIG_BBCONFIG=y +CONFIG_FEATURE_COMPRESS_BBCONFIG=y CONFIG_BEEP=y CONFIG_FEATURE_BEEP_FREQ=4000 CONFIG_FEATURE_BEEP_LENGTH_MS=30 @@ -883,6 +881,7 @@ CONFIG_SENDMAIL=y # Process Utilities # CONFIG_IOSTAT=y +CONFIG_LSOF=y CONFIG_MPSTAT=y CONFIG_NMETER=y CONFIG_PMAP=y diff --git a/release/src/router/busybox/configs/cygwin_defconfig b/release/src/router/busybox/configs/cygwin_defconfig index bdd0d66d0a..aa346e34cb 100644 --- a/release/src/router/busybox/configs/cygwin_defconfig +++ b/release/src/router/busybox/configs/cygwin_defconfig @@ -363,7 +363,6 @@ CONFIG_FEATURE_VI_SETOPTS=y CONFIG_FEATURE_VI_SET=y CONFIG_FEATURE_VI_WIN_RESIZE=y CONFIG_FEATURE_VI_ASK_TERMINAL=y -CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y CONFIG_AWK=y CONFIG_FEATURE_AWK_LIBM=y CONFIG_CMP=y diff --git a/release/src/router/busybox/configs/freebsd_defconfig b/release/src/router/busybox/configs/freebsd_defconfig index dcb5d953c2..ec3ed03c47 100644 --- a/release/src/router/busybox/configs/freebsd_defconfig +++ b/release/src/router/busybox/configs/freebsd_defconfig @@ -367,7 +367,6 @@ CONFIG_FEATURE_VI_SETOPTS=y CONFIG_FEATURE_VI_SET=y CONFIG_FEATURE_VI_WIN_RESIZE=y CONFIG_FEATURE_VI_ASK_TERMINAL=y -CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y CONFIG_FEATURE_ALLOW_EXEC=y # diff --git a/release/src/router/busybox/console-tools/loadfont.c b/release/src/router/busybox/console-tools/loadfont.c index 9e887f2566..032506d6da 100644 --- a/release/src/router/busybox/console-tools/loadfont.c +++ b/release/src/router/busybox/console-tools/loadfont.c @@ -229,7 +229,7 @@ static void do_loadtable(int fd, unsigned char *inbuf, int tailsz, int fontsize, } /* Note: after PIO_UNIMAPCLR and before PIO_UNIMAP - this printf did not work on many kernels */ + * this printf did not work on many kernels */ advice.advised_hashsize = 0; advice.advised_hashstep = 0; diff --git a/release/src/router/busybox/console-tools/setlogcons.c b/release/src/router/busybox/console-tools/setlogcons.c index 83a895407b..c76a5a42b1 100644 --- a/release/src/router/busybox/console-tools/setlogcons.c +++ b/release/src/router/busybox/console-tools/setlogcons.c @@ -22,9 +22,10 @@ int setlogcons_main(int argc UNUSED_PARAM, char **argv) struct { char fn; char subarg; - } arg = { 11, /* redirect kernel messages */ - 0 /* to specified console (current as default) */ - }; + } arg = { + 11, /* redirect kernel messages */ + 0 /* to specified console (current as default) */ + }; if (argv[1]) arg.subarg = xatou_range(argv[1], 0, 63); diff --git a/release/src/router/busybox/coreutils/Config.src b/release/src/router/busybox/coreutils/Config.src index a28449b11d..0c44c4b514 100644 --- a/release/src/router/busybox/coreutils/Config.src +++ b/release/src/router/busybox/coreutils/Config.src @@ -514,6 +514,12 @@ config SHA512SUM help Compute and check SHA512 message digest +config SHA3SUM + bool "sha3sum" + default y + help + Compute and check SHA3 (512-bit) message digest + config SLEEP bool "sleep" default y @@ -766,13 +772,13 @@ config FEATURE_HUMAN_READABLE help Allow df, du, and ls to have human readable output. -comment "Common options for md5sum, sha1sum, sha256sum, sha512sum" - depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM +comment "Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum" + depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM config FEATURE_MD5_SHA1_SUM_CHECK bool "Enable -c, -s and -w options" default y - depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM + depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM help Enabling the -c options allows files to be checked against pre-calculated hash values. diff --git a/release/src/router/busybox/coreutils/Kbuild.src b/release/src/router/busybox/coreutils/Kbuild.src index d6453f0145..b715b9c47a 100644 --- a/release/src/router/busybox/coreutils/Kbuild.src +++ b/release/src/router/busybox/coreutils/Kbuild.src @@ -62,6 +62,7 @@ lib-$(CONFIG_SEQ) += seq.o lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o +lib-$(CONFIG_SHA3SUM) += md5_sha1_sum.o lib-$(CONFIG_SLEEP) += sleep.o lib-$(CONFIG_SPLIT) += split.o lib-$(CONFIG_SORT) += sort.o diff --git a/release/src/router/busybox/coreutils/cal.c b/release/src/router/busybox/coreutils/cal.c index b470ad968a..0d388aa1cb 100644 --- a/release/src/router/busybox/coreutils/cal.c +++ b/release/src/router/busybox/coreutils/cal.c @@ -43,7 +43,7 @@ static const unsigned char days_in_month[] ALIGN1 = { }; static const unsigned char sep1752[] ALIGN1 = { - 1, 2, 14, 15, 16, + 1, 2, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 }; @@ -167,8 +167,8 @@ int cal_main(int argc UNUSED_PARAM, char **argv) day_array(month, year, dp); len = sprintf(lineout, "%s %d", month_names[month - 1], year); printf("%*s%s\n%s\n", - ((7*julian + WEEK_LEN) - len) / 2, "", - lineout, day_headings); + ((7*julian + WEEK_LEN) - len) / 2, "", + lineout, day_headings); for (row = 0; row < 6; row++) { build_row(lineout, dp)[0] = '\0'; dp += 7; @@ -181,10 +181,11 @@ int cal_main(int argc UNUSED_PARAM, char **argv) sprintf(lineout, "%u", year); center(lineout, - (WEEK_LEN * 3 + HEAD_SEP * 2) - + julian * (J_WEEK_LEN * 2 + HEAD_SEP - - (WEEK_LEN * 3 + HEAD_SEP * 2)), - 0); + (WEEK_LEN * 3 + HEAD_SEP * 2) + + julian * (J_WEEK_LEN * 2 + HEAD_SEP + - (WEEK_LEN * 3 + HEAD_SEP * 2)), + 0 + ); puts("\n"); /* two \n's */ for (i = 0; i < 12; i++) { day_array(i + 1, year, days[i]); diff --git a/release/src/router/busybox/coreutils/chown.c b/release/src/router/busybox/coreutils/chown.c index bb166d8fe4..1a91276221 100644 --- a/release/src/router/busybox/coreutils/chown.c +++ b/release/src/router/busybox/coreutils/chown.c @@ -126,8 +126,8 @@ int chown_main(int argc UNUSED_PARAM, char **argv) /* This matches coreutils behavior (almost - see below) */ param.chown_func = chown; if (OPT_NODEREF - /* || (OPT_RECURSE && !OPT_TRAVERSE_TOP): */ - IF_DESKTOP( || (opt & (BIT_RECURSE|BIT_TRAVERSE_TOP)) == BIT_RECURSE) + /* || (OPT_RECURSE && !OPT_TRAVERSE_TOP): */ + IF_DESKTOP( || (opt & (BIT_RECURSE|BIT_TRAVERSE_TOP)) == BIT_RECURSE) ) { param.chown_func = lchown; } diff --git a/release/src/router/busybox/coreutils/cut.c b/release/src/router/busybox/coreutils/cut.c index 2c27b704f5..84449c775c 100644 --- a/release/src/router/busybox/coreutils/cut.c +++ b/release/src/router/busybox/coreutils/cut.c @@ -212,7 +212,7 @@ int cut_main(int argc UNUSED_PARAM, char **argv) if (opt & CUT_OPT_SUPPRESS_FLGS) { bb_error_msg_and_die ("suppressing non-delimited lines makes sense%s", - _op_on_field); + _op_on_field); } if (delim != '\t') { bb_error_msg_and_die diff --git a/release/src/router/busybox/coreutils/df.c b/release/src/router/busybox/coreutils/df.c index 25dbd3eec1..640ef43985 100644 --- a/release/src/router/busybox/coreutils/df.c +++ b/release/src/router/busybox/coreutils/df.c @@ -110,9 +110,9 @@ int df_main(int argc UNUSED_PARAM, char **argv) df_disp_hr = xatoul_range(chp, 1, ULONG_MAX); /* disallow 0 */ /* From the manpage of df from coreutils-6.10: - Disk space is shown in 1K blocks by default, unless the environment - variable POSIXLY_CORRECT is set, in which case 512-byte blocks are used. - */ + * Disk space is shown in 1K blocks by default, unless the environment + * variable POSIXLY_CORRECT is set, in which case 512-byte blocks are used. + */ if (getenv("POSIXLY_CORRECT")) /* TODO - a new libbb function? */ df_disp_hr = 512; @@ -223,7 +223,7 @@ int df_main(int argc UNUSED_PARAM, char **argv) } #else if (printf("\n%-20s" + 1, device) > 20 && !(opt & OPT_POSIX)) - printf("\n%-20s", ""); + printf("\n%-20s", ""); #endif #if ENABLE_FEATURE_HUMAN_READABLE diff --git a/release/src/router/busybox/coreutils/du.c b/release/src/router/busybox/coreutils/du.c index 19a0319f13..9c6ff88005 100644 --- a/release/src/router/busybox/coreutils/du.c +++ b/release/src/router/busybox/coreutils/du.c @@ -89,6 +89,10 @@ struct globals { #define INIT_G() do { } while (0) +/* FIXME? coreutils' du rounds sizes up: + * for example, 1025k file is shown as "2" by du -m. + * We round to nearest. + */ static void print(unsigned long long size, const char *filename) { /* TODO - May not want to defer error checking here. */ diff --git a/release/src/router/busybox/coreutils/id.c b/release/src/router/busybox/coreutils/id.c index 399d25e342..1f20b755ed 100644 --- a/release/src/router/busybox/coreutils/id.c +++ b/release/src/router/busybox/coreutils/id.c @@ -174,7 +174,7 @@ int id_main(int argc UNUSED_PARAM, char **argv) /* Don't allow -n -r -nr -ug -rug -nug -rnug -uZ -gZ -GZ*/ /* Don't allow more than one username */ opt_complementary = "?1:u--g:g--u:G--u:u--G:g--G:G--g:r?ugG:n?ugG" - IF_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G"); + IF_SELINUX(":u--Z:Z--u:g--Z:Z--g:G--Z:Z--G"); opt = getopt32(argv, "rnugG" IF_SELINUX("Z")); } diff --git a/release/src/router/busybox/coreutils/ln.c b/release/src/router/busybox/coreutils/ln.c index 0eb3e6579e..3b822e8c7f 100644 --- a/release/src/router/busybox/coreutils/ln.c +++ b/release/src/router/busybox/coreutils/ln.c @@ -20,6 +20,8 @@ //usage: "\n -n Don't dereference symlinks - treat like normal file" //usage: "\n -b Make a backup of the target (if exists) before link operation" //usage: "\n -S suf Use suffix instead of ~ when making backup files" +//usage: "\n -T 2nd arg must be a DIR" +//usage: "\n -v Verbose" //usage: //usage:#define ln_example_usage //usage: "$ ln -s BusyBox /tmp/ls\n" @@ -31,11 +33,13 @@ /* This is a NOEXEC applet. Be very careful! */ -#define LN_SYMLINK 1 -#define LN_FORCE 2 -#define LN_NODEREFERENCE 4 -#define LN_BACKUP 8 -#define LN_SUFFIX 16 +#define LN_SYMLINK (1 << 0) +#define LN_FORCE (1 << 1) +#define LN_NODEREFERENCE (1 << 2) +#define LN_BACKUP (1 << 3) +#define LN_SUFFIX (1 << 4) +#define LN_VERBOSE (1 << 5) +#define LN_LINKFILE (1 << 6) int ln_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int ln_main(int argc, char **argv) @@ -50,10 +54,15 @@ int ln_main(int argc, char **argv) int (*link_func)(const char *, const char *); opt_complementary = "-1"; /* min one arg */ - opts = getopt32(argv, "sfnbS:", &suffix); + opts = getopt32(argv, "sfnbS:vT", &suffix); last = argv[argc - 1]; argv += optind; + argc -= optind; + + if ((opts & LN_LINKFILE) && argc > 2) { + bb_error_msg_and_die("-T accepts 2 args max"); + } if (!argv[1]) { /* "ln PATH/TO/FILE" -> "ln PATH/TO/FILE FILE" */ @@ -72,6 +81,9 @@ int ln_main(int argc, char **argv) (opts & LN_NODEREFERENCE) ^ LN_NODEREFERENCE ) ) { + if (opts & LN_LINKFILE) { + bb_error_msg_and_die("'%s' is a directory", src); + } src_name = xstrdup(*argv); src = concat_path_file(src, bb_get_last_path_component_strip(src_name)); free(src_name); @@ -112,6 +124,10 @@ int ln_main(int argc, char **argv) link_func = symlink; } + if (opts & LN_VERBOSE) { + printf("'%s' -> '%s'\n", src, *argv); + } + if (link_func(*argv, src) != 0) { bb_simple_perror_msg(src); status = EXIT_FAILURE; diff --git a/release/src/router/busybox/coreutils/ls.c b/release/src/router/busybox/coreutils/ls.c index d5b25ee70b..166473d4d7 100644 --- a/release/src/router/busybox/coreutils/ls.c +++ b/release/src/router/busybox/coreutils/ls.c @@ -260,7 +260,7 @@ enum { /* TODO: simple toggles may be stored as OPT_xxx bits instead */ static const uint32_t opt_flags[] = { - STYLE_COLUMNAR, /* C */ + STYLE_COLUMNAR, /* C */ DISP_HIDDEN | DISP_DOT, /* a */ DISP_NOLIST, /* d */ LIST_INO, /* i */ @@ -720,7 +720,7 @@ static struct dnode *my_stat(const char *fullname, const char *name, int force_f if ((option_mask32 & OPT_L) || force_follow) { #if ENABLE_SELINUX if (is_selinux_enabled()) { - getfilecon(fullname, &cur->sid); + getfilecon(fullname, &cur->sid); } #endif if (stat(fullname, &statbuf)) { diff --git a/release/src/router/busybox/coreutils/md5_sha1_sum.c b/release/src/router/busybox/coreutils/md5_sha1_sum.c index 2cb6dd43c1..92a4d44621 100644 --- a/release/src/router/busybox/coreutils/md5_sha1_sum.c +++ b/release/src/router/busybox/coreutils/md5_sha1_sum.c @@ -55,6 +55,16 @@ //usage: "\n -s Don't output anything, status code shows success" //usage: "\n -w Warn about improperly formatted checksum lines" //usage: ) +//usage: +//usage:#define sha3sum_trivial_usage +//usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..." +//usage:#define sha3sum_full_usage "\n\n" +//usage: "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA3-512 checksums" +//usage: IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n" +//usage: "\n -c Check sums against list in FILEs" +//usage: "\n -s Don't output anything, status code shows success" +//usage: "\n -w Warn about improperly formatted checksum lines" +//usage: ) #include "libbb.h" @@ -65,6 +75,7 @@ enum { HASH_MD5 = 's', /* "md5>sst_mode)) return "fifo"; if (S_ISLNK(st->st_mode)) return "symbolic link"; if (S_ISSOCK(st->st_mode)) return "socket"; +#ifdef S_TYPEISMQ if (S_TYPEISMQ(st)) return "message queue"; +#endif +#ifdef S_TYPEISSEM if (S_TYPEISSEM(st)) return "semaphore"; +#endif +#ifdef S_TYPEISSHM if (S_TYPEISSHM(st)) return "shared memory object"; +#endif #ifdef S_TYPEISTMO if (S_TYPEISTMO(st)) return "typed memory object"; #endif @@ -436,7 +442,7 @@ static bool do_statfs(const char *filename, const char *format) : getfilecon(filename, &scontext) ) < 0 ) { - bb_perror_msg(filename); + bb_simple_perror_msg(filename); return 0; } } @@ -549,7 +555,7 @@ static bool do_stat(const char *filename, const char *format) : getfilecon(filename, &scontext) ) < 0 ) { - bb_perror_msg(filename); + bb_simple_perror_msg(filename); return 0; } } @@ -585,37 +591,43 @@ static bool do_stat(const char *filename, const char *format) # else if (option_mask32 & OPT_TERSE) { format = (option_mask32 & OPT_SELINUX ? - "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n": - "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n"); + "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o %C\n" + : + "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n" + ); } else { if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) { format = (option_mask32 & OPT_SELINUX ? - " File: %N\n" - " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" - "Device: %Dh/%dd\tInode: %-10i Links: %-5h" - " Device type: %t,%T\n" - "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" - " S_Context: %C\n" - "Access: %x\n" "Modify: %y\n" "Change: %z\n": - " File: %N\n" - " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" - "Device: %Dh/%dd\tInode: %-10i Links: %-5h" - " Device type: %t,%T\n" - "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" - "Access: %x\n" "Modify: %y\n" "Change: %z\n"); + " File: %N\n" + " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" + "Device: %Dh/%dd\tInode: %-10i Links: %-5h" + " Device type: %t,%T\n" + "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" + " S_Context: %C\n" + "Access: %x\n" "Modify: %y\n" "Change: %z\n" + : + " File: %N\n" + " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" + "Device: %Dh/%dd\tInode: %-10i Links: %-5h" + " Device type: %t,%T\n" + "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" + "Access: %x\n" "Modify: %y\n" "Change: %z\n" + ); } else { format = (option_mask32 & OPT_SELINUX ? - " File: %N\n" - " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" - "Device: %Dh/%dd\tInode: %-10i Links: %h\n" - "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" - "S_Context: %C\n" - "Access: %x\n" "Modify: %y\n" "Change: %z\n": - " File: %N\n" - " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" - "Device: %Dh/%dd\tInode: %-10i Links: %h\n" - "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" - "Access: %x\n" "Modify: %y\n" "Change: %z\n"); + " File: %N\n" + " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" + "Device: %Dh/%dd\tInode: %-10i Links: %h\n" + "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" + "S_Context: %C\n" + "Access: %x\n" "Modify: %y\n" "Change: %z\n" + : + " File: %N\n" + " Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n" + "Device: %Dh/%dd\tInode: %-10i Links: %h\n" + "Access: (%04a/%10.10A) Uid: (%5u/%8U) Gid: (%5g/%8G)\n" + "Access: %x\n" "Modify: %y\n" "Change: %z\n" + ); } } # endif diff --git a/release/src/router/busybox/coreutils/stty.c b/release/src/router/busybox/coreutils/stty.c index 0668cf7be5..96754dd840 100644 --- a/release/src/router/busybox/coreutils/stty.c +++ b/release/src/router/busybox/coreutils/stty.c @@ -1056,7 +1056,7 @@ static void do_display(const struct termios *mode, int all) } #endif wrapf("%s = %s;", nth_string(control_name, i), - visible(mode->c_cc[control_info[i].offset])); + visible(mode->c_cc[control_info[i].offset])); } #if VEOF == VMIN if ((mode->c_lflag & ICANON) == 0) diff --git a/release/src/router/busybox/coreutils/sum.c b/release/src/router/busybox/coreutils/sum.c index 95110a6da6..75f6ef60a2 100644 --- a/release/src/router/busybox/coreutils/sum.c +++ b/release/src/router/busybox/coreutils/sum.c @@ -94,8 +94,8 @@ int sum_main(int argc UNUSED_PARAM, char **argv) n = sum_file("-", type); } else { /* Need to print the name if either - - more than one file given - - doing sysv */ + * - more than one file given + * - doing sysv */ type += (argv[1] || type == SUM_SYSV); n = 1; do { diff --git a/release/src/router/busybox/coreutils/test.c b/release/src/router/busybox/coreutils/test.c index 0bc008e7c8..4df505a050 100644 --- a/release/src/router/busybox/coreutils/test.c +++ b/release/src/router/busybox/coreutils/test.c @@ -610,7 +610,7 @@ static int test_eaccess(char *path, int mode) return 0; /* Root can execute any file that has any one of the execute - bits set. */ + * bits set. */ if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) return 0; } diff --git a/release/src/router/busybox/debianutils/mktemp.c b/release/src/router/busybox/debianutils/mktemp.c index dbe4309555..983d7a2465 100644 --- a/release/src/router/busybox/debianutils/mktemp.c +++ b/release/src/router/busybox/debianutils/mktemp.c @@ -38,7 +38,7 @@ //usage: "TEMPLATE must end with XXXXXX (e.g. [/dir/]nameXXXXXX).\n" //usage: "Without TEMPLATE, -t tmp.XXXXXX is assumed.\n" //usage: "\n -d Make directory, not file" -////usage: "\n -q Fail silently on errors" - we ignore this opt +//usage: "\n -q Fail silently on errors" //usage: "\n -t Prepend base directory name to TEMPLATE" //usage: "\n -p DIR Use DIR as a base directory (implies -t)" //usage: "\n -u Do not create anything; print a name" @@ -71,7 +71,6 @@ int mktemp_main(int argc UNUSED_PARAM, char **argv) if (!path || path[0] == '\0') path = "/tmp"; - /* -q is ignored */ opt_complementary = "?1"; /* 1 argument max */ opts = getopt32(argv, "dqtp:u", &path); @@ -83,33 +82,32 @@ int mktemp_main(int argc UNUSED_PARAM, char **argv) chp = xstrdup("tmp.XXXXXX"); opts |= OPT_t; } - - if (opts & OPT_u) { - /* Remove (up to) 6 X's */ - unsigned len = strlen(chp); - int cnt = len > 6 ? 6 : len; - while (--cnt >= 0 && chp[--len] == 'X') - chp[len] = '\0'; - - chp = tempnam(opts & (OPT_t|OPT_p) ? path : "./", chp); - if (!chp) - return EXIT_FAILURE; - if (!(opts & (OPT_t|OPT_p))) - chp += 2; - goto ret; +#if 0 + /* Don't allow directory separator in template */ + if ((opts & OPT_t) && bb_basename(chp) != chp) { + errno = EINVAL; + goto error; } - +#endif if (opts & (OPT_t|OPT_p)) chp = concat_path_file(path, chp); - if (opts & OPT_d) { + if (opts & OPT_u) { + chp = mktemp(chp); + if (chp[0] == '\0') + goto error; + } else if (opts & OPT_d) { if (mkdtemp(chp) == NULL) - return EXIT_FAILURE; + goto error; } else { if (mkstemp(chp) < 0) - return EXIT_FAILURE; + goto error; } - ret: puts(chp); return EXIT_SUCCESS; + error: + if (opts & OPT_q) + return EXIT_FAILURE; + /* don't use chp as it gets mangled in case of error */ + bb_perror_nomsg_and_die(); } diff --git a/release/src/router/busybox/debianutils/run_parts.c b/release/src/router/busybox/debianutils/run_parts.c index 8f08f6dc66..005b304208 100644 --- a/release/src/router/busybox/debianutils/run_parts.c +++ b/release/src/router/busybox/debianutils/run_parts.c @@ -4,14 +4,13 @@ * * Copyright (C) 2007 Bernhard Reutner-Fischer * - * Based on a older version that was in busybox which was 1k big.. + * Based on a older version that was in busybox which was 1k big. * Copyright (C) 2001 by Emanuele Aina * * Based on the Debian run-parts program, version 1.15 * Copyright (C) 1996 Jeff Noxon , * Copyright (C) 1996-1999 Guy Maor * - * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ @@ -19,7 +18,7 @@ * attempt to write a program! :-) . */ /* This piece of code is heavily based on the original version of run-parts, - * taken from debian-utils. I've only removed the long options and a the + * taken from debian-utils. I've only removed the long options and the * report mode. As the original run-parts support only long options, I've * broken compatibility because the BusyBox policy doesn't allow them. * The supported options are: @@ -31,15 +30,15 @@ */ //usage:#define run_parts_trivial_usage -//usage: "[-t] "IF_FEATURE_RUN_PARTS_FANCY("[-l] ")"[-a ARG] [-u MASK] DIRECTORY" +//usage: "[-t"IF_FEATURE_RUN_PARTS_FANCY("l")"] [-a ARG]... [-u MASK] DIRECTORY" //usage:#define run_parts_full_usage "\n\n" //usage: "Run a bunch of scripts in DIRECTORY\n" -//usage: "\n -t Print what would be run, but don't actually run anything" -//usage: "\n -a ARG Pass ARG as argument for every program" -//usage: "\n -u MASK Set the umask to MASK before running every program" +//usage: "\n -t Dry run" //usage: IF_FEATURE_RUN_PARTS_FANCY( -//usage: "\n -l Print names of all matching files even if they are not executable" +//usage: "\n -l Print names of matching files even if they are not executable" //usage: ) +//usage: "\n -a ARG Pass ARG as argument to programs" +//usage: "\n -u MASK Set umask to MASK before running programs" //usage: //usage:#define run_parts_example_usage //usage: "$ run-parts -a start /etc/init.d\n" diff --git a/release/src/router/busybox/e2fsprogs/Kbuild.src b/release/src/router/busybox/e2fsprogs/Kbuild.src index 8df2b17504..1172a64c86 100644 --- a/release/src/router/busybox/e2fsprogs/Kbuild.src +++ b/release/src/router/busybox/e2fsprogs/Kbuild.src @@ -13,6 +13,6 @@ lib-$(CONFIG_E2FSCK) += e2fsck.o util.o e2fs_lib.o lib-$(CONFIG_FSCK) += fsck.o lib-$(CONFIG_LSATTR) += lsattr.o e2fs_lib.o lib-$(CONFIG_MKE2FS) += mke2fs.o util.o e2fs_lib.o -lib-$(CONFIG_TUNE2FS) += tune2fs.o util.o e2fs_lib.o +lib-$(CONFIG_TUNE2FS) += tune2fs.o CFLAGS += -include $(srctree)/e2fsprogs/e2fsbb.h diff --git a/release/src/router/busybox/e2fsprogs/fsck.c b/release/src/router/busybox/e2fsprogs/fsck.c index 3a0743bb12..509683625a 100644 --- a/release/src/router/busybox/e2fsprogs/fsck.c +++ b/release/src/router/busybox/e2fsprogs/fsck.c @@ -764,7 +764,7 @@ ret_inst: instance_list = inst->next; if (verbose > 1) printf("Finished with %s (exit status %d)\n", - inst->device, inst->exit_status); + inst->device, inst->exit_status); num_running--; return inst; } @@ -1134,7 +1134,7 @@ static int check_all(void) if (verbose > 1) printf("--waiting-- (pass %d)\n", passno); status |= wait_many(pass_done ? FLAG_WAIT_ALL : - FLAG_WAIT_ATLEAST_ONE); + FLAG_WAIT_ATLEAST_ONE); if (pass_done) { if (verbose > 1) printf("----------------------------------\n"); diff --git a/release/src/router/busybox/e2fsprogs/lsattr.c b/release/src/router/busybox/e2fsprogs/lsattr.c index 9e0e4cb602..9eab68b5b2 100644 --- a/release/src/router/busybox/e2fsprogs/lsattr.c +++ b/release/src/router/busybox/e2fsprogs/lsattr.c @@ -93,7 +93,7 @@ static int lsattr_dir_proc(const char *dir_name, struct dirent *de, path = concat_path_file(dir_name, de->d_name); if (lstat(path, &st) == -1) - bb_perror_msg(path); + bb_simple_perror_msg(path); else { if (de->d_name[0] != '.' || (flags & OPT_ALL)) { list_attributes(path); diff --git a/release/src/router/busybox/e2fsprogs/tune2fs.c b/release/src/router/busybox/e2fsprogs/tune2fs.c dissimilarity index 97% index 464f18d612..4977346788 100644 --- a/release/src/router/busybox/e2fsprogs/tune2fs.c +++ b/release/src/router/busybox/e2fsprogs/tune2fs.c @@ -1,727 +1,95 @@ -/* vi: set sw=4 ts=4: */ -/* - * tune2fs.c - Change the file system parameters on an ext2 file system - * - * Copyright (C) 1992, 1993, 1994 Remy Card - * Laboratoire MASI, Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * Copyright 1995, 1996, 1997, 1998, 1999, 2000 by Theodore Ts'o. - * - * Licensed under GPLv2, see file LICENSE in this source tree. - */ - -//usage:#define tune2fs_trivial_usage -//usage: "[-c MOUNT_CNT] " -//usage: "[-e errors-behavior] [-g group] " -//usage: "[-i DAYS] " -//usage: "[-j] [-J journal-options] [-l] [-s sparse-flag] " -//usage: "[-m reserved-blocks-percent] [-o [^]mount-options[,...]] " -//usage: "[-r reserved-blocks-count] [-u user] [-C mount-count] " -//usage: "[-L LABEL] " -//usage: "[-M last-mounted-dir] [-O [^]feature[,...]] " -//usage: "[-T last-check-time] [-U UUID] " -//usage: "BLOCKDEV" -//usage: -//usage:#define tune2fs_full_usage "\n\n" -//usage: "Adjust filesystem options on ext[23] filesystems" - -/* - * History: - * 93/06/01 - Creation - * 93/10/31 - Added the -c option to change the maximal mount counts - * 93/12/14 - Added -l flag to list contents of superblock - * M.J.E. Mol (marcel@duteca.et.tudelft.nl) - * F.W. ten Wolde (franky@duteca.et.tudelft.nl) - * 93/12/29 - Added the -e option to change errors behavior - * 94/02/27 - Ported to use the ext2fs library - * 94/03/06 - Added the checks interval from Uwe Ohse (uwe@tirka.gun.de) - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "e2fsbb.h" -#include "ext2fs/ext2_fs.h" -#include "ext2fs/ext2fs.h" -#include "e2fs_lib.h" -#include "e2p/e2p.h" -#include "ext2fs/kernel-jbd.h" -#include "util.h" -#include "volume_id.h" - -#include "libbb.h" - -static char * device_name = NULL; -static char * new_label, *new_last_mounted, *new_UUID; -static char * io_options; -static int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag; -static int m_flag, M_flag, r_flag, s_flag = -1, u_flag, U_flag, T_flag; -static time_t last_check_time; -static int print_label; -static int max_mount_count, mount_count, mount_flags; -static unsigned long interval, reserved_blocks; -static unsigned reserved_ratio; -static unsigned long resgid, resuid; -static unsigned short errors; -static int open_flag; -static char *features_cmd; -static char *mntopts_cmd; - -static int journal_size, journal_flags; -static char *journal_device = NULL; - -static const char *please_fsck = "Please run e2fsck on the filesystem\n"; - -static __u32 ok_features[3] = { - EXT3_FEATURE_COMPAT_HAS_JOURNAL | EXT2_FEATURE_COMPAT_DIR_INDEX, - EXT2_FEATURE_INCOMPAT_FILETYPE, - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER -}; - -/* - * Remove an external journal from the filesystem - */ -static void remove_journal_device(ext2_filsys fs) -{ - char *journal_path; - ext2_filsys jfs; - char buf[1024]; - journal_superblock_t *jsb; - int i, nr_users; - errcode_t retval; - int commit_remove_journal = 0; - io_manager io_ptr; - - if (f_flag) - commit_remove_journal = 1; /* force removal even if error */ - - unparse_uuid(fs->super->s_journal_uuid, buf); - journal_path = get_devname_from_uuid(buf); - - if (!journal_path) { - journal_path = - ext2fs_find_block_device(fs->super->s_journal_dev); - if (!journal_path) - return; - } - - io_ptr = unix_io_manager; - retval = ext2fs_open(journal_path, EXT2_FLAG_RW| - EXT2_FLAG_JOURNAL_DEV_OK, 0, - fs->blocksize, io_ptr, &jfs); - if (retval) { - bb_error_msg("Failed to open external journal"); - goto no_valid_journal; - } - if (!(jfs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) { - bb_error_msg("%s is not a journal device", journal_path); - goto no_valid_journal; - } - - /* Get the journal superblock */ - if ((retval = io_channel_read_blk(jfs->io, 1, -1024, buf))) { - bb_error_msg("Failed to read journal superblock"); - goto no_valid_journal; - } - - jsb = (journal_superblock_t *) buf; - if ((jsb->s_header.h_magic != (unsigned) ntohl(JFS_MAGIC_NUMBER)) || - (jsb->s_header.h_blocktype != (unsigned) ntohl(JFS_SUPERBLOCK_V2))) { - bb_error_msg("Journal superblock not found!"); - goto no_valid_journal; - } - - /* Find the filesystem UUID */ - nr_users = ntohl(jsb->s_nr_users); - for (i=0; i < nr_users; i++) { - if (memcmp(fs->super->s_uuid, - &jsb->s_users[i*16], 16) == 0) - break; - } - if (i >= nr_users) { - bb_error_msg("Filesystem's UUID not found on journal device"); - commit_remove_journal = 1; - goto no_valid_journal; - } - nr_users--; - for (i=0; i < nr_users; i++) - memcpy(&jsb->s_users[i*16], &jsb->s_users[(i+1)*16], 16); - jsb->s_nr_users = htonl(nr_users); - - /* Write back the journal superblock */ - if ((retval = io_channel_write_blk(jfs->io, 1, -1024, buf))) { - bb_error_msg("Failed to write journal superblock"); - goto no_valid_journal; - } - - commit_remove_journal = 1; - -no_valid_journal: - if (commit_remove_journal == 0) - bb_error_msg_and_die("Journal NOT removed"); - fs->super->s_journal_dev = 0; - uuid_clear(fs->super->s_journal_uuid); - ext2fs_mark_super_dirty(fs); - puts("Journal removed"); - free(journal_path); -} - -/* Helper function for remove_journal_inode */ -static int release_blocks_proc(ext2_filsys fs, blk_t *blocknr, - int blockcnt EXT2FS_ATTR((unused)), - void *private EXT2FS_ATTR((unused))) -{ - blk_t block; - int group; - - block = *blocknr; - ext2fs_unmark_block_bitmap(fs->block_map,block); - group = ext2fs_group_of_blk(fs, block); - fs->group_desc[group].bg_free_blocks_count++; - fs->super->s_free_blocks_count++; - return 0; -} - -/* - * Remove the journal inode from the filesystem - */ -static void remove_journal_inode(ext2_filsys fs) -{ - struct ext2_inode inode; - errcode_t retval; - ino_t ino = fs->super->s_journal_inum; - const char *msg = "to read"; - const char *s = "journal inode"; - - retval = ext2fs_read_inode(fs, ino, &inode); - if (retval) - goto REMOVE_JOURNAL_INODE_ERROR; - if (ino == EXT2_JOURNAL_INO) { - retval = ext2fs_read_bitmaps(fs); - if (retval) { - msg = "to read bitmaps"; - s = ""; - goto REMOVE_JOURNAL_INODE_ERROR; - } - retval = ext2fs_block_iterate(fs, ino, 0, NULL, - release_blocks_proc, NULL); - if (retval) { - msg = "clearing"; - goto REMOVE_JOURNAL_INODE_ERROR; - } - memset(&inode, 0, sizeof(inode)); - ext2fs_mark_bb_dirty(fs); - fs->flags &= ~EXT2_FLAG_SUPER_ONLY; - } else - inode.i_flags &= ~EXT2_IMMUTABLE_FL; - retval = ext2fs_write_inode(fs, ino, &inode); - if (retval) { - msg = "writing"; -REMOVE_JOURNAL_INODE_ERROR: - bb_error_msg_and_die("Failed %s %s", msg, s); - } - fs->super->s_journal_inum = 0; - ext2fs_mark_super_dirty(fs); -} - -/* - * Update the default mount options - */ -static void update_mntopts(ext2_filsys fs, char *mntopts) -{ - struct ext2_super_block *sb= fs->super; - - if (e2p_edit_mntopts(mntopts, &sb->s_default_mount_opts, ~0)) - bb_error_msg_and_die("Invalid mount option set: %s", mntopts); - ext2fs_mark_super_dirty(fs); -} - -/* - * Update the feature set as provided by the user. - */ -static void update_feature_set(ext2_filsys fs, char *features) -{ - int sparse, old_sparse, filetype, old_filetype; - int journal, old_journal, dxdir, old_dxdir; - struct ext2_super_block *sb= fs->super; - __u32 old_compat, old_incompat, old_ro_compat; - - old_compat = sb->s_feature_compat; - old_ro_compat = sb->s_feature_ro_compat; - old_incompat = sb->s_feature_incompat; - - old_sparse = sb->s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; - old_filetype = sb->s_feature_incompat & - EXT2_FEATURE_INCOMPAT_FILETYPE; - old_journal = sb->s_feature_compat & - EXT3_FEATURE_COMPAT_HAS_JOURNAL; - old_dxdir = sb->s_feature_compat & - EXT2_FEATURE_COMPAT_DIR_INDEX; - if (e2p_edit_feature(features, &sb->s_feature_compat, ok_features)) - bb_error_msg_and_die("Invalid filesystem option set: %s", features); - sparse = sb->s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; - filetype = sb->s_feature_incompat & - EXT2_FEATURE_INCOMPAT_FILETYPE; - journal = sb->s_feature_compat & - EXT3_FEATURE_COMPAT_HAS_JOURNAL; - dxdir = sb->s_feature_compat & - EXT2_FEATURE_COMPAT_DIR_INDEX; - if (old_journal && !journal) { - if ((mount_flags & EXT2_MF_MOUNTED) && - !(mount_flags & EXT2_MF_READONLY)) { - bb_error_msg_and_die( - "The has_journal flag may only be " - "cleared when the filesystem is\n" - "unmounted or mounted " - "read-only"); - } - if (sb->s_feature_incompat & - EXT3_FEATURE_INCOMPAT_RECOVER) { - bb_error_msg_and_die( - "The needs_recovery flag is set. " - "%s before clearing the has_journal flag.", - please_fsck); - } - if (sb->s_journal_inum) { - remove_journal_inode(fs); - } - if (sb->s_journal_dev) { - remove_journal_device(fs); - } - } - if (journal && !old_journal) { - /* - * If adding a journal flag, let the create journal - * code below handle creating setting the flag and - * creating the journal. We supply a default size if - * necessary. - */ - if (!journal_size) - journal_size = -1; - sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL; - } - if (dxdir && !old_dxdir) { - if (!sb->s_def_hash_version) - sb->s_def_hash_version = EXT2_HASH_TEA; - if (uuid_is_null((unsigned char *) sb->s_hash_seed)) - generate_uuid((unsigned char *) sb->s_hash_seed); - } - - if (sb->s_rev_level == EXT2_GOOD_OLD_REV && - (sb->s_feature_compat || sb->s_feature_ro_compat || - sb->s_feature_incompat)) - ext2fs_update_dynamic_rev(fs); - if ((sparse != old_sparse) || - (filetype != old_filetype)) { - sb->s_state &= ~EXT2_VALID_FS; - printf("\n%s\n", please_fsck); - } - if ((old_compat != sb->s_feature_compat) || - (old_ro_compat != sb->s_feature_ro_compat) || - (old_incompat != sb->s_feature_incompat)) - ext2fs_mark_super_dirty(fs); -} - -/* - * Add a journal to the filesystem. - */ -static void add_journal(ext2_filsys fs) -{ - if (fs->super->s_feature_compat & - EXT3_FEATURE_COMPAT_HAS_JOURNAL) { - bb_error_msg_and_die("The filesystem already has a journal"); - } - if (journal_device) { - make_journal_device(journal_device, fs, 0, 0); - } else if (journal_size) { - make_journal_blocks(fs, journal_size, journal_flags, 0); - /* - * If the filesystem wasn't mounted, we need to force - * the block group descriptors out. - */ - if ((mount_flags & EXT2_MF_MOUNTED) == 0) - fs->flags &= ~EXT2_FLAG_SUPER_ONLY; - } - print_check_message(fs); -} - -/* - * Busybox stuff - */ -static char * x_blkid_get_devname(const char *token) -{ - char *dev_name = (char *)token; - - if (resolve_mount_spec(&dev_name) != 1 || !dev_name) - bb_error_msg_and_die("Unable to resolve '%s'", token); - return dev_name; -} - -#ifdef CONFIG_E2LABEL -static void parse_e2label_options(int argc, char ** argv) -{ - if ((argc < 2) || (argc > 3)) - bb_show_usage(); - io_options = strchr(argv[1], '?'); - if (io_options) - *io_options++ = 0; - device_name = x_blkid_get_devname(argv[1]); - if (argc == 3) { - open_flag = EXT2_FLAG_RW | EXT2_FLAG_JOURNAL_DEV_OK; - L_flag = 1; - new_label = argv[2]; - } else - print_label++; -} -#else -#define parse_e2label_options(x,y) -#endif - -static time_t parse_time(char *str) -{ - struct tm ts; - - if (strcmp(str, "now") == 0) { - return time(0); - } - memset(&ts, 0, sizeof(ts)); -#ifdef HAVE_STRPTIME - strptime(str, "%Y%m%d%H%M%S", &ts); -#else - sscanf(str, "%4d%2d%2d%2d%2d%2d", &ts.tm_year, &ts.tm_mon, - &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec); - ts.tm_year -= 1900; - ts.tm_mon -= 1; - if (ts.tm_year < 0 || ts.tm_mon < 0 || ts.tm_mon > 11 || - ts.tm_mday < 0 || ts.tm_mday > 31 || ts.tm_hour > 23 || - ts.tm_min > 59 || ts.tm_sec > 61) - ts.tm_mday = 0; -#endif - if (ts.tm_mday == 0) { - bb_error_msg_and_die("can't parse date/time specifier: %s", str); - } - return mktime(&ts); -} - -static void parse_tune2fs_options(int argc, char **argv) -{ - int c; - char * tmp; - - printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); - while ((c = getopt(argc, argv, "c:e:fg:i:jlm:o:r:s:u:C:J:L:M:O:T:U:")) != EOF) - switch (c) - { - case 'c': - max_mount_count = xatou_range(optarg, 0, 16000); - if (max_mount_count == 0) - max_mount_count = -1; - c_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'C': - mount_count = xatou_range(optarg, 0, 16000); - C_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'e': - if (strcmp (optarg, "continue") == 0) - errors = EXT2_ERRORS_CONTINUE; - else if (strcmp (optarg, "remount-ro") == 0) - errors = EXT2_ERRORS_RO; - else if (strcmp (optarg, "panic") == 0) - errors = EXT2_ERRORS_PANIC; - else { - bb_error_msg_and_die("bad error behavior - %s", optarg); - } - e_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'f': /* Force */ - f_flag = 1; - break; - case 'g': - resgid = bb_strtoul(optarg, NULL, 10); - if (errno) - resgid = xgroup2gid(optarg); - g_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'i': - interval = strtoul(optarg, &tmp, 0); - switch (*tmp) { - case 's': - tmp++; - break; - case '\0': - case 'd': - case 'D': /* days */ - interval *= 86400; - if (*tmp != '\0') - tmp++; - break; - case 'm': - case 'M': /* months! */ - interval *= 86400 * 30; - tmp++; - break; - case 'w': - case 'W': /* weeks */ - interval *= 86400 * 7; - tmp++; - break; - } - if (*tmp || interval > (365 * 86400)) { - bb_error_msg_and_die("bad interval - %s", optarg); - } - i_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'j': - if (!journal_size) - journal_size = -1; - open_flag = EXT2_FLAG_RW; - break; - case 'J': - parse_journal_opts(&journal_device, &journal_flags, &journal_size, optarg); - open_flag = EXT2_FLAG_RW; - break; - case 'l': - l_flag = 1; - break; - case 'L': - new_label = optarg; - L_flag = 1; - open_flag = EXT2_FLAG_RW | - EXT2_FLAG_JOURNAL_DEV_OK; - break; - case 'm': - reserved_ratio = xatou_range(optarg, 0, 50); - m_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'M': - new_last_mounted = optarg; - M_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'o': - if (mntopts_cmd) { - bb_error_msg_and_die("-o may only be specified once"); - } - mntopts_cmd = optarg; - open_flag = EXT2_FLAG_RW; - break; - - case 'O': - if (features_cmd) { - bb_error_msg_and_die("-O may only be specified once"); - } - features_cmd = optarg; - open_flag = EXT2_FLAG_RW; - break; - case 'r': - reserved_blocks = xatoul(optarg); - r_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 's': - s_flag = atoi(optarg); - open_flag = EXT2_FLAG_RW; - break; - case 'T': - T_flag = 1; - last_check_time = parse_time(optarg); - open_flag = EXT2_FLAG_RW; - break; - case 'u': - resuid = bb_strtoul(optarg, NULL, 10); - if (errno) - resuid = xuname2uid(optarg); - u_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'U': - new_UUID = optarg; - U_flag = 1; - open_flag = EXT2_FLAG_RW | - EXT2_FLAG_JOURNAL_DEV_OK; - break; - default: - bb_show_usage(); - } - if (optind < argc - 1 || optind == argc) - bb_show_usage(); - if (!open_flag && !l_flag) - bb_show_usage(); - io_options = strchr(argv[optind], '?'); - if (io_options) - *io_options++ = 0; - device_name = x_blkid_get_devname(argv[optind]); -} - -static void tune2fs_clean_up(void) -{ - if (ENABLE_FEATURE_CLEAN_UP && device_name) free(device_name); - if (ENABLE_FEATURE_CLEAN_UP && journal_device) free(journal_device); -} - -int tune2fs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int tune2fs_main(int argc, char **argv) -{ - errcode_t retval; - ext2_filsys fs; - struct ext2_super_block *sb; - io_manager io_ptr; - - if (ENABLE_FEATURE_CLEAN_UP) - atexit(tune2fs_clean_up); - - if (ENABLE_E2LABEL && (applet_name[0] == 'e')) /* e2label */ - parse_e2label_options(argc, argv); - else - parse_tune2fs_options(argc, argv); /* tune2fs */ - - io_ptr = unix_io_manager; - retval = ext2fs_open2(device_name, io_options, open_flag, - 0, 0, io_ptr, &fs); - if (retval) - bb_error_msg_and_die("No valid superblock on %s", device_name); - sb = fs->super; - if (print_label) { - /* For e2label emulation */ - printf("%.*s\n", (int) sizeof(sb->s_volume_name), - sb->s_volume_name); - return 0; - } - retval = ext2fs_check_if_mounted(device_name, &mount_flags); - if (retval) - bb_error_msg_and_die("can't determine if %s is mounted", device_name); - /* Normally we only need to write out the superblock */ - fs->flags |= EXT2_FLAG_SUPER_ONLY; - - if (c_flag) { - sb->s_max_mnt_count = max_mount_count; - ext2fs_mark_super_dirty(fs); - printf("Setting maximal mount count to %d\n", max_mount_count); - } - if (C_flag) { - sb->s_mnt_count = mount_count; - ext2fs_mark_super_dirty(fs); - printf("Setting current mount count to %d\n", mount_count); - } - if (e_flag) { - sb->s_errors = errors; - ext2fs_mark_super_dirty(fs); - printf("Setting error behavior to %d\n", errors); - } - if (g_flag) { - sb->s_def_resgid = resgid; - ext2fs_mark_super_dirty(fs); - printf("Setting reserved blocks gid to %lu\n", resgid); - } - if (i_flag) { - sb->s_checkinterval = interval; - ext2fs_mark_super_dirty(fs); - printf("Setting interval between check %lu seconds\n", interval); - } - if (m_flag) { - sb->s_r_blocks_count = (sb->s_blocks_count / 100) - * reserved_ratio; - ext2fs_mark_super_dirty(fs); - printf("Setting reserved blocks percentage to %u (%u blocks)\n", - reserved_ratio, sb->s_r_blocks_count); - } - if (r_flag) { - if (reserved_blocks >= sb->s_blocks_count/2) - bb_error_msg_and_die("reserved blocks count is too big (%lu)", reserved_blocks); - sb->s_r_blocks_count = reserved_blocks; - ext2fs_mark_super_dirty(fs); - printf("Setting reserved blocks count to %lu\n", reserved_blocks); - } - if (s_flag == 1) { - if (sb->s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) - bb_error_msg("\nThe filesystem already has sparse superblocks"); - else { - sb->s_feature_ro_compat |= - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; - sb->s_state &= ~EXT2_VALID_FS; - ext2fs_mark_super_dirty(fs); - printf("\nSparse superblock flag set. %s", please_fsck); - } - } - if (s_flag == 0) { - if (!(sb->s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) - bb_error_msg("\nThe filesystem already has sparse superblocks disabled"); - else { - sb->s_feature_ro_compat &= - ~EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; - sb->s_state &= ~EXT2_VALID_FS; - fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; - ext2fs_mark_super_dirty(fs); - printf("\nSparse superblock flag cleared. %s", please_fsck); - } - } - if (T_flag) { - sb->s_lastcheck = last_check_time; - ext2fs_mark_super_dirty(fs); - printf("Setting time filesystem last checked to %s\n", - ctime(&last_check_time)); - } - if (u_flag) { - sb->s_def_resuid = resuid; - ext2fs_mark_super_dirty(fs); - printf("Setting reserved blocks uid to %lu\n", resuid); - } - if (L_flag) { - if (strlen(new_label) > sizeof(sb->s_volume_name)) - bb_error_msg("Warning: label too long, truncating"); - memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name)); - safe_strncpy(sb->s_volume_name, new_label, - sizeof(sb->s_volume_name)); - ext2fs_mark_super_dirty(fs); - } - if (M_flag) { - memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted)); - safe_strncpy(sb->s_last_mounted, new_last_mounted, - sizeof(sb->s_last_mounted)); - ext2fs_mark_super_dirty(fs); - } - if (mntopts_cmd) - update_mntopts(fs, mntopts_cmd); - if (features_cmd) - update_feature_set(fs, features_cmd); - if (journal_size || journal_device) - add_journal(fs); - - if (U_flag) { - if ((strcasecmp(new_UUID, "null") == 0) || - (strcasecmp(new_UUID, "clear") == 0)) { - uuid_clear(sb->s_uuid); -/* - } else if (strcasecmp(new_UUID, "time") == 0) { - uuid_generate_time(sb->s_uuid); -*/ - } else if (strcasecmp(new_UUID, "random") == 0) { - generate_uuid(sb->s_uuid); - } else if (parse_uuid(new_UUID, sb->s_uuid)) { - bb_error_msg_and_die("Invalid UUID format"); - } - ext2fs_mark_super_dirty(fs); - } - - if (l_flag) - list_super (sb); - return (ext2fs_close (fs) ? 1 : 0); -} +/* vi: set sw=4 ts=4: */ +/* + * tune2fs: utility to modify EXT2 filesystem + * + * Busybox'ed (2009) by Vladimir Dronnikov + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ +#include "libbb.h" +#include +#include + +// storage helpers +char BUG_wrong_field_size(void); +#define STORE_LE(field, value) \ +do { \ + if (sizeof(field) == 4) \ + field = SWAP_LE32(value); \ + else if (sizeof(field) == 2) \ + field = SWAP_LE16(value); \ + else if (sizeof(field) == 1) \ + field = (value); \ + else \ + BUG_wrong_field_size(); \ +} while (0) + +#define FETCH_LE32(field) \ + (sizeof(field) == 4 ? SWAP_LE32(field) : BUG_wrong_field_size()) + +//usage:#define tune2fs_trivial_usage +//usage: "[-c MOUNT_CNT] " +//usage: "[-i DAYS] " +//usage: "[-L LABEL] " +//usage: "BLOCKDEV" +//usage: +//usage:#define tune2fs_full_usage "\n\n" +//usage: "Adjust filesystem options on ext[23] filesystems" +//applet:IF_E2LABEL(APPLET_ODDNAME(e2label, tune2fs, BB_DIR_SBIN, BB_SUID_DROP, tune2fs)) + +enum { + OPT_L = 1 << 0, // label + OPT_c = 1 << 1, // max mount count + OPT_i = 1 << 2, // check interval +}; + +int tune2fs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int tune2fs_main(int argc UNUSED_PARAM, char **argv) +{ + unsigned opts; + const char *label, *str_c, *str_i; + struct ext2_super_block *sb; + int fd; + + opt_complementary = "=1"; + opts = getopt32(argv, "L:c:i:", &label, &str_c, &str_i); + if (!opts) + bb_show_usage(); + argv += optind; // argv[0] -- device + + // read superblock + fd = xopen(argv[0], O_RDWR); + xlseek(fd, 1024, SEEK_SET); + sb = xzalloc(1024); + xread(fd, sb, 1024); + + // mangle superblock + //STORE_LE(sb->s_wtime, time(NULL)); - why bother? + + // set the label + if (opts & OPT_L) + safe_strncpy((char *)sb->s_volume_name, label, sizeof(sb->s_volume_name)); + + if (opts & OPT_c) { + int n = xatoi_range(str_c, -1, 0xfffe); + if (n == 0) + n = -1; + STORE_LE(sb->s_max_mnt_count, (unsigned)n); + } + + if (opts & OPT_i) { + unsigned n = xatou_range(str_i, 0, (unsigned)0xffffffff / (24*60*60)) * 24*60*60; + STORE_LE(sb->s_checkinterval, n); + } + + // write superblock + xlseek(fd, 1024, SEEK_SET); + xwrite(fd, sb, 1024); + + if (ENABLE_FEATURE_CLEAN_UP) { + free(sb); + } + + xclose(fd); + return EXIT_SUCCESS; +} diff --git a/release/src/router/busybox/editors/awk.c b/release/src/router/busybox/editors/awk.c index 71abca215a..3224788c0f 100644 --- a/release/src/router/busybox/editors/awk.c +++ b/release/src/router/busybox/editors/awk.c @@ -155,7 +155,7 @@ typedef struct tsplitter_s { /* simple token classes */ /* Order and hex values are very important!!! See next_token() */ -#define TC_SEQSTART 1 /* ( */ +#define TC_SEQSTART 1 /* ( */ #define TC_SEQTERM (1 << 1) /* ) */ #define TC_REGEXP (1 << 2) /* /.../ */ #define TC_OUTRDR (1 << 3) /* | > >> */ @@ -696,6 +696,10 @@ static char nextchar(char **s) pps = *s; if (c == '\\') c = bb_process_escape_sequence((const char**)s); + /* Example awk statement: + * s = "abc\"def" + * we must treat \" as " + */ if (c == '\\' && *s == pps) { /* unrecognized \z? */ c = *(*s); /* yes, fetch z */ if (c) @@ -704,6 +708,15 @@ static char nextchar(char **s) return c; } +/* TODO: merge with strcpy_and_process_escape_sequences()? + */ +static void unescape_string_in_place(char *s1) +{ + char *s = s1; + while ((*s1 = nextchar(&s)) != '\0') + s1++; +} + static ALWAYS_INLINE int isalnum_(int c) { return (isalnum(c) || c == '_'); @@ -1799,6 +1812,18 @@ static void handle_special(var *v) is_f0_split = FALSE; } else if (v == intvar[FS]) { + /* + * The POSIX-2008 standard says that changing FS should have no effect on the + * current input line, but only on the next one. The language is: + * + * > Before the first reference to a field in the record is evaluated, the record + * > shall be split into fields, according to the rules in Regular Expressions, + * > using the value of FS that was current at the time the record was read. + * + * So, split up current line before assignment to FS: + */ + split_f0(); + mk_splitter(getvar_s(v), &fsplitter); } else if (v == intvar[RS]) { @@ -2992,7 +3017,7 @@ static int awk_exit(int r) * otherwise return 0 */ static int is_assignment(const char *expr) { - char *exprc, *val, *s, *s1; + char *exprc, *val; if (!isalnum_(*expr) || (val = strchr(expr, '=')) == NULL) { return FALSE; @@ -3002,10 +3027,7 @@ static int is_assignment(const char *expr) val = exprc + (val - expr); *val++ = '\0'; - s = s1 = val; - while ((*s1 = nextchar(&s)) != '\0') - s1++; - + unescape_string_in_place(val); setvar_u(newvar(exprc), val); free(exprc); return TRUE; @@ -3118,8 +3140,10 @@ int awk_main(int argc, char **argv) opt = getopt32(argv, "F:v:f:W:", &opt_F, &list_v, &list_f, NULL); argv += optind; argc -= optind; - if (opt & 0x1) - setvar_s(intvar[FS], opt_F); // -F + if (opt & 0x1) { /* -F */ + unescape_string_in_place(opt_F); + setvar_s(intvar[FS], opt_F); + } while (list_v) { /* -v */ if (!is_assignment(llist_pop(&list_v))) bb_show_usage(); diff --git a/release/src/router/busybox/editors/diff.c b/release/src/router/busybox/editors/diff.c index 3a33346402..b08ded3a15 100644 --- a/release/src/router/busybox/editors/diff.c +++ b/release/src/router/busybox/editors/diff.c @@ -843,7 +843,7 @@ static void diffdir(char *p[2], const char *s_start) * add_to_dirlist will remove it. */ list[i].len = strlen(p[i]); recursive_action(p[i], ACTION_RECURSE | ACTION_FOLLOWLINKS, - add_to_dirlist, skip_dir, &list[i], 0); + add_to_dirlist, skip_dir, &list[i], 0); /* Sort dl alphabetically. * GNU diff does this ignoring any number of trailing dots. * We don't, so for us dotted files almost always are diff --git a/release/src/router/busybox/editors/sed.c b/release/src/router/busybox/editors/sed.c index 3ee8edc433..f8ca5d3517 100644 --- a/release/src/router/busybox/editors/sed.c +++ b/release/src/router/busybox/editors/sed.c @@ -53,7 +53,9 @@ * Todo: * - Create a wrapper around regex to make libc's regex conform with sed * - * Reference http://www.opengroup.org/onlinepubs/007904975/utilities/sed.html + * Reference + * http://www.opengroup.org/onlinepubs/007904975/utilities/sed.html + * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/sed.html */ //usage:#define sed_trivial_usage @@ -62,7 +64,8 @@ //usage:#define sed_full_usage "\n\n" //usage: " -e CMD Add CMD to sed commands to be executed" //usage: "\n -f FILE Add FILE contents to sed commands to be executed" -//usage: "\n -i Edit files in-place (else sends result to stdout)" +//usage: "\n -i[SFX] Edit files in-place (otherwise sends to stdout)" +//usage: "\n Optionally back files up, appending SFX" //usage: "\n -n Suppress automatic printing of pattern space" //usage: "\n -r Use extended regex syntax" //usage: "\n" @@ -491,8 +494,10 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr) } /* handle edit cmds: (a)ppend, (i)nsert, and (c)hange */ else if (idx <= IDX_c) { /* a,i,c */ - if ((sed_cmd->end_line || sed_cmd->end_match) && sed_cmd->cmd != 'c') - bb_error_msg_and_die("only a beginning address can be specified for edit commands"); + if (idx < IDX_c) { /* a,i */ + if (sed_cmd->end_line || sed_cmd->end_match) + bb_error_msg_and_die("command '%c' uses only one address", sed_cmd->cmd); + } for (;;) { if (*cmdstr == '\n' || *cmdstr == '\\') { cmdstr++; @@ -509,8 +514,10 @@ static const char *parse_cmd_args(sed_cmd_t *sed_cmd, const char *cmdstr) } /* handle file cmds: (r)ead */ else if (idx <= IDX_w) { /* r,w */ - if (sed_cmd->end_line || sed_cmd->end_match) - bb_error_msg_and_die("command only uses one address"); + if (idx < IDX_w) { /* r */ + if (sed_cmd->end_line || sed_cmd->end_match) + bb_error_msg_and_die("command '%c' uses only one address", sed_cmd->cmd); + } cmdstr += parse_file_cmd(/*sed_cmd,*/ cmdstr, &sed_cmd->string); if (sed_cmd->cmd == 'w') { sed_cmd->sw_file = xfopen_for_write(sed_cmd->string); @@ -672,7 +679,7 @@ static void do_subst_w_backrefs(char *line, char *replace) /* go through the replacement string */ for (i = 0; replace[i]; i++) { - /* if we find a backreference (\1, \2, etc.) print the backref'ed * text */ + /* if we find a backreference (\1, \2, etc.) print the backref'ed text */ if (replace[i] == '\\') { unsigned backref = replace[++i] - '0'; if (backref <= 9) { @@ -706,8 +713,10 @@ static void do_subst_w_backrefs(char *line, char *replace) static int do_subst_command(sed_cmd_t *sed_cmd, char **line_p) { char *line = *line_p; - int altered = 0; unsigned match_count = 0; + bool altered = 0; + bool prev_match_empty = 1; + bool tried_at_eol = 0; regex_t *current_regex; current_regex = sed_cmd->sub_match; @@ -734,50 +743,75 @@ static int do_subst_command(sed_cmd_t *sed_cmd, char **line_p) /* Now loop through, substituting for matches */ do { + int start = G.regmatch[0].rm_so; + int end = G.regmatch[0].rm_eo; int i; - /* Work around bug in glibc regexec, demonstrated by: - * echo " a.b" | busybox sed 's [^ .]* x g' - * The match_count check is so not to break - * echo "hi" | busybox sed 's/^/!/g' - */ - if (!G.regmatch[0].rm_so && !G.regmatch[0].rm_eo && match_count) { - pipe_putc(*line++); - goto next; - } - match_count++; /* If we aren't interested in this match, output old line to - end of match and continue */ + * end of match and continue */ if (sed_cmd->which_match && (sed_cmd->which_match != match_count) ) { - for (i = 0; i < G.regmatch[0].rm_eo; i++) + for (i = 0; i < end; i++) + pipe_putc(*line++); + /* Null match? Print one more char */ + if (start == end && *line) pipe_putc(*line++); goto next; } - /* print everything before the match */ - for (i = 0; i < G.regmatch[0].rm_so; i++) + /* Print everything before the match */ + for (i = 0; i < start; i++) pipe_putc(line[i]); - /* then print the substitution string */ - do_subst_w_backrefs(line, sed_cmd->string); + /* Then print the substitution string, + * unless we just matched empty string after non-empty one. + * Example: string "cccd", pattern "c*", repl "R": + * result is "RdR", not "RRdR": first match "ccc", + * second is "" before "d", third is "" after "d". + * Second match is NOT replaced! + */ + if (prev_match_empty || start != 0 || start != end) { + //dbg("%d %d %d", prev_match_empty, start, end); + dbg("inserting replacement at %d in '%s'", start, line); + do_subst_w_backrefs(line, sed_cmd->string); + /* Flag that something has changed */ + altered = 1; + } else { + dbg("NOT inserting replacement at %d in '%s'", start, line); + } - /* advance past the match */ - line += G.regmatch[0].rm_eo; - /* flag that something has changed */ - altered++; + /* If matched string is empty (f.e. "c*" pattern), + * copy verbatim one char after it before attempting more matches + */ + prev_match_empty = (start == end); + if (prev_match_empty) { + if (!line[end]) { + tried_at_eol = 1; + } else { + pipe_putc(line[end]); + end++; + } + } + + /* Advance past the match */ + dbg("line += %d", end); + line += end; /* if we're not doing this globally, get out now */ if (sed_cmd->which_match != 0) break; next: - if (*line == '\0') - break; + /* Exit if we are at EOL and already tried matching at it */ + if (*line == '\0') { + if (tried_at_eol) + break; + tried_at_eol = 1; + } -//maybe (G.regmatch[0].rm_eo ? REG_NOTBOL : 0) instead of unconditional REG_NOTBOL? +//maybe (end ? REG_NOTBOL : 0) instead of unconditional REG_NOTBOL? } while (regexec(current_regex, line, 10, G.regmatch, REG_NOTBOL) != REG_NOMATCH); /* Copy rest of string into output pipeline */ @@ -1043,7 +1077,7 @@ static void process_files(void) /* or does this line matches our last address regex */ || (sed_cmd->end_match && old_matched && (regexec(sed_cmd->end_match, - pattern_space, 0, NULL, 0) == 0) + pattern_space, 0, NULL, 0) == 0) ) ); } @@ -1126,7 +1160,7 @@ static void process_files(void) case 's': if (!do_subst_command(sed_cmd, &pattern_space)) break; - dbg("do_subst_command succeeeded:'%s'", pattern_space); + dbg("do_subst_command succeeded:'%s'", pattern_space); substituted |= 1; /* handle p option */ @@ -1374,6 +1408,19 @@ int sed_main(int argc UNUSED_PARAM, char **argv) { unsigned opt; llist_t *opt_e, *opt_f; + char *opt_i; + +#if ENABLE_LONG_OPTS + static const char sed_longopts[] ALIGN1 = + /* name has_arg short */ + "in-place\0" Optional_argument "i" + "regexp-extended\0" No_argument "r" + "quiet\0" No_argument "n" + "silent\0" No_argument "n" + "expression\0" Required_argument "e" + "file\0" Required_argument "f"; +#endif + int status = EXIT_SUCCESS; INIT_G(); @@ -1382,17 +1429,21 @@ int sed_main(int argc UNUSED_PARAM, char **argv) if (ENABLE_FEATURE_CLEAN_UP) atexit(sed_free_and_close_stuff); /* Lie to autoconf when it starts asking stupid questions. */ - if (argv[1] && !strcmp(argv[1], "--version")) { + if (argv[1] && strcmp(argv[1], "--version") == 0) { puts("This is not GNU sed version 4.0"); return 0; } /* do normal option parsing */ opt_e = opt_f = NULL; + opt_i = NULL; opt_complementary = "e::f::" /* can occur multiple times */ "nn"; /* count -n */ + + IF_LONG_OPTS(applet_long_options = sed_longopts); + /* -i must be first, to match OPT_in_place definition */ - opt = getopt32(argv, "irne:f:", &opt_e, &opt_f, + opt = getopt32(argv, "i::rne:f:", &opt_i, &opt_e, &opt_f, &G.be_quiet); /* counter for -n */ //argc -= optind; argv += optind; @@ -1474,8 +1525,13 @@ int sed_main(int argc UNUSED_PARAM, char **argv) fclose(G.nonstdout); G.nonstdout = stdout; - /* unlink(argv[i]); */ - xrename(G.outname, argv[i]); + if (opt_i) { + char *backupname = xasprintf("%s%s", argv[i], opt_i); + xrename(argv[i], backupname); + free(backupname); + } + /* else unlink(argv[i]); - rename below does this */ + xrename(G.outname, argv[i]); //TODO: rollback backup on error? free(G.outname); G.outname = NULL; diff --git a/release/src/router/busybox/editors/vi.c b/release/src/router/busybox/editors/vi.c index b4ad12e5c9..5b5e2b0bff 100644 --- a/release/src/router/busybox/editors/vi.c +++ b/release/src/router/busybox/editors/vi.c @@ -14,7 +14,7 @@ * add :help command * :map macros * if mark[] values were line numbers rather than pointers - * it would be easier to change the mark when add/delete lines + * it would be easier to change the mark when add/delete lines * More intelligence in refresh() * ":r !cmd" and "!cmd" to filter text through an external command * A true "undo" facility @@ -136,14 +136,6 @@ //config: cursor position using "ESC [ 6 n" escape sequence, then read stdin. //config: //config: This is not clean but helps a lot on serial lines and such. -//config: -//config:config FEATURE_VI_OPTIMIZE_CURSOR -//config: bool "Optimize cursor movement" -//config: default y -//config: depends on VI -//config: help -//config: This will make the cursor movement faster, but requires more memory -//config: and it makes the applet a tiny bit larger. //applet:IF_VI(APPLET(vi, BB_DIR_BIN, BB_SUID_DROP)) @@ -154,12 +146,12 @@ //usage:#define vi_full_usage "\n\n" //usage: "Edit FILE\n" //usage: IF_FEATURE_VI_COLON( -//usage: "\n -c Initial command to run ($EXINIT also available)" +//usage: "\n -c CMD Initial command to run ($EXINIT also available)" //usage: ) //usage: IF_FEATURE_VI_READONLY( //usage: "\n -R Read-only" //usage: ) -//usage: "\n -H Short help regarding available features" +//usage: "\n -H List available features" #include "libbb.h" /* Should be after libbb.h: on some systems regex.h needs sys/types.h: */ @@ -202,20 +194,29 @@ enum { MAX_SCR_ROWS = CONFIG_FEATURE_VI_MAX_LEN, }; -/* vt102 typical ESC sequence */ -/* terminal standout start/normal ESC sequence */ -#define SOs "\033[7m" -#define SOn "\033[0m" -/* terminal bell sequence */ -#define bell "\007" -/* Clear-end-of-line and Clear-end-of-screen ESC sequence */ -#define Ceol "\033[K" -#define Ceos "\033[J" -/* Cursor motion arbitrary destination ESC sequence */ -#define CMrc "\033[%u;%uH" -/* Cursor motion up and down ESC sequence */ -#define CMup "\033[A" -#define CMdown "\n" +/* VT102 ESC sequences. + * See "Xterm Control Sequences" + * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html + */ +/* Inverse/Normal text */ +#define ESC_BOLD_TEXT "\033[7m" +#define ESC_NORM_TEXT "\033[0m" +/* Bell */ +#define ESC_BELL "\007" +/* Clear-to-end-of-line */ +#define ESC_CLEAR2EOL "\033[K" +/* Clear-to-end-of-screen. + * (We use default param here. + * Full sequence is "ESC [ J", + * is 0/1/2 = "erase below/above/all".) + */ +#define ESC_CLEAR2EOS "\033[J" +/* Cursor to given coordinate (1,1: top left) */ +#define ESC_SET_CURSOR_POS "\033[%u;%uH" +//UNUSED +///* Cursor up and down */ +//#define ESC_CURSOR_UP "\033[A" +//#define ESC_CURSOR_DOWN "\n" #if ENABLE_FEATURE_VI_DOT_CMD || ENABLE_FEATURE_VI_YANKMARK // cmds modifying text[] @@ -303,9 +304,6 @@ struct globals { int lmc_len; // length of last_modifying_cmd char *ioq, *ioq_start; // pointer to string for get_one_char to "read" #endif -#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR - int last_row; // where the cursor was last moved to -#endif #if ENABLE_FEATURE_VI_USE_SIGNALS || ENABLE_FEATURE_VI_CRASHME int my_pid; #endif @@ -389,7 +387,6 @@ struct globals { #define lmc_len (G.lmc_len ) #define ioq (G.ioq ) #define ioq_start (G.ioq_start ) -#define last_row (G.last_row ) #define my_pid (G.my_pid ) #define last_search_pattern (G.last_search_pattern) @@ -470,10 +467,7 @@ static int file_size(const char *); // what is the byte size of "fn" // file_insert might reallocate text[]! static int file_insert(const char *, char *, int); static int file_write(char *, char *, char *); -#if !ENABLE_FEATURE_VI_OPTIMIZE_CURSOR -#define place_cursor(a, b, optimize) place_cursor(a, b) -#endif -static void place_cursor(int, int, int); +static void place_cursor(int, int); static void screen_erase(void); static void clear_to_eol(void); static void clear_to_eos(void); @@ -558,7 +552,8 @@ int vi_main(int argc, char **argv) } #endif - vi_setops = VI_AUTOINDENT | VI_SHOWMATCH | VI_IGNORECASE; + // autoindent is not default in vim 7.3 + vi_setops = /*VI_AUTOINDENT |*/ VI_SHOWMATCH | VI_IGNORECASE; // 1- process $HOME/.exrc file (not inplemented yet) // 2- process EXINIT variable from environment // 3- process command line args @@ -584,7 +579,7 @@ int vi_main(int argc, char **argv) #if ENABLE_FEATURE_VI_COLON case 'c': // cmd line vi command if (*optarg) - initial_cmds[initial_cmds[0] != 0] = xstrndup(optarg, MAX_INPUT_LEN); + initial_cmds[initial_cmds[0] != NULL] = xstrndup(optarg, MAX_INPUT_LEN); break; #endif case 'H': @@ -599,15 +594,19 @@ int vi_main(int argc, char **argv) // The argv array can be used by the ":next" and ":rewind" commands argv += optind; argc -= optind; - save_argc = argc; - optind = 0; //----- This is the main file handling loop -------------- + save_argc = argc; + optind = 0; + // "Save cursor, use alternate screen buffer, clear screen" + write1("\033[?1049h"); while (1) { edit_file(argv[optind]); /* param might be NULL */ if (++optind >= argc) break; } + // "Use normal screen buffer, restore cursor" + write1("\033[?1049l"); //----------------------------------------------------------- return 0; @@ -1191,7 +1190,7 @@ static void colon(char *buf) char *argp; #endif i = 0; // offset into args - // only blank is regarded as args delmiter. What about tab '\t' ? + // only blank is regarded as args delimiter. What about tab '\t'? if (!args[0] || strcasecmp(args, "all") == 0) { // print out values of all options #if ENABLE_FEATURE_VI_SETOPTS @@ -1930,11 +1929,11 @@ static int find_range(char **start, char **stop, char c) dot_end(); // find NL q = dot; } else { - // nothing -- this causes any other values of c to - // represent the one-character range under the - // cursor. this is correct for ' ' and 'l', but - // perhaps no others. - // + // nothing -- this causes any other values of c to + // represent the one-character range under the + // cursor. this is correct for ' ' and 'l', but + // perhaps no others. + // } if (q < p) { t = q; @@ -2176,7 +2175,7 @@ static void show_help(void) "\n\tPattern searches with / and ?" #endif #if ENABLE_FEATURE_VI_DOT_CMD - "\n\tLast command repeat with \'.\'" + "\n\tLast command repeat with ." #endif #if ENABLE_FEATURE_VI_YANKMARK "\n\tLine marking with 'x" @@ -2187,7 +2186,7 @@ static void show_help(void) //redundant: usage text says this too: "\n\tReadonly with -R command line arg" #endif #if ENABLE_FEATURE_VI_SET - "\n\tSome colon mode commands with \':\'" + "\n\tSome colon mode commands with :" #endif #if ENABLE_FEATURE_VI_SETOPTS "\n\tSettable options with \":set\"" @@ -2592,107 +2591,56 @@ static int file_write(char *fn, char *first, char *last) // 23,0 ... 23,79 <- status line //----- Move the cursor to row x col (count from 0, not 1) ------- -static void place_cursor(int row, int col, int optimize) +static void place_cursor(int row, int col) { - char cm1[sizeof(CMrc) + sizeof(int)*3 * 2]; -#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR - enum { - SZ_UP = sizeof(CMup), - SZ_DN = sizeof(CMdown), - SEQ_SIZE = SZ_UP > SZ_DN ? SZ_UP : SZ_DN, - }; - char cm2[SEQ_SIZE * 5 + 32]; // bigger than worst case size -#endif - char *cm; + char cm1[sizeof(ESC_SET_CURSOR_POS) + sizeof(int)*3 * 2]; if (row < 0) row = 0; if (row >= rows) row = rows - 1; if (col < 0) col = 0; if (col >= columns) col = columns - 1; - //----- 1. Try the standard terminal ESC sequence - sprintf(cm1, CMrc, row + 1, col + 1); - cm = cm1; - -#if ENABLE_FEATURE_VI_OPTIMIZE_CURSOR - if (optimize && col < 16) { - char *screenp; - int Rrow = last_row; - int diff = Rrow - row; - - if (diff < -5 || diff > 5) - goto skip; - - //----- find the minimum # of chars to move cursor ------------- - //----- 2. Try moving with discreet chars (Newline, [back]space, ...) - cm2[0] = '\0'; - - // move to the correct row - while (row < Rrow) { - // the cursor has to move up - strcat(cm2, CMup); - Rrow--; - } - while (row > Rrow) { - // the cursor has to move down - strcat(cm2, CMdown); - Rrow++; - } - - // now move to the correct column - strcat(cm2, "\r"); // start at col 0 - // just send out orignal source char to get to correct place - screenp = &screen[row * columns]; // start of screen line - strncat(cm2, screenp, col); - - // pick the shortest cursor motion to send out - if (strlen(cm2) < strlen(cm)) { - cm = cm2; - } - skip: ; - } - last_row = row; -#endif /* FEATURE_VI_OPTIMIZE_CURSOR */ - write1(cm); + sprintf(cm1, ESC_SET_CURSOR_POS, row + 1, col + 1); + write1(cm1); } //----- Erase from cursor to end of line ----------------------- static void clear_to_eol(void) { - write1(Ceol); // Erase from cursor to end of line + write1(ESC_CLEAR2EOL); } static void go_bottom_and_clear_to_eol(void) { - place_cursor(rows - 1, 0, FALSE); // go to bottom of screen - clear_to_eol(); // erase to end of line + place_cursor(rows - 1, 0); + clear_to_eol(); } //----- Erase from cursor to end of screen ----------------------- static void clear_to_eos(void) { - write1(Ceos); // Erase from cursor to end of screen + write1(ESC_CLEAR2EOS); } //----- Start standout mode ------------------------------------ -static void standout_start(void) // send "start reverse video" sequence +static void standout_start(void) { - write1(SOs); // Start reverse video mode + write1(ESC_BOLD_TEXT); } //----- End standout mode -------------------------------------- -static void standout_end(void) // send "end reverse video" sequence +static void standout_end(void) { - write1(SOn); // End reverse video mode + write1(ESC_NORM_TEXT); } //----- Flash the screen -------------------------------------- static void flash(int h) { - standout_start(); // send "start reverse video" sequence + standout_start(); redraw(TRUE); mysleep(h); - standout_end(); // send "end reverse video" sequence + standout_end(); redraw(TRUE); } @@ -2703,7 +2651,7 @@ static void Indicate_Error(void) return; // generate a random command #endif if (!err_method) { - write1(bell); // send out a bell character + write1(ESC_BELL); } else { flash(10); } @@ -2749,7 +2697,7 @@ static void show_status_line(void) } have_status_msg = 0; } - place_cursor(crow, ccol, FALSE); // put cursor back in correct place + place_cursor(crow, ccol); // put cursor back in correct place } fflush_all(); } @@ -2761,12 +2709,12 @@ static void status_line_bold(const char *format, ...) va_list args; va_start(args, format); - strcpy(status_buffer, SOs); // Terminal standout mode on - vsprintf(status_buffer + sizeof(SOs)-1, format, args); - strcat(status_buffer, SOn); // Terminal standout mode off + strcpy(status_buffer, ESC_BOLD_TEXT); + vsprintf(status_buffer + sizeof(ESC_BOLD_TEXT)-1, format, args); + strcat(status_buffer, ESC_NORM_TEXT); va_end(args); - have_status_msg = 1 + sizeof(SOs) + sizeof(SOn) - 2; + have_status_msg = 1 + sizeof(ESC_BOLD_TEXT) + sizeof(ESC_NORM_TEXT) - 2; } // format status buffer @@ -2798,8 +2746,8 @@ static void print_literal(char *buf, const char *s) c = *s; c_is_no_print = (c & 0x80) && !Isprint(c); if (c_is_no_print) { - strcpy(d, SOn); - d += sizeof(SOn)-1; + strcpy(d, ESC_NORM_TEXT); + d += sizeof(ESC_NORM_TEXT)-1; c = '.'; } if (c < ' ' || c == 0x7f) { @@ -2811,8 +2759,8 @@ static void print_literal(char *buf, const char *s) *d++ = c; *d = '\0'; if (c_is_no_print) { - strcpy(d, SOs); - d += sizeof(SOs)-1; + strcpy(d, ESC_BOLD_TEXT); + d += sizeof(ESC_BOLD_TEXT)-1; } if (*s == '\n') { *d++ = '$'; @@ -2894,8 +2842,8 @@ static int format_edit_status(void) //----- Force refresh of all Lines ----------------------------- static void redraw(int full_screen) { - place_cursor(0, 0, FALSE); // put cursor in correct place - clear_to_eos(); // tell terminal to erase display + place_cursor(0, 0); + clear_to_eos(); screen_erase(); // erase the internal screen buffer last_status_cksum = 0; // force status update refresh(full_screen); // this will redraw the entire display @@ -3035,22 +2983,13 @@ static void refresh(int full_screen) if (changed) { // copy changed part of buffer to virtual screen memcpy(sp+cs, out_buf+cs, ce-cs+1); - - // move cursor to column of first change - //if (offset != old_offset) { - // // place_cursor is still too stupid - // // to handle offsets correctly - // place_cursor(li, cs, FALSE); - //} else { - place_cursor(li, cs, TRUE); - //} - + place_cursor(li, cs); // write line out to terminal fwrite(&sp[cs], ce - cs + 1, 1, stdout); } } - place_cursor(crow, ccol, TRUE); + place_cursor(crow, ccol); old_offset = offset; #undef old_offset @@ -3220,9 +3159,9 @@ static void do_cmd(int c) break; case 12: // ctrl-L force redraw whole screen case 18: // ctrl-R force redraw - place_cursor(0, 0, FALSE); // put cursor in correct place - clear_to_eos(); // tel terminal to erase display - mysleep(10); + place_cursor(0, 0); + clear_to_eos(); + //mysleep(10); // why??? screen_erase(); // erase the internal screen buffer last_status_cksum = 0; // force status update refresh(TRUE); // this will redraw the entire display @@ -4141,7 +4080,7 @@ static void crash_test() if (msg[0]) { printf("\n\n%d: \'%c\' %s\n\n\n%s[Hit return to continue]%s", - totalcmds, last_input_char, msg, SOs, SOn); + totalcmds, last_input_char, msg, ESC_BOLD_TEXT, ESC_NORM_TEXT); fflush_all(); while (safe_read(STDIN_FILENO, d, 1) > 0) { if (d[0] == '\n' || d[0] == '\r') diff --git a/release/src/router/busybox/examples/mdev.conf b/release/src/router/busybox/examples/mdev.conf index cdbb4fcfea..51795694d9 100644 --- a/release/src/router/busybox/examples/mdev.conf +++ b/release/src/router/busybox/examples/mdev.conf @@ -7,8 +7,14 @@ # instead of the default 0:0 660. # # Syntax: -# %s %d:%d %s -# devicename_regex user:group mode +# [-]devicename_regex user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] +# [-]$ENVVAR=regex user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] +# [-]@maj,min[-min2] user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] +# +# [-]: do not stop on this match, continue reading mdev.conf +# =: move, >: move and create a symlink +# !: do not create device node +# @|$|*: run@cmd if $ACTION=add, $cmd if $ACTION=remove, *cmd in all cases null 0:0 666 zero 0:0 666 diff --git a/release/src/router/busybox/examples/mdev_fat.conf b/release/src/router/busybox/examples/mdev_fat.conf index df329b4b54..ceba3a797a 100644 --- a/release/src/router/busybox/examples/mdev_fat.conf +++ b/release/src/router/busybox/examples/mdev_fat.conf @@ -7,10 +7,14 @@ # instead of the default 0:0 660. # # Syntax: -# [-]devicename_regex user:group mode [>|=path] [@|$|*cmd args...] +# [-]devicename_regex user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] +# [-]$ENVVAR=regex user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] +# [-]@maj,min[-min2] user:group mode [=path]|[>path]|[!] [@|$|*cmd args...] # +# [-]: do not stop on this match, continue reading mdev.conf # =: move, >: move and create a symlink -# @|$|*: run $cmd on delete, @cmd on create, *cmd on both +# !: do not create device node +# @|$|*: run cmd if $ACTION=remove, @cmd if $ACTION=add, *cmd in all cases # support module loading on hotplug $MODALIAS=.* root:root 660 @modprobe "$MODALIAS" @@ -49,7 +53,6 @@ sr[0-9]* root:cdrom 660 @ln -sf $MDEV cdrom fd[0-9]* root:floppy 660 # net devices --net/.* root:root 600 @nameif tun[0-9]* root:root 600 =net/ tap[0-9]* root:root 600 =net/ diff --git a/release/src/router/busybox/findutils/find.c b/release/src/router/busybox/findutils/find.c index 0ec5bdfeaa..2235b50493 100644 --- a/release/src/router/busybox/findutils/find.c +++ b/release/src/router/busybox/findutils/find.c @@ -728,10 +728,27 @@ static int FAST_FUNC fileAction(const char *fileName, int depth IF_NOT_FEATURE_FIND_MAXDEPTH(UNUSED_PARAM)) { int r; + int same_fs = 1; + +#if ENABLE_FEATURE_FIND_XDEV + if (S_ISDIR(statbuf->st_mode) && G.xdev_count) { + int i; + for (i = 0; i < G.xdev_count; i++) { + if (G.xdev_dev[i] == statbuf->st_dev) + goto found; + } + //bb_error_msg("'%s': not same fs", fileName); + same_fs = 0; + found: ; + } +#endif #if ENABLE_FEATURE_FIND_MAXDEPTH - if (depth < G.minmaxdepth[0]) - return TRUE; /* skip this, continue recursing */ + if (depth < G.minmaxdepth[0]) { + if (same_fs) + return TRUE; /* skip this, continue recursing */ + return SKIP; /* stop recursing */ + } if (depth > G.minmaxdepth[1]) return SKIP; /* stop recursing */ #endif @@ -747,21 +764,11 @@ static int FAST_FUNC fileAction(const char *fileName, return SKIP; } #endif -#if ENABLE_FEATURE_FIND_XDEV /* -xdev stops on mountpoints, but AFTER mountpoit itself * is processed as usual */ - if (S_ISDIR(statbuf->st_mode)) { - if (G.xdev_count) { - int i; - for (i = 0; i < G.xdev_count; i++) { - if (G.xdev_dev[i] == statbuf->st_dev) - goto found; - } - return SKIP; - found: ; - } + if (!same_fs) { + return SKIP; } -#endif /* Cannot return 0: our caller, recursive_action(), * will perror() and skip dirs (if called on dir) */ @@ -871,8 +878,8 @@ static action*** parse_params(char **argv) IF_FEATURE_FIND_EXEC( "-exec\0" ) IF_FEATURE_FIND_PAREN( "(\0" ) /* All options/actions starting from here require argument */ - "-name\0" - "-iname\0" + "-name\0" + "-iname\0" IF_FEATURE_FIND_PATH( "-path\0" ) #if ENABLE_DESKTOP IF_FEATURE_FIND_PATH( "-wholename\0") diff --git a/release/src/router/busybox/findutils/grep.c b/release/src/router/busybox/findutils/grep.c index f14d6e6c1c..70f3516a53 100644 --- a/release/src/router/busybox/findutils/grep.c +++ b/release/src/router/busybox/findutils/grep.c @@ -344,10 +344,34 @@ static int grep_file(FILE *file) while (pattern_ptr) { gl = (grep_list_data_t *)pattern_ptr->data; if (FGREP_FLAG) { - found |= (((option_mask32 & OPT_i) - ? strcasestr(line, gl->pattern) - : strstr(line, gl->pattern) - ) != NULL); + char *match; + char *str = line; + opt_f_again: + match = ((option_mask32 & OPT_i) + ? strcasestr(str, gl->pattern) + : strstr(str, gl->pattern) + ); + if (match) { + if (option_mask32 & OPT_x) { + if (match != str) + goto opt_f_not_found; + if (str[strlen(gl->pattern)] != '\0') + goto opt_f_not_found; + } else + if (option_mask32 & OPT_w) { + char c = (match != str) ? match[-1] : ' '; + if (!isalnum(c) && c != '_') { + c = match[strlen(gl->pattern)]; + if (!c || (!isalnum(c) && c != '_')) + goto opt_f_found; + } + str = match + 1; + goto opt_f_again; + } + opt_f_found: + found = 1; + opt_f_not_found: ; + } } else { if (!(gl->flg_mem_alocated_compiled & COMPILED)) { gl->flg_mem_alocated_compiled |= COMPILED; @@ -376,7 +400,8 @@ static int grep_file(FILE *file) if (option_mask32 & OPT_x) { found = (gl->matched_range.rm_so == 0 && line[gl->matched_range.rm_eo] == '\0'); - } else if (!(option_mask32 & OPT_w)) { + } else + if (!(option_mask32 & OPT_w)) { found = 1; } else { char c = ' '; @@ -387,6 +412,8 @@ static int grep_file(FILE *file) if (!c || (!isalnum(c) && c != '_')) found = 1; } +//BUG: "echo foop foo | grep -w foo" should match, but doesn't: +//we bail out on first "mismatch" because it's not a word. } } } @@ -638,7 +665,7 @@ int grep_main(int argc UNUSED_PARAM, char **argv) if (opts & OPT_C) { /* -C unsets prev -A and -B, but following -A or -B - may override it */ + * may override it */ if (!(opts & OPT_A)) /* not overridden */ lines_after = Copt; if (!(opts & OPT_B)) /* not overridden */ diff --git a/release/src/router/busybox/include/applets.src.h b/release/src/router/busybox/include/applets.src.h index 252a060fb1..bb79147ab4 100644 --- a/release/src/router/busybox/include/applets.src.h +++ b/release/src/router/busybox/include/applets.src.h @@ -70,12 +70,12 @@ INSERT IF_TEST(APPLET_NOFORK([, test, BB_DIR_USR_BIN, BB_SUID_DROP, test)) IF_TEST(APPLET_NOFORK([[, test, BB_DIR_USR_BIN, BB_SUID_DROP, test)) IF_ACPID(APPLET(acpid, BB_DIR_SBIN, BB_SUID_DROP)) -IF_ADDGROUP(APPLET(addgroup, BB_DIR_BIN, BB_SUID_DROP)) -IF_ADDUSER(APPLET(adduser, BB_DIR_BIN, BB_SUID_DROP)) +IF_ADDGROUP(APPLET(addgroup, BB_DIR_USR_SBIN, BB_SUID_DROP)) +IF_ADDUSER(APPLET(adduser, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_ADJTIMEX(APPLET(adjtimex, BB_DIR_SBIN, BB_SUID_DROP)) IF_AR(APPLET(ar, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_ARP(APPLET(arp, BB_DIR_SBIN, BB_SUID_DROP)) -IF_ARPING(APPLET(arping, BB_DIR_USR_BIN, BB_SUID_DROP)) +IF_ARPING(APPLET(arping, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_AWK(APPLET_NOEXEC(awk, awk, BB_DIR_USR_BIN, BB_SUID_DROP, awk)) IF_BASENAME(APPLET_NOFORK(basename, basename, BB_DIR_USR_BIN, BB_SUID_DROP, basename)) IF_BBCONFIG(APPLET(bbconfig, BB_DIR_BIN, BB_SUID_DROP)) @@ -86,7 +86,7 @@ IF_BZIP2(APPLET(bzip2, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_CAL(APPLET(cal, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_CAT(APPLET_NOFORK(cat, cat, BB_DIR_BIN, BB_SUID_DROP, cat)) IF_CATV(APPLET(catv, BB_DIR_BIN, BB_SUID_DROP)) -IF_CHAT(APPLET(chat, BB_DIR_USR_BIN, BB_SUID_DROP)) +IF_CHAT(APPLET(chat, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_CHATTR(APPLET(chattr, BB_DIR_BIN, BB_SUID_DROP)) IF_CHCON(APPLET(chcon, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_CHGRP(APPLET_NOEXEC(chgrp, chgrp, BB_DIR_BIN, BB_SUID_DROP, chgrp)) @@ -111,8 +111,8 @@ IF_CUT(APPLET_NOEXEC(cut, cut, BB_DIR_USR_BIN, BB_SUID_DROP, cut)) IF_DC(APPLET(dc, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_DD(APPLET_NOEXEC(dd, dd, BB_DIR_BIN, BB_SUID_DROP, dd)) IF_DEALLOCVT(APPLET(deallocvt, BB_DIR_USR_BIN, BB_SUID_DROP)) -IF_DELGROUP(APPLET_ODDNAME(delgroup, deluser, BB_DIR_BIN, BB_SUID_DROP, delgroup)) -IF_DELUSER(APPLET(deluser, BB_DIR_BIN, BB_SUID_DROP)) +IF_DELGROUP(APPLET_ODDNAME(delgroup, deluser, BB_DIR_USR_SBIN, BB_SUID_DROP, delgroup)) +IF_DELUSER(APPLET(deluser, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_DEVFSD(APPLET(devfsd, BB_DIR_SBIN, BB_SUID_DROP)) IF_DEVMEM(APPLET(devmem, BB_DIR_SBIN, BB_SUID_DROP)) IF_DF(APPLET(df, BB_DIR_BIN, BB_SUID_DROP)) @@ -136,7 +136,7 @@ IF_EJECT(APPLET(eject, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_ENV(APPLET_NOEXEC(env, env, BB_DIR_USR_BIN, BB_SUID_DROP, env)) IF_ENVDIR(APPLET_ODDNAME(envdir, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, envdir)) IF_ENVUIDGID(APPLET_ODDNAME(envuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, envuidgid)) -IF_ETHER_WAKE(APPLET_ODDNAME(ether-wake, ether_wake, BB_DIR_USR_BIN, BB_SUID_DROP, ether_wake)) +IF_ETHER_WAKE(APPLET_ODDNAME(ether-wake, ether_wake, BB_DIR_USR_SBIN, BB_SUID_DROP, ether_wake)) IF_EXPAND(APPLET(expand, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_EXPR(APPLET(expr, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_FAKEIDENTD(APPLET(fakeidentd, BB_DIR_USR_SBIN, BB_SUID_DROP)) @@ -144,7 +144,7 @@ IF_FALSE(APPLET_NOFORK(false, false, BB_DIR_BIN, BB_SUID_DROP, false)) IF_FBSET(APPLET(fbset, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_FBSPLASH(APPLET(fbsplash, BB_DIR_SBIN, BB_SUID_DROP)) IF_FDFLUSH(APPLET_ODDNAME(fdflush, freeramdisk, BB_DIR_BIN, BB_SUID_DROP, fdflush)) -IF_FDFORMAT(APPLET(fdformat, BB_DIR_USR_BIN, BB_SUID_DROP)) +IF_FDFORMAT(APPLET(fdformat, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_FDISK(APPLET(fdisk, BB_DIR_SBIN, BB_SUID_DROP)) IF_FGCONSOLE(APPLET(fgconsole, BB_DIR_USR_BIN, BB_SUID_DROP)) /* Benefits from suid root: better access to /dev/BLOCKDEVs: */ @@ -182,7 +182,7 @@ IF_HWCLOCK(APPLET(hwclock, BB_DIR_SBIN, BB_SUID_DROP)) IF_IFCONFIG(APPLET(ifconfig, BB_DIR_SBIN, BB_SUID_DROP)) IF_IFUPDOWN(APPLET_ODDNAME(ifdown, ifupdown, BB_DIR_SBIN, BB_SUID_DROP, ifdown)) IF_IFENSLAVE(APPLET(ifenslave, BB_DIR_SBIN, BB_SUID_DROP)) -IF_IFPLUGD(APPLET(ifplugd, BB_DIR_USR_BIN, BB_SUID_DROP)) +IF_IFPLUGD(APPLET(ifplugd, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_IFUPDOWN(APPLET_ODDNAME(ifup, ifupdown, BB_DIR_SBIN, BB_SUID_DROP, ifup)) IF_INETD(APPLET(inetd, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_INOTIFYD(APPLET(inotifyd, BB_DIR_SBIN, BB_SUID_DROP)) @@ -193,20 +193,20 @@ IF_IONICE(APPLET(ionice, BB_DIR_BIN, BB_SUID_DROP)) || ENABLE_FEATURE_IP_LINK \ || ENABLE_FEATURE_IP_TUNNEL \ || ENABLE_FEATURE_IP_RULE -IF_IP(APPLET(ip, BB_DIR_BIN, BB_SUID_DROP)) +IF_IP(APPLET(ip, BB_DIR_SBIN, BB_SUID_DROP)) #endif -IF_IPADDR(APPLET(ipaddr, BB_DIR_BIN, BB_SUID_DROP)) +IF_IPADDR(APPLET(ipaddr, BB_DIR_SBIN, BB_SUID_DROP)) IF_IPCALC(APPLET(ipcalc, BB_DIR_BIN, BB_SUID_DROP)) IF_IPCRM(APPLET(ipcrm, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_IPCS(APPLET(ipcs, BB_DIR_USR_BIN, BB_SUID_DROP)) -IF_IPLINK(APPLET(iplink, BB_DIR_BIN, BB_SUID_DROP)) -IF_IPROUTE(APPLET(iproute, BB_DIR_BIN, BB_SUID_DROP)) -IF_IPRULE(APPLET(iprule, BB_DIR_BIN, BB_SUID_DROP)) -IF_IPTUNNEL(APPLET(iptunnel, BB_DIR_BIN, BB_SUID_DROP)) -IF_KBD_MODE(APPLET(kbd_mode, BB_DIR_USR_BIN, BB_SUID_DROP)) +IF_IPLINK(APPLET(iplink, BB_DIR_SBIN, BB_SUID_DROP)) +IF_IPROUTE(APPLET(iproute, BB_DIR_SBIN, BB_SUID_DROP)) +IF_IPRULE(APPLET(iprule, BB_DIR_SBIN, BB_SUID_DROP)) +IF_IPTUNNEL(APPLET(iptunnel, BB_DIR_SBIN, BB_SUID_DROP)) +IF_KBD_MODE(APPLET(kbd_mode, BB_DIR_BIN, BB_SUID_DROP)) IF_KILL(APPLET(kill, BB_DIR_BIN, BB_SUID_DROP)) IF_KILLALL(APPLET_ODDNAME(killall, kill, BB_DIR_USR_BIN, BB_SUID_DROP, killall)) -IF_KILLALL5(APPLET_ODDNAME(killall5, kill, BB_DIR_USR_BIN, BB_SUID_DROP, killall5)) +IF_KILLALL5(APPLET_ODDNAME(killall5, kill, BB_DIR_USR_SBIN, BB_SUID_DROP, killall5)) IF_KLOGD(APPLET(klogd, BB_DIR_SBIN, BB_SUID_DROP)) IF_LAST(APPLET(last, BB_DIR_USR_BIN, BB_SUID_DROP)) //IF_LENGTH(APPLET_NOFORK(length, length, BB_DIR_USR_BIN, BB_SUID_DROP, length)) @@ -288,7 +288,7 @@ IF_PWD(APPLET_NOFORK(pwd, pwd, BB_DIR_BIN, BB_SUID_DROP, pwd)) IF_RAIDAUTORUN(APPLET(raidautorun, BB_DIR_SBIN, BB_SUID_DROP)) IF_RDATE(APPLET(rdate, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_RDEV(APPLET(rdev, BB_DIR_USR_SBIN, BB_SUID_DROP)) -IF_READAHEAD(APPLET(readahead, BB_DIR_USR_BIN, BB_SUID_DROP)) +IF_READAHEAD(APPLET(readahead, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_READLINK(APPLET(readlink, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_READPROFILE(APPLET(readprofile, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_REALPATH(APPLET(realpath, BB_DIR_USR_BIN, BB_SUID_DROP)) @@ -303,7 +303,7 @@ IF_RMDIR(APPLET_NOFORK(rmdir, rmdir, BB_DIR_BIN, BB_SUID_DROP, rmdir)) IF_ROUTE(APPLET(route, BB_DIR_SBIN, BB_SUID_DROP)) IF_RPM(APPLET(rpm, BB_DIR_BIN, BB_SUID_DROP)) IF_RPM2CPIO(APPLET(rpm2cpio, BB_DIR_USR_BIN, BB_SUID_DROP)) -IF_RTCWAKE(APPLET(rtcwake, BB_DIR_USR_BIN, BB_SUID_DROP)) +IF_RTCWAKE(APPLET(rtcwake, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_RUN_PARTS(APPLET_ODDNAME(run-parts, run_parts, BB_DIR_BIN, BB_SUID_DROP, run_parts)) IF_RUNCON(APPLET(runcon, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_RUNLEVEL(APPLET(runlevel, BB_DIR_SBIN, BB_SUID_DROP)) @@ -328,6 +328,7 @@ IF_SETSEBOOL(APPLET(setsebool, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_SETSID(APPLET(setsid, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_SETUIDGID(APPLET_ODDNAME(setuidgid, chpst, BB_DIR_USR_BIN, BB_SUID_DROP, setuidgid)) IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum)) +IF_SHA3SUM(APPLET_NOEXEC(sha3sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha3sum)) IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum)) IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha512sum)) IF_SHOWKEY(APPLET(showkey, BB_DIR_USR_BIN, BB_SUID_DROP)) @@ -365,7 +366,7 @@ IF_TELNETD(APPLET(telnetd, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_TEST(APPLET_NOFORK(test, test, BB_DIR_USR_BIN, BB_SUID_DROP, test)) #if ENABLE_FEATURE_TFTP_GET || ENABLE_FEATURE_TFTP_PUT IF_TFTP(APPLET(tftp, BB_DIR_USR_BIN, BB_SUID_DROP)) -IF_TFTPD(APPLET(tftpd, BB_DIR_USR_BIN, BB_SUID_DROP)) +IF_TFTPD(APPLET(tftpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) #endif IF_TIME(APPLET(time, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_TIMEOUT(APPLET(timeout, BB_DIR_USR_BIN, BB_SUID_DROP)) @@ -380,6 +381,7 @@ IF_TTYSIZE(APPLET(ttysize, BB_DIR_USR_BIN, BB_SUID_DROP)) IF_TUNCTL(APPLET(tunctl, BB_DIR_SBIN, BB_SUID_DROP)) IF_TUNE2FS(APPLET(tune2fs, BB_DIR_SBIN, BB_SUID_DROP)) IF_UDHCPC(APPLET(udhcpc, BB_DIR_SBIN, BB_SUID_DROP)) +IF_UDHCPC_OLD(APPLET(udhcpc, BB_DIR_SBIN, BB_SUID_DROP)) IF_UDHCPD(APPLET(udhcpd, BB_DIR_USR_SBIN, BB_SUID_DROP)) IF_UDPSVD(APPLET_ODDNAME(udpsvd, tcpudpsvd, BB_DIR_USR_BIN, BB_SUID_DROP, udpsvd)) IF_UMOUNT(APPLET(umount, BB_DIR_BIN, BB_SUID_DROP)) diff --git a/release/src/router/busybox/include/bb_archive.h b/release/src/router/busybox/include/bb_archive.h index 2043d8570d..a7a2a11358 100644 --- a/release/src/router/busybox/include/bb_archive.h +++ b/release/src/router/busybox/include/bb_archive.h @@ -121,6 +121,7 @@ typedef struct archive_handle_t { #define ARCHIVE_DONT_RESTORE_PERM (1 << 6) #define ARCHIVE_NUMERIC_OWNER (1 << 7) #define ARCHIVE_O_TRUNC (1 << 8) +#define ARCHIVE_REMEMBER_NAMES (1 << 9) /* POSIX tar Header Block, from POSIX 1003.1-1990 */ @@ -219,9 +220,9 @@ IF_DESKTOP(long long) int unpack_xz_stream(transformer_aux_data_t *aux, int src_ char* append_ext(char *filename, const char *expected_ext) FAST_FUNC; int bbunpack(char **argv, - IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_aux_data_t *aux), - char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), - const char *expected_ext + IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_aux_data_t *aux), + char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), + const char *expected_ext ) FAST_FUNC; void check_errors_in_children(int signo); diff --git a/release/src/router/busybox/include/bb_e2fs_defs.h b/release/src/router/busybox/include/bb_e2fs_defs.h index 3edff8377c..b400f8c119 100644 --- a/release/src/router/busybox/include/bb_e2fs_defs.h +++ b/release/src/router/busybox/include/bb_e2fs_defs.h @@ -406,21 +406,21 @@ struct ext2_super_block { * Performance hints. Directory preallocation should only * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on. */ - uint8_t s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ - uint8_t s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ + uint8_t s_prealloc_blocks; /* Nr of blocks to try to preallocate*/ + uint8_t s_prealloc_dir_blocks; /* Nr to preallocate for dirs */ uint16_t s_reserved_gdt_blocks; /* Per group table for online growth */ /* * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set. */ - uint8_t s_journal_uuid[16]; /* uuid of journal superblock */ - uint32_t s_journal_inum; /* inode number of journal file */ +/*D0*/ uint8_t s_journal_uuid[16]; /* uuid of journal superblock */ +/*E0*/ uint32_t s_journal_inum; /* inode number of journal file */ uint32_t s_journal_dev; /* device number of journal file */ uint32_t s_last_orphan; /* start of list of inodes to delete */ uint32_t s_hash_seed[4]; /* HTREE hash seed */ uint8_t s_def_hash_version; /* Default hash version to use */ uint8_t s_jnl_backup_type; /* Default type of journal backup */ uint16_t s_reserved_word_pad; - uint32_t s_default_mount_opts; +/*100*/ uint32_t s_default_mount_opts; uint32_t s_first_meta_bg; /* First metablock group */ /* ext3 additions */ uint32_t s_mkfs_time; /* When the filesystem was created */ @@ -481,6 +481,7 @@ struct BUG_ext2_super_block { #define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \ ( EXT2_SB(sb)->s_feature_incompat & (mask) ) +/* for s_feature_compat */ #define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001 #define EXT2_FEATURE_COMPAT_IMAGIC_INODES 0x0002 #define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 @@ -488,23 +489,45 @@ struct BUG_ext2_super_block { #define EXT2_FEATURE_COMPAT_RESIZE_INO 0x0010 #define EXT2_FEATURE_COMPAT_DIR_INDEX 0x0020 +/* for s_feature_ro_compat */ #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 #define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 -/* #define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 not used */ +#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 /* not used */ +#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008 +#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 +#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 +#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 +/* for s_feature_incompat */ #define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001 #define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 -#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ -#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ +#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 +#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 #define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 -#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 +#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 +#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 +#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 +#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 #define EXT2_FEATURE_COMPAT_SUPP 0 -#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE) #define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ EXT2_FEATURE_RO_COMPAT_BTREE_DIR) +#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ + EXT2_FEATURE_INCOMPAT_META_BG) +#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED (~EXT2_FEATURE_INCOMPAT_SUPP) +#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED (~EXT2_FEATURE_RO_COMPAT_SUPP) + +#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ + EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ + EXT2_FEATURE_RO_COMPAT_BTREE_DIR) +#define EXT3_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ + EXT3_FEATURE_INCOMPAT_RECOVER| \ + EXT2_FEATURE_INCOMPAT_META_BG) +#define EXT3_FEATURE_INCOMPAT_UNSUPPORTED (~EXT3_FEATURE_INCOMPAT_SUPP) +#define EXT3_FEATURE_RO_COMPAT_UNSUPPORTED (~EXT3_FEATURE_RO_COMPAT_SUPP) + /* * Default values for user and/or group using reserved blocks diff --git a/release/src/router/busybox/include/busybox.h b/release/src/router/busybox/include/busybox.h index 315ef8f266..b1e31e5ee6 100644 --- a/release/src/router/busybox/include/busybox.h +++ b/release/src/router/busybox/include/busybox.h @@ -13,10 +13,10 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN /* Defined in appletlib.c (by including generated applet_tables.h) */ /* Keep in sync with applets/applet_tables.c! */ -extern const char applet_names[]; +extern const char applet_names[] ALIGN1; extern int (*const applet_main[])(int argc, char **argv); extern const uint16_t applet_nameofs[]; -extern const uint8_t applet_install_loc[]; +extern const uint8_t applet_install_loc[] ALIGN1; #if ENABLE_FEATURE_SUID || ENABLE_FEATURE_PREFER_APPLETS # define APPLET_NAME(i) (applet_names + (applet_nameofs[i] & 0x0fff)) diff --git a/release/src/router/busybox/include/grp_.h b/release/src/router/busybox/include/grp_.h index 82ad904921..e5075e5a0b 100644 --- a/release/src/router/busybox/include/grp_.h +++ b/release/src/router/busybox/include/grp_.h @@ -64,7 +64,7 @@ extern struct group *fgetgrent(FILE *__stream); /* Write the given entry onto the given stream. */ extern int putgrent(const struct group *__restrict __p, - FILE *__restrict __f); + FILE *__restrict __f); #endif /* Search for an entry with a matching group ID. */ @@ -82,32 +82,32 @@ extern struct group *getgrnam(const char *__name); POSIX people would choose. */ extern int getgrent_r(struct group *__restrict __resultbuf, - char *__restrict __buffer, size_t __buflen, - struct group **__restrict __result); + char *__restrict __buffer, size_t __buflen, + struct group **__restrict __result); /* Search for an entry with a matching group ID. */ extern int getgrgid_r(gid_t __gid, struct group *__restrict __resultbuf, - char *__restrict __buffer, size_t __buflen, - struct group **__restrict __result); + char *__restrict __buffer, size_t __buflen, + struct group **__restrict __result); /* Search for an entry with a matching group name. */ extern int getgrnam_r(const char *__restrict __name, - struct group *__restrict __resultbuf, - char *__restrict __buffer, size_t __buflen, - struct group **__restrict __result); + struct group *__restrict __resultbuf, + char *__restrict __buffer, size_t __buflen, + struct group **__restrict __result); /* Read a group entry from STREAM. This function is not standardized an probably never will. */ extern int fgetgrent_r(FILE *__restrict __stream, - struct group *__restrict __resultbuf, - char *__restrict __buffer, size_t __buflen, - struct group **__restrict __result); + struct group *__restrict __resultbuf, + char *__restrict __buffer, size_t __buflen, + struct group **__restrict __result); /* Store at most *NGROUPS members of the group set for USER into *GROUPS. Also include GROUP. The actual number of groups found is returned in *NGROUPS. Return -1 if the if *NGROUPS is too small. */ extern int getgrouplist(const char *__user, gid_t __group, - gid_t *__groups, int *__ngroups); + gid_t *__groups, int *__ngroups); /* Initialize the group set for the current user by reading the group database and using all groups diff --git a/release/src/router/busybox/include/libbb.h b/release/src/router/busybox/include/libbb.h index 6ae8c504fa..4c9f754f69 100644 --- a/release/src/router/busybox/include/libbb.h +++ b/release/src/router/busybox/include/libbb.h @@ -333,6 +333,7 @@ enum { /* DO NOT CHANGE THESE VALUES! cp.c, mv.c, install.c depend on them. */ FILEUTILS_PRESERVE_SECURITY_CONTEXT = 1 << 9, /* -c */ FILEUTILS_SET_SECURITY_CONTEXT = 1 << 10, #endif + FILEUTILS_IGNORE_CHMOD_ERR = 1 << 11, }; #define FILEUTILS_CP_OPTSTR "pdRfilsLH" IF_SELINUX("c") extern int remove_file(const char *path, int flags) FAST_FUNC; @@ -795,7 +796,6 @@ void qsort_string_vector(char **sv, unsigned count) FAST_FUNC; int safe_poll(struct pollfd *ufds, nfds_t nfds, int timeout_ms) FAST_FUNC; char *safe_gethostname(void) FAST_FUNC; -char *safe_getdomainname(void) FAST_FUNC; /* Convert each alpha char in str to lower-case */ char* str_tolower(char *str) FAST_FUNC; @@ -1252,7 +1252,7 @@ extern void run_shell(const char *shell, int loginshell, const char *command, co * Note that getpwuid result might need xstrdup'ing * if there is a possibility of intervening getpwxxx() calls. */ -const char *get_shell_name(void); +const char *get_shell_name(void) FAST_FUNC; #if ENABLE_SELINUX extern void renew_current_security_context(void) FAST_FUNC; @@ -1290,6 +1290,7 @@ int sd_listen_fds(void); #define SETUP_ENV_CHANGEENV (1 << 0) #define SETUP_ENV_CLEARENV (1 << 1) #define SETUP_ENV_TO_TMP (1 << 2) +#define SETUP_ENV_NO_CHDIR (1 << 4) extern void setup_environment(const char *shell, int flags, const struct passwd *pw) FAST_FUNC; extern int correct_password(const struct passwd *pw) FAST_FUNC; /* Returns a malloced string */ @@ -1519,7 +1520,7 @@ struct smaprec { procps_read_smaps(pid, total) #endif int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, - void (*cb)(struct smaprec *, void *), void *data); + void (*cb)(struct smaprec *, void *), void *data); typedef struct procps_status_t { DIR *dir; @@ -1615,8 +1616,8 @@ unsigned get_cpu_count(void) FAST_FUNC; char *percent_decode_in_place(char *str, int strict) FAST_FUNC; -extern const char bb_uuenc_tbl_base64[]; -extern const char bb_uuenc_tbl_std[]; +extern const char bb_uuenc_tbl_base64[] ALIGN1; +extern const char bb_uuenc_tbl_std[] ALIGN1; void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC; enum { BASE64_FLAG_UU_STOP = 0x100, @@ -1639,8 +1640,12 @@ typedef struct sha512_ctx_t { uint64_t hash[8]; uint8_t wbuffer[128]; /* always correctly aligned for uint64_t */ } sha512_ctx_t; +typedef struct sha3_ctx_t { + uint64_t state[25]; + unsigned bytes_queued; +} sha3_ctx_t; void md5_begin(md5_ctx_t *ctx) FAST_FUNC; -void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC; +void md5_hash(md5_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC; void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC; #define sha1_hash md5_hash @@ -1651,6 +1656,9 @@ void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC; void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC; void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC; +void sha3_begin(sha3_ctx_t *ctx) FAST_FUNC; +void sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC; +void sha3_end(sha3_ctx_t *ctx, void *resbuf) FAST_FUNC; extern uint32_t *global_crc32_table; uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC; @@ -1697,24 +1705,24 @@ extern const char *applet_name; * Therefore now we use #defines. */ /* "BusyBox vN.N.N (timestamp or extra_version)" */ -extern const char bb_banner[]; -extern const char bb_msg_memory_exhausted[]; -extern const char bb_msg_invalid_date[]; +extern const char bb_banner[] ALIGN1; +extern const char bb_msg_memory_exhausted[] ALIGN1; +extern const char bb_msg_invalid_date[] ALIGN1; #define bb_msg_read_error "read error" #define bb_msg_write_error "write error" -extern const char bb_msg_unknown[]; -extern const char bb_msg_can_not_create_raw_socket[]; -extern const char bb_msg_perm_denied_are_you_root[]; -extern const char bb_msg_you_must_be_root[]; -extern const char bb_msg_requires_arg[]; -extern const char bb_msg_invalid_arg[]; -extern const char bb_msg_standard_input[]; -extern const char bb_msg_standard_output[]; +extern const char bb_msg_unknown[] ALIGN1; +extern const char bb_msg_can_not_create_raw_socket[] ALIGN1; +extern const char bb_msg_perm_denied_are_you_root[] ALIGN1; +extern const char bb_msg_you_must_be_root[] ALIGN1; +extern const char bb_msg_requires_arg[] ALIGN1; +extern const char bb_msg_invalid_arg[] ALIGN1; +extern const char bb_msg_standard_input[] ALIGN1; +extern const char bb_msg_standard_output[] ALIGN1; /* NB: (bb_hexdigits_upcase[i] | 0x20) -> lowercase hex digit */ -extern const char bb_hexdigits_upcase[]; +extern const char bb_hexdigits_upcase[] ALIGN1; -extern const char bb_path_wtmp_file[]; +extern const char bb_path_wtmp_file[] ALIGN1; /* Busybox mount uses either /proc/mounts or /etc/mtab to * get the list of currently mounted filesystems */ @@ -1728,10 +1736,10 @@ extern const char bb_path_wtmp_file[]; #define bb_path_motd_file "/etc/motd" #define bb_dev_null "/dev/null" -extern const char bb_busybox_exec_path[]; +extern const char bb_busybox_exec_path[] ALIGN1; /* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin, * but I want to save a few bytes here */ -extern const char bb_PATH_root_path[]; /* "PATH=/sbin:/usr/sbin:/bin:/usr/bin" */ +extern const char bb_PATH_root_path[] ALIGN1; /* "PATH=/sbin:/usr/sbin:/bin:/usr/bin" */ #define bb_default_root_path (bb_PATH_root_path + sizeof("PATH")) #define bb_default_path (bb_PATH_root_path + sizeof("PATH=/sbin:/usr/sbin:/opt/sbin")) @@ -1761,7 +1769,7 @@ extern struct globals *const ptr_to_globals; * If you change LIBBB_DEFAULT_LOGIN_SHELL, * don't forget to change increment constant. */ #define LIBBB_DEFAULT_LOGIN_SHELL "-/bin/sh" -extern const char bb_default_login_shell[]; +extern const char bb_default_login_shell[] ALIGN1; /* "/bin/sh" */ #define DEFAULT_SHELL (bb_default_login_shell+1) /* "sh" */ diff --git a/release/src/router/busybox/include/platform.h b/release/src/router/busybox/include/platform.h index d79cc97e5a..f4deb30c0f 100644 --- a/release/src/router/busybox/include/platform.h +++ b/release/src/router/busybox/include/platform.h @@ -205,6 +205,7 @@ #include typedef int bb__aliased_int FIX_ALIASING; +typedef long bb__aliased_long FIX_ALIASING; typedef uint16_t bb__aliased_uint16_t FIX_ALIASING; typedef uint32_t bb__aliased_uint32_t FIX_ALIASING; @@ -212,7 +213,8 @@ typedef uint32_t bb__aliased_uint32_t FIX_ALIASING; * a lvalue. This makes it more likely to not swap them by mistake */ #if defined(i386) || defined(__x86_64__) || defined(__powerpc__) -# define move_from_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp)) +# define move_from_unaligned_int(v, intp) ((v) = *(bb__aliased_int*)(intp)) +# define move_from_unaligned_long(v, longp) ((v) = *(bb__aliased_long*)(longp)) # define move_from_unaligned16(v, u16p) ((v) = *(bb__aliased_uint16_t*)(u16p)) # define move_from_unaligned32(v, u32p) ((v) = *(bb__aliased_uint32_t*)(u32p)) # define move_to_unaligned16(u16p, v) (*(bb__aliased_uint16_t*)(u16p) = (v)) @@ -221,11 +223,12 @@ typedef uint32_t bb__aliased_uint32_t FIX_ALIASING; #else /* performs reasonably well (gcc usually inlines memcpy here) */ # define move_from_unaligned_int(v, intp) (memcpy(&(v), (intp), sizeof(int))) +# define move_from_unaligned_long(v, longp) (memcpy(&(v), (longp), sizeof(long))) # define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2)) # define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4)) # define move_to_unaligned16(u16p, v) do { \ uint16_t __t = (v); \ - memcpy((u16p), &__t, 4); \ + memcpy((u16p), &__t, 2); \ } while (0) # define move_to_unaligned32(u32p, v) do { \ uint32_t __t = (v); \ @@ -284,7 +287,8 @@ typedef unsigned smalluint; #define fdprintf dprintf /* Useful for defeating gcc's alignment of "char message[]"-like data */ -#if 1 /* if needed: !defined(arch1) && !defined(arch2) */ +#if !defined(__s390__) + /* on s390[x], non-word-aligned data accesses require larger code */ # define ALIGN1 __attribute__((aligned(1))) # define ALIGN2 __attribute__((aligned(2))) # define ALIGN4 __attribute__((aligned(4))) @@ -334,6 +338,12 @@ typedef unsigned smalluint; # define MAXSYMLINKS SYMLOOP_MAX #endif +#if defined(ANDROID) || defined(__ANDROID__) +# define BB_ADDITIONAL_PATH ":/system/sbin:/system/bin:/system/xbin" +# define SYS_ioprio_set __NR_ioprio_set +# define SYS_ioprio_get __NR_ioprio_get +#endif + /* ---- Who misses what? ------------------------------------ */ diff --git a/release/src/router/busybox/include/pwd_.h b/release/src/router/busybox/include/pwd_.h index ea158da452..625b6f5a2e 100644 --- a/release/src/router/busybox/include/pwd_.h +++ b/release/src/router/busybox/include/pwd_.h @@ -63,7 +63,7 @@ extern struct passwd *fgetpwent(FILE *__stream); /* Write the given entry onto the given stream. */ extern int putpwent(const struct passwd *__restrict __p, - FILE *__restrict __f); + FILE *__restrict __f); #endif /* Search for an entry with a matching user ID. */ @@ -81,25 +81,25 @@ extern struct passwd *getpwnam(const char *__name); POSIX people would choose. */ extern int getpwent_r(struct passwd *__restrict __resultbuf, - char *__restrict __buffer, size_t __buflen, - struct passwd **__restrict __result); + char *__restrict __buffer, size_t __buflen, + struct passwd **__restrict __result); extern int getpwuid_r(uid_t __uid, - struct passwd *__restrict __resultbuf, - char *__restrict __buffer, size_t __buflen, - struct passwd **__restrict __result); + struct passwd *__restrict __resultbuf, + char *__restrict __buffer, size_t __buflen, + struct passwd **__restrict __result); extern int getpwnam_r(const char *__restrict __name, - struct passwd *__restrict __resultbuf, - char *__restrict __buffer, size_t __buflen, - struct passwd **__restrict __result); + struct passwd *__restrict __resultbuf, + char *__restrict __buffer, size_t __buflen, + struct passwd **__restrict __result); /* Read an entry from STREAM. This function is not standardized and probably never will. */ extern int fgetpwent_r(FILE *__restrict __stream, - struct passwd *__restrict __resultbuf, - char *__restrict __buffer, size_t __buflen, - struct passwd **__restrict __result); + struct passwd *__restrict __resultbuf, + char *__restrict __buffer, size_t __buflen, + struct passwd **__restrict __result); POP_SAVED_FUNCTION_VISIBILITY diff --git a/release/src/router/busybox/include/shadow_.h b/release/src/router/busybox/include/shadow_.h index 648a62ab32..7babe4f30e 100644 --- a/release/src/router/busybox/include/shadow_.h +++ b/release/src/router/busybox/include/shadow_.h @@ -79,21 +79,21 @@ extern int putspent(const struct spwd *__p, FILE *__stream); /* Reentrant versions of some of the functions above */ extern int getspent_r(struct spwd *__result_buf, char *__buffer, - size_t __buflen, struct spwd **__result); + size_t __buflen, struct spwd **__result); #endif extern int getspnam_r(const char *__name, struct spwd *__result_buf, - char *__buffer, size_t __buflen, - struct spwd **__result); + char *__buffer, size_t __buflen, + struct spwd **__result); #ifdef UNUSED_FOR_NOW extern int sgetspent_r(const char *__string, struct spwd *__result_buf, - char *__buffer, size_t __buflen, - struct spwd **__result); + char *__buffer, size_t __buflen, + struct spwd **__result); extern int fgetspent_r(FILE *__stream, struct spwd *__result_buf, - char *__buffer, size_t __buflen, - struct spwd **__result); + char *__buffer, size_t __buflen, + struct spwd **__result); /* Protect password file against multi writers */ extern int lckpwdf(void); diff --git a/release/src/router/busybox/init/init.c b/release/src/router/busybox/init/init.c index 7248946988..b84bdccbc3 100644 --- a/release/src/router/busybox/init/init.c +++ b/release/src/router/busybox/init/init.c @@ -520,7 +520,7 @@ static pid_t run(const struct init_action *a) /* Log the process name and args */ message(L_LOG, "starting pid %d, tty '%s': '%s'", - getpid(), a->terminal, a->command); + getpid(), a->terminal, a->command); /* Now run it. The new program will take over this PID, * so nothing further in init.c should be run. */ diff --git a/release/src/router/busybox/libbb/Config.src b/release/src/router/busybox/libbb/Config.src index ee1b66a458..19021fed13 100644 --- a/release/src/router/busybox/libbb/Config.src +++ b/release/src/router/busybox/libbb/Config.src @@ -28,6 +28,16 @@ config MD5_SMALL 2 3.0 5088 3 (smallest) 5.1 4912 +config SHA3_SMALL + int "SHA3: Trade bytes for speed (0:fast, 1:slow)" + default 1 + range 0 1 + help + Trade binary size versus speed for the sha3sum algorithm. + SHA3_SMALL=0 compared to SHA3_SMALL=1 (approximate): + 64-bit x86: +270 bytes of code, 45% faster + 32-bit x86: +450 bytes of code, 75% faster + config FEATURE_FAST_TOP bool "Faster /proc scanning code (+100 bytes)" default y diff --git a/release/src/router/busybox/libbb/Kbuild.src b/release/src/router/busybox/libbb/Kbuild.src index 61eec26f70..e1ae3daedd 100644 --- a/release/src/router/busybox/libbb/Kbuild.src +++ b/release/src/router/busybox/libbb/Kbuild.src @@ -170,6 +170,7 @@ lib-$(CONFIG_PING) += inet_cksum.o lib-$(CONFIG_TRACEROUTE) += inet_cksum.o lib-$(CONFIG_TRACEROUTE6) += inet_cksum.o lib-$(CONFIG_UDHCPC) += inet_cksum.o +lib-$(CONFIG_UDHCPC_OLD) += inet_cksum.o lib-$(CONFIG_UDHCPC6) += inet_cksum.o lib-$(CONFIG_UDHCPD) += inet_cksum.o diff --git a/release/src/router/busybox/libbb/appletlib.c b/release/src/router/busybox/libbb/appletlib.c index 73f71f1d02..67df44690b 100644 --- a/release/src/router/busybox/libbb/appletlib.c +++ b/release/src/router/busybox/libbb/appletlib.c @@ -140,10 +140,9 @@ void FAST_FUNC bb_show_usage(void) } #if NUM_APPLETS > 8 -/* NB: any char pointer will work as well, not necessarily applet_names */ -static int applet_name_compare(const void *name, const void *v) +static int applet_name_compare(const void *name, const void *idx) { - int i = (const char *)v - applet_names; + int i = (int)(ptrdiff_t)idx - 1; return strcmp(name, APPLET_NAME(i)); } #endif @@ -152,10 +151,12 @@ int FAST_FUNC find_applet_by_name(const char *name) #if NUM_APPLETS > 8 /* Do a binary search to find the applet entry given the name. */ const char *p; - p = bsearch(name, applet_names, ARRAY_SIZE(applet_main), 1, applet_name_compare); - if (!p) - return -1; - return p - applet_names; + p = bsearch(name, (void*)(ptrdiff_t)1, ARRAY_SIZE(applet_main), 1, applet_name_compare); + /* + * if (!p) return -1; + * ^^^^^^^^^^^^^^^^^^ the code below will do this if p == NULL :) + */ + return (int)(ptrdiff_t)p - 1; #else /* A version which does not pull in bsearch */ int i = 0; @@ -627,11 +628,11 @@ static int busybox_main(char **argv) full_write2_str(bb_banner); /* reuse const string */ full_write2_str(" multi-call binary.\n"); /* reuse */ full_write2_str( - "Copyright (C) 1998-2011 Erik Andersen, Rob Landley, Denys Vlasenko\n" - "and others. Licensed under GPLv2.\n" - "See source distribution for full notice.\n" + "BusyBox is copyrighted by many authors between 1998-2012.\n" + "Licensed under GPLv2. See source distribution for detailed\n" + "copyright notices.\n" "\n" - "Usage: busybox [function] [arguments]...\n" + "Usage: busybox [function [arguments]...]\n" " or: busybox --list"IF_FEATURE_INSTALLER("[-full]")"\n" IF_FEATURE_INSTALLER( " or: busybox --install [-s] [DIR]\n" @@ -747,8 +748,11 @@ void FAST_FUNC run_applet_no_and_exit(int applet_no, char **argv) /* Special case. POSIX says "test --help" * should be no different from e.g. "test --foo". */ //TODO: just compare applet_no with APPLET_NO_test - if (!ENABLE_TEST || strcmp(applet_name, "test") != 0) + if (!ENABLE_TEST || strcmp(applet_name, "test") != 0) { + /* If you want "foo --help" to return 0: */ + /*xfunc_error_retval = 0;*/ bb_show_usage(); + } } if (ENABLE_FEATURE_SUID) check_suid(applet_no); diff --git a/release/src/router/busybox/libbb/correct_password.c b/release/src/router/busybox/libbb/correct_password.c index 6301589e6a..7cabd33d07 100644 --- a/release/src/router/busybox/libbb/correct_password.c +++ b/release/src/router/busybox/libbb/correct_password.c @@ -41,12 +41,6 @@ int FAST_FUNC correct_password(const struct passwd *pw) char *unencrypted, *encrypted; const char *correct; int r; -#if ENABLE_FEATURE_SHADOWPASSWDS - /* Using _r function to avoid pulling in static buffers */ - struct spwd spw; - char buffer[256]; -#endif - /* fake salt. crypt() can choke otherwise. */ correct = "aa"; if (!pw) { @@ -55,7 +49,10 @@ int FAST_FUNC correct_password(const struct passwd *pw) } correct = pw->pw_passwd; #if ENABLE_FEATURE_SHADOWPASSWDS + /* Using _r function to avoid pulling in static buffers */ if ((correct[0] == 'x' || correct[0] == '*') && !correct[1]) { + struct spwd spw; + char buffer[256]; /* getspnam_r may return 0 yet set result to NULL. * At least glibc 2.4 does this. Be extra paranoid here. */ struct spwd *result = NULL; diff --git a/release/src/router/busybox/libbb/get_shell_name.c b/release/src/router/busybox/libbb/get_shell_name.c index c930afd94e..5aebe9cdcc 100644 --- a/release/src/router/busybox/libbb/get_shell_name.c +++ b/release/src/router/busybox/libbb/get_shell_name.c @@ -8,7 +8,7 @@ #include "libbb.h" -const char *get_shell_name(void) +const char* FAST_FUNC get_shell_name(void) { struct passwd *pw; char *shell; diff --git a/release/src/router/busybox/libbb/hash_md5_sha.c b/release/src/router/busybox/libbb/hash_md5_sha.c index a313c2a65c..b4d955e5a3 100644 --- a/release/src/router/busybox/libbb/hash_md5_sha.c +++ b/release/src/router/busybox/libbb/hash_md5_sha.c @@ -31,6 +31,11 @@ static ALWAYS_INLINE uint64_t rotr64(uint64_t x, unsigned n) return (x >> n) | (x << (64 - n)); } +/* rotl64 only used for sha3 currently */ +static ALWAYS_INLINE uint64_t rotl64(uint64_t x, unsigned n) +{ + return (x << n) | (x >> (64 - n)); +} /* Feed data through a temporary buffer. * The internal buffer remembers previous data until it has 64 @@ -51,7 +56,7 @@ static void FAST_FUNC common64_hash(md5_ctx_t *ctx, const void *buffer, size_t l len -= remaining; buffer = (const char *)buffer + remaining; bufpos += remaining; - /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */ + /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */ bufpos -= 64; if (bufpos != 0) break; @@ -185,10 +190,9 @@ static void FAST_FUNC md5_process_block64(md5_ctx_t *ctx) int i; uint32_t temp; -# if BB_BIG_ENDIAN - for (i = 0; i < 16; i++) - words[i] = SWAP_LE32(words[i]); -# endif + if (BB_BIG_ENDIAN) + for (i = 0; i < 16; i++) + words[i] = SWAP_LE32(words[i]); # if MD5_SMALL == 3 pc = C_array; @@ -462,12 +466,13 @@ void FAST_FUNC md5_end(md5_ctx_t *ctx, void *resbuf) common64_end(ctx, /*swap_needed:*/ BB_BIG_ENDIAN); /* The MD5 result is in little endian byte order */ -#if BB_BIG_ENDIAN - ctx->hash[0] = SWAP_LE32(ctx->hash[0]); - ctx->hash[1] = SWAP_LE32(ctx->hash[1]); - ctx->hash[2] = SWAP_LE32(ctx->hash[2]); - ctx->hash[3] = SWAP_LE32(ctx->hash[3]); -#endif + if (BB_BIG_ENDIAN) { + ctx->hash[0] = SWAP_LE32(ctx->hash[0]); + ctx->hash[1] = SWAP_LE32(ctx->hash[1]); + ctx->hash[2] = SWAP_LE32(ctx->hash[2]); + ctx->hash[3] = SWAP_LE32(ctx->hash[3]); + } + memcpy(resbuf, ctx->hash, sizeof(ctx->hash[0]) * 4); } @@ -834,7 +839,7 @@ void FAST_FUNC sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) len -= remaining; buffer = (const char *)buffer + remaining; bufpos += remaining; - /* clever way to do "if (bufpos != 128) break; ... ; bufpos = 0;" */ + /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */ bufpos -= 128; if (bufpos != 0) break; @@ -896,3 +901,268 @@ void FAST_FUNC sha512_end(sha512_ctx_t *ctx, void *resbuf) } memcpy(resbuf, ctx->hash, sizeof(ctx->hash)); } + + +/* + * The Keccak sponge function, designed by Guido Bertoni, Joan Daemen, + * Michael Peeters and Gilles Van Assche. For more information, feedback or + * questions, please refer to our website: http://keccak.noekeon.org/ + * + * Implementation by Ronny Van Keer, + * hereby denoted as "the implementer". + * + * To the extent possible under law, the implementer has waived all copyright + * and related or neighboring rights to the source code in this file. + * http://creativecommons.org/publicdomain/zero/1.0/ + * + * Busybox modifications (C) Lauri Kasanen, under the GPLv2. + */ + +#if CONFIG_SHA3_SMALL < 0 +# define SHA3_SMALL 0 +#elif CONFIG_SHA3_SMALL > 1 +# define SHA3_SMALL 1 +#else +# define SHA3_SMALL CONFIG_SHA3_SMALL +#endif + +enum { + SHA3_IBLK_BYTES = 72, /* 576 bits / 8 */ +}; + +/* + * In the crypto literature this function is usually called Keccak-f(). + */ +static void sha3_process_block72(uint64_t *state) +{ + enum { NROUNDS = 24 }; + + /* Elements should be 64-bit, but top half is always zero or 0x80000000. + * We encode 63rd bits in a separate word below. + * Same is true for 31th bits, which lets us use 16-bit table instead of 64-bit. + * The speed penalty is lost in the noise. + */ + static const uint16_t IOTA_CONST[NROUNDS] = { + 0x0001, + 0x8082, + 0x808a, + 0x8000, + 0x808b, + 0x0001, + 0x8081, + 0x8009, + 0x008a, + 0x0088, + 0x8009, + 0x000a, + 0x808b, + 0x008b, + 0x8089, + 0x8003, + 0x8002, + 0x0080, + 0x800a, + 0x000a, + 0x8081, + 0x8080, + 0x0001, + 0x8008, + }; + /* bit for CONST[0] is in msb: 0011 0011 0000 0111 1101 1101 */ + const uint32_t IOTA_CONST_bit63 = (uint32_t)(0x3307dd00); + /* bit for CONST[0] is in msb: 0001 0110 0011 1000 0001 1011 */ + const uint32_t IOTA_CONST_bit31 = (uint32_t)(0x16381b00); + + static const uint8_t ROT_CONST[24] = { + 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14, + 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44, + }; + static const uint8_t PI_LANE[24] = { + 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4, + 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1, + }; + /*static const uint8_t MOD5[10] = { 0, 1, 2, 3, 4, 0, 1, 2, 3, 4, };*/ + + unsigned x, y; + unsigned round; + + if (BB_BIG_ENDIAN) { + for (x = 0; x < 25; x++) { + state[x] = SWAP_LE64(state[x]); + } + } + + for (round = 0; round < NROUNDS; ++round) { + /* Theta */ + { + uint64_t BC[10]; + for (x = 0; x < 5; ++x) { + BC[x + 5] = BC[x] = state[x] + ^ state[x + 5] ^ state[x + 10] + ^ state[x + 15] ^ state[x + 20]; + } + /* Using 2x5 vector above eliminates the need to use + * BC[MOD5[x+N]] trick below to fetch BC[(x+N) % 5], + * and the code is a bit _smaller_. + */ + for (x = 0; x < 5; ++x) { + uint64_t temp = BC[x + 4] ^ rotl64(BC[x + 1], 1); + state[x] ^= temp; + state[x + 5] ^= temp; + state[x + 10] ^= temp; + state[x + 15] ^= temp; + state[x + 20] ^= temp; + } + } + + /* Rho Pi */ + if (SHA3_SMALL) { + uint64_t t1 = state[1]; + for (x = 0; x < 24; ++x) { + uint64_t t0 = state[PI_LANE[x]]; + state[PI_LANE[x]] = rotl64(t1, ROT_CONST[x]); + t1 = t0; + } + } else { + /* Especially large benefit for 32-bit arch (75% faster): + * 64-bit rotations by non-constant usually are SLOW on those. + * We resort to unrolling here. + * This optimizes out PI_LANE[] and ROT_CONST[], + * but generates 300-500 more bytes of code. + */ + uint64_t t0; + uint64_t t1 = state[1]; +#define RhoPi_twice(x) \ + t0 = state[PI_LANE[x ]]; \ + state[PI_LANE[x ]] = rotl64(t1, ROT_CONST[x ]); \ + t1 = state[PI_LANE[x+1]]; \ + state[PI_LANE[x+1]] = rotl64(t0, ROT_CONST[x+1]); + RhoPi_twice(0); RhoPi_twice(2); + RhoPi_twice(4); RhoPi_twice(6); + RhoPi_twice(8); RhoPi_twice(10); + RhoPi_twice(12); RhoPi_twice(14); + RhoPi_twice(16); RhoPi_twice(18); + RhoPi_twice(20); RhoPi_twice(22); +#undef RhoPi_twice + } + + /* Chi */ + for (y = 0; y <= 20; y += 5) { + uint64_t BC0, BC1, BC2, BC3, BC4; + BC0 = state[y + 0]; + BC1 = state[y + 1]; + BC2 = state[y + 2]; + state[y + 0] = BC0 ^ ((~BC1) & BC2); + BC3 = state[y + 3]; + state[y + 1] = BC1 ^ ((~BC2) & BC3); + BC4 = state[y + 4]; + state[y + 2] = BC2 ^ ((~BC3) & BC4); + state[y + 3] = BC3 ^ ((~BC4) & BC0); + state[y + 4] = BC4 ^ ((~BC0) & BC1); + } + + /* Iota */ + state[0] ^= IOTA_CONST[round] + | (uint32_t)((IOTA_CONST_bit31 << round) & 0x80000000) + | (uint64_t)((IOTA_CONST_bit63 << round) & 0x80000000) << 32; + } + + if (BB_BIG_ENDIAN) { + for (x = 0; x < 25; x++) { + state[x] = SWAP_LE64(state[x]); + } + } +} + +void FAST_FUNC sha3_begin(sha3_ctx_t *ctx) +{ + memset(ctx, 0, sizeof(*ctx)); +} + +void FAST_FUNC sha3_hash(sha3_ctx_t *ctx, const void *buffer, size_t len) +{ +#if SHA3_SMALL + const uint8_t *data = buffer; + unsigned bufpos = ctx->bytes_queued; + + while (1) { + unsigned remaining = SHA3_IBLK_BYTES - bufpos; + if (remaining > len) + remaining = len; + len -= remaining; + /* XOR data into buffer */ + while (remaining != 0) { + uint8_t *buf = (uint8_t*)ctx->state; + buf[bufpos] ^= *data++; + bufpos++; + remaining--; + } + /* Clever way to do "if (bufpos != N) break; ... ; bufpos = 0;" */ + bufpos -= SHA3_IBLK_BYTES; + if (bufpos != 0) + break; + /* Buffer is filled up, process it */ + sha3_process_block72(ctx->state); + /*bufpos = 0; - already is */ + } + ctx->bytes_queued = bufpos + SHA3_IBLK_BYTES; +#else + /* +50 bytes code size, but a bit faster because of long-sized XORs */ + const uint8_t *data = buffer; + unsigned bufpos = ctx->bytes_queued; + + /* If already data in queue, continue queuing first */ + while (len != 0 && bufpos != 0) { + uint8_t *buf = (uint8_t*)ctx->state; + buf[bufpos] ^= *data++; + len--; + bufpos++; + if (bufpos == SHA3_IBLK_BYTES) { + bufpos = 0; + goto do_block; + } + } + + /* Absorb complete blocks */ + while (len >= SHA3_IBLK_BYTES) { + /* XOR data onto beginning of state[]. + * We try to be efficient - operate one word at a time, not byte. + * Careful wrt unaligned access: can't just use "*(long*)data"! + */ + unsigned count = SHA3_IBLK_BYTES / sizeof(long); + long *buf = (long*)ctx->state; + do { + long v; + move_from_unaligned_long(v, (long*)data); + *buf++ ^= v; + data += sizeof(long); + } while (--count); + len -= SHA3_IBLK_BYTES; + do_block: + sha3_process_block72(ctx->state); + } + + /* Queue remaining data bytes */ + while (len != 0) { + uint8_t *buf = (uint8_t*)ctx->state; + buf[bufpos] ^= *data++; + bufpos++; + len--; + } + + ctx->bytes_queued = bufpos; +#endif +} + +void FAST_FUNC sha3_end(sha3_ctx_t *ctx, void *resbuf) +{ + /* Padding */ + uint8_t *buf = (uint8_t*)ctx->state; + buf[ctx->bytes_queued] ^= 1; + buf[SHA3_IBLK_BYTES - 1] ^= 0x80; + + sha3_process_block72(ctx->state); + + /* Output */ + memcpy(resbuf, ctx->state, 64); +} diff --git a/release/src/router/busybox/libbb/inet_common.c b/release/src/router/busybox/libbb/inet_common.c index 7208db9ea9..0f4fca1a27 100644 --- a/release/src/router/busybox/libbb/inet_common.c +++ b/release/src/router/busybox/libbb/inet_common.c @@ -97,7 +97,7 @@ char* FAST_FUNC INET_rresolve(struct sockaddr_in *s_in, int numeric, uint32_t ne if (s_in->sin_family != AF_INET) { #ifdef DEBUG bb_error_msg("rresolve: unsupported address family %d!", - s_in->sin_family); + s_in->sin_family); #endif errno = EAFNOSUPPORT; return NULL; @@ -195,7 +195,7 @@ char* FAST_FUNC INET6_rresolve(struct sockaddr_in6 *sin6, int numeric) if (sin6->sin6_family != AF_INET6) { #ifdef DEBUG bb_error_msg("rresolve: unsupported address family %d!", - sin6->sin6_family); + sin6->sin6_family); #endif errno = EAFNOSUPPORT; return NULL; diff --git a/release/src/router/busybox/libbb/kernel_version.c b/release/src/router/busybox/libbb/kernel_version.c index a168a1e4ef..738ed022b3 100644 --- a/release/src/router/busybox/libbb/kernel_version.c +++ b/release/src/router/busybox/libbb/kernel_version.c @@ -20,18 +20,15 @@ int FAST_FUNC get_linux_version_code(void) { struct utsname name; - char *s; + char *s, *t; int i, r; - if (uname(&name) == -1) { - bb_perror_msg("can't get system information"); - return 0; - } - + uname(&name); /* never fails */ s = name.release; r = 0; for (i = 0; i < 3; i++) { - r = r * 256 + atoi(strtok(s, ".")); + t = strtok(s, "."); + r = r * 256 + (t ? atoi(t) : 0); s = NULL; } return r; diff --git a/release/src/router/busybox/libbb/lineedit.c b/release/src/router/busybox/libbb/lineedit.c index b89748a1c6..dbe616466d 100644 --- a/release/src/router/busybox/libbb/lineedit.c +++ b/release/src/router/busybox/libbb/lineedit.c @@ -2527,9 +2527,9 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman /* Delete word forward */ int nc, sc = cursor; ctrl_right(); - nc = cursor; - input_backward(cursor - sc); - while (--nc >= cursor) + nc = cursor - sc; + input_backward(nc); + while (--nc >= 0) input_delete(1); break; } @@ -2729,7 +2729,8 @@ int FAST_FUNC read_line_input(const char* prompt, char* command, int maxsize) { fputs(prompt, stdout); fflush_all(); - fgets(command, maxsize, stdin); + if (!fgets(command, maxsize, stdin)) + return -1; return strlen(command); } diff --git a/release/src/router/busybox/libbb/loop.c b/release/src/router/busybox/libbb/loop.c index b3a5208481..823fba0795 100644 --- a/release/src/router/busybox/libbb/loop.c +++ b/release/src/router/busybox/libbb/loop.c @@ -150,9 +150,9 @@ int FAST_FUNC set_loop(char **device, const char *file, unsigned long long offse } /* If this block device already set up right, re-use it. - (Yes this is racy, but associating two loop devices with the same - file isn't pretty either. In general, mounting the same file twice - without using losetup manually is problematic.) + * (Yes this is racy, but associating two loop devices with the same + * file isn't pretty either. In general, mounting the same file twice + * without using losetup manually is problematic.) */ } else if (strcmp(file, (char *)loopinfo.lo_file_name) != 0 diff --git a/release/src/router/busybox/libbb/make_directory.c b/release/src/router/busybox/libbb/make_directory.c index 72303e7a30..7826b90f5f 100644 --- a/release/src/router/busybox/libbb/make_directory.c +++ b/release/src/router/busybox/libbb/make_directory.c @@ -107,6 +107,10 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags) * an error. */ if ((mode != -1) && (chmod(path, mode) < 0)) { fail_msg = "set permissions of"; + if (flags & FILEUTILS_IGNORE_CHMOD_ERR) { + flags = 0; + goto print_err; + } break; } goto ret0; @@ -116,8 +120,9 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags) *s = c; } /* while (1) */ - bb_perror_msg("can't %s directory '%s'", fail_msg, path); flags = -1; + print_err: + bb_perror_msg("can't %s directory '%s'", fail_msg, path); goto ret; ret0: flags = 0; diff --git a/release/src/router/busybox/libbb/missing_syscalls.c b/release/src/router/busybox/libbb/missing_syscalls.c new file mode 100644 index 0000000000..dd430e3e25 --- /dev/null +++ b/release/src/router/busybox/libbb/missing_syscalls.c @@ -0,0 +1,42 @@ +/* + * Copyright 2012, Denys Vlasenko + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ + +//kbuild:lib-y += missing_syscalls.o + +/*#include - for struct timex, but may collide with */ +#include +#include "libbb.h" + +#if defined(ANDROID) || defined(__ANDROID__) +pid_t getsid(pid_t pid) +{ + return syscall(__NR_getsid, pid); +} + +int stime(const time_t *t) +{ + struct timeval tv; + tv.tv_sec = *t; + tv.tv_usec = 0; + return settimeofday(&tv, NULL); +} + +int sethostname(const char *name, size_t len) +{ + return syscall(__NR_sethostname, name, len); +} + +struct timex; +int adjtimex(struct timex *buf) +{ + return syscall(__NR_adjtimex, buf); +} + +int pivot_root(const char *new_root, const char *put_old) +{ + return syscall(__NR_pivot_root, new_root, put_old); +} +#endif diff --git a/release/src/router/busybox/libbb/procps.c b/release/src/router/busybox/libbb/procps.c index 40587db82b..5b68d34313 100644 --- a/release/src/router/busybox/libbb/procps.c +++ b/release/src/router/busybox/libbb/procps.c @@ -180,7 +180,7 @@ static char *skip_fields(char *str, int count) #if ENABLE_FEATURE_TOPMEM || ENABLE_PMAP int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total, - void (*cb)(struct smaprec *, void *), void *data) + void (*cb)(struct smaprec *, void *), void *data) { FILE *file; struct smaprec currec; @@ -425,7 +425,7 @@ procps_status_t* FAST_FUNC procps_scan(procps_status_t* sp, int flags) if (n < 11) continue; /* bogus data, get next /proc/XXX */ # if ENABLE_FEATURE_TOP_SMP_PROCESS - if (n < 11+15) + if (n == 11) sp->last_seen_on_cpu = 0; # endif @@ -583,6 +583,8 @@ void FAST_FUNC read_cmdline(char *buf, int col, unsigned pid, const char *comm) buf[sz] = '\0'; while (--sz >= 0 && buf[sz] == '\0') continue; + /* Prevent basename("process foo/bar") = "bar" */ + strchrnul(buf, ' ')[0] = '\0'; base = bb_basename(buf); /* before we replace argv0's NUL with space */ while (sz >= 0) { if ((unsigned char)(buf[sz]) < ' ') diff --git a/release/src/router/busybox/libbb/read_key.c b/release/src/router/busybox/libbb/read_key.c index 8d72d2a63c..ace23defb8 100644 --- a/release/src/router/busybox/libbb/read_key.c +++ b/release/src/router/busybox/libbb/read_key.c @@ -15,7 +15,10 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout) const char *seq; int n; - /* Known escape sequences for cursor and function keys */ + /* Known escape sequences for cursor and function keys. + * See "Xterm Control Sequences" + * http://invisible-island.net/xterm/ctlseqs/ctlseqs.html + */ static const char esccmds[] ALIGN1 = { 'O','A' |0x80,KEYCODE_UP , 'O','B' |0x80,KEYCODE_DOWN , @@ -44,6 +47,8 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout) /* ESC [ 1 ; 4 x, where x = A/B/C/D: Alt-Shift- */ /* ESC [ 1 ; 5 x, where x = A/B/C/D: Ctrl- - implemented below */ /* ESC [ 1 ; 6 x, where x = A/B/C/D: Ctrl-Shift- */ + /* ESC [ 1 ; 7 x, where x = A/B/C/D: Ctrl-Alt- */ + /* ESC [ 1 ; 8 x, where x = A/B/C/D: Ctrl-Alt-Shift- */ '[','H' |0x80,KEYCODE_HOME , /* xterm */ '[','F' |0x80,KEYCODE_END , /* xterm */ /* [ESC] ESC [ [2] H - [Alt-][Shift-]Home (End similarly?) */ @@ -64,10 +69,10 @@ int64_t FAST_FUNC read_key(int fd, char *buffer, int timeout) '[','7','~' |0x80,KEYCODE_HOME , /* vt100? linux vt? or what? */ '[','8','~' |0x80,KEYCODE_END , /* vt100? linux vt? or what? */ #if 0 - '[','1','1','~'|0x80,KEYCODE_FUN1 , - '[','1','2','~'|0x80,KEYCODE_FUN2 , - '[','1','3','~'|0x80,KEYCODE_FUN3 , - '[','1','4','~'|0x80,KEYCODE_FUN4 , + '[','1','1','~'|0x80,KEYCODE_FUN1 , /* old xterm, deprecated by ESC O P */ + '[','1','2','~'|0x80,KEYCODE_FUN2 , /* old xterm... */ + '[','1','3','~'|0x80,KEYCODE_FUN3 , /* old xterm... */ + '[','1','4','~'|0x80,KEYCODE_FUN4 , /* old xterm... */ '[','1','5','~'|0x80,KEYCODE_FUN5 , /* [ESC] ESC [ 1 5 [;2] ~ - [Alt-][Shift-]F5 */ '[','1','7','~'|0x80,KEYCODE_FUN6 , diff --git a/release/src/router/busybox/libbb/remove_file.c b/release/src/router/busybox/libbb/remove_file.c index c6531a0b99..5b75f7f30e 100644 --- a/release/src/router/busybox/libbb/remove_file.c +++ b/release/src/router/busybox/libbb/remove_file.c @@ -33,7 +33,7 @@ int FAST_FUNC remove_file(const char *path, int flags) int status = 0; if (!(flags & FILEUTILS_RECUR)) { - bb_error_msg("%s: is a directory", path); + bb_error_msg("'%s' is a directory", path); return -1; } diff --git a/release/src/router/busybox/libbb/safe_gethostname.c b/release/src/router/busybox/libbb/safe_gethostname.c index bdb9896311..cac99ae039 100644 --- a/release/src/router/busybox/libbb/safe_gethostname.c +++ b/release/src/router/busybox/libbb/safe_gethostname.c @@ -50,25 +50,3 @@ char* FAST_FUNC safe_gethostname(void) uname(&uts); return xstrndup(!uts.nodename[0] ? "?" : uts.nodename, sizeof(uts.nodename)); } - -/* - * On success return the current malloced and NUL terminated domainname. - * On error return malloced and NUL terminated string "?". - * This is an illegal first character for a domainname. - * The returned malloced string must be freed by the caller. - */ -char* FAST_FUNC safe_getdomainname(void) -{ -#if defined(__linux__) -/* The field domainname of struct utsname is Linux specific. */ - struct utsname uts; - uname(&uts); - return xstrndup(!uts.domainname[0] ? "?" : uts.domainname, sizeof(uts.domainname)); -#else - /* We really don't care about people with domain names wider than most screens */ - char buf[256]; - int r = getdomainname(buf, sizeof(buf)); - buf[sizeof(buf)-1] = '\0'; - return xstrdup(r < 0 ? "?" : buf); -#endif -} diff --git a/release/src/router/busybox/libbb/selinux_common.c b/release/src/router/busybox/libbb/selinux_common.c index 62910e2856..c2585557f2 100644 --- a/release/src/router/busybox/libbb/selinux_common.c +++ b/release/src/router/busybox/libbb/selinux_common.c @@ -10,7 +10,7 @@ #include context_t FAST_FUNC set_security_context_component(security_context_t cur_context, - char *user, char *role, char *type, char *range) + char *user, char *role, char *type, char *range) { context_t con = context_new(cur_context); if (!con) diff --git a/release/src/router/busybox/libbb/setup_environment.c b/release/src/router/busybox/libbb/setup_environment.c index 73229ca6ce..4258656fea 100644 --- a/release/src/router/busybox/libbb/setup_environment.c +++ b/release/src/router/busybox/libbb/setup_environment.c @@ -37,9 +37,11 @@ void FAST_FUNC setup_environment(const char *shell, int flags, const struct pass /* Change the current working directory to be the home directory * of the user */ - if (chdir(pw->pw_dir)) { - xchdir((flags & SETUP_ENV_TO_TMP) ? "/tmp" : "/"); - bb_error_msg("can't chdir to home directory '%s'", pw->pw_dir); + if (!(flags & SETUP_ENV_NO_CHDIR)) { + if (chdir(pw->pw_dir) != 0) { + bb_error_msg("can't change directory to '%s'", pw->pw_dir); + xchdir((flags & SETUP_ENV_TO_TMP) ? "/tmp" : "/"); + } } if (flags & SETUP_ENV_CLEARENV) { diff --git a/release/src/router/busybox/libbb/signals.c b/release/src/router/busybox/libbb/signals.c index cdc37b1ef2..56512473a2 100644 --- a/release/src/router/busybox/libbb/signals.c +++ b/release/src/router/busybox/libbb/signals.c @@ -39,7 +39,7 @@ void FAST_FUNC bb_signals(int sigs, void (*f)(int)) while (sigs) { if (sigs & bit) { - sigs &= ~bit; + sigs -= bit; signal(sig_no, f); } sig_no++; @@ -60,7 +60,7 @@ void FAST_FUNC bb_signals_recursive_norestart(int sigs, void (*f)(int)) while (sigs) { if (sigs & bit) { - sigs &= ~bit; + sigs -= bit; sigaction_set(sig_no, &sa); } sig_no++; @@ -97,7 +97,7 @@ void FAST_FUNC kill_myself_with_sig(int sig) signal(sig, SIG_DFL); sig_unblock(sig); raise(sig); - _exit(EXIT_FAILURE); /* Should not reach it */ + _exit(sig | 128); /* Should not reach it */ } void FAST_FUNC signal_SA_RESTART_empty_mask(int sig, void (*handler)(int)) diff --git a/release/src/router/busybox/libbb/udp_io.c b/release/src/router/busybox/libbb/udp_io.c index ef7ff1de60..c2bdb7ced9 100644 --- a/release/src/router/busybox/libbb/udp_io.c +++ b/release/src/router/busybox/libbb/udp_io.c @@ -18,8 +18,13 @@ socket_want_pktinfo(int fd UNUSED_PARAM) #ifdef IP_PKTINFO setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &const_int_1, sizeof(int)); #endif -#if ENABLE_FEATURE_IPV6 && defined(IPV6_PKTINFO) +#if ENABLE_FEATURE_IPV6 +# ifdef IPV6_RECVPKTINFO + setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &const_int_1, sizeof(int)); + setsockopt(fd, IPPROTO_IPV6, IPV6_2292PKTINFO, &const_int_1, sizeof(int)); +# elif defined(IPV6_PKTINFO) setsockopt(fd, IPPROTO_IPV6, IPV6_PKTINFO, &const_int_1, sizeof(int)); +# endif #endif } diff --git a/release/src/router/busybox/libbb/xatonum_template.c b/release/src/router/busybox/libbb/xatonum_template.c index 029f66202e..e0471983c9 100644 --- a/release/src/router/busybox/libbb/xatonum_template.c +++ b/release/src/router/busybox/libbb/xatonum_template.c @@ -59,7 +59,7 @@ unsigned type FAST_FUNC xstrtou(_range_sfx)(const char *numstr, int base, } /* Note: trailing space is an error. - It would be easy enough to allow though if desired. */ + * It would be easy enough to allow though if desired. */ if (*e) goto inval; chk_range: diff --git a/release/src/router/busybox/libbb/xfuncs_printf.c b/release/src/router/busybox/libbb/xfuncs_printf.c index d8a42ba0bc..05aa07ce80 100644 --- a/release/src/router/busybox/libbb/xfuncs_printf.c +++ b/release/src/router/busybox/libbb/xfuncs_printf.c @@ -355,13 +355,13 @@ void FAST_FUNC xsetuid(uid_t uid) void FAST_FUNC xchdir(const char *path) { if (chdir(path)) - bb_perror_msg_and_die("chdir(%s)", path); + bb_perror_msg_and_die("can't change directory to '%s'", path); } void FAST_FUNC xchroot(const char *path) { if (chroot(path)) - bb_perror_msg_and_die("can't change root directory to %s", path); + bb_perror_msg_and_die("can't change root directory to '%s'", path); xchdir("/"); } diff --git a/release/src/router/busybox/libpwdgrp/pwd_grp.c b/release/src/router/busybox/libpwdgrp/pwd_grp.c index edf53f350b..2060d78116 100644 --- a/release/src/router/busybox/libpwdgrp/pwd_grp.c +++ b/release/src/router/busybox/libpwdgrp/pwd_grp.c @@ -300,8 +300,8 @@ struct group *getgrgid(gid_t gid) * to have been created as a reentrant version of the non-standard * functions getspuid. Why getspuid was added, I do not know. */ int getspuid_r(uid_t uid, struct spwd *__restrict resultbuf, - char *__restrict buffer, size_t buflen, - struct spwd **__restrict result) + char *__restrict buffer, size_t buflen, + struct spwd **__restrict result) { int rv; struct passwd *pp; @@ -403,8 +403,8 @@ void endpwent(void) int getpwent_r(struct passwd *__restrict resultbuf, - char *__restrict buffer, size_t buflen, - struct passwd **__restrict result) + char *__restrict buffer, size_t buflen, + struct passwd **__restrict result) { int rv; @@ -451,8 +451,8 @@ void endgrent(void) } int getgrent_r(struct group *__restrict resultbuf, - char *__restrict buffer, size_t buflen, - struct group **__restrict result) + char *__restrict buffer, size_t buflen, + struct group **__restrict result) { int rv; @@ -501,7 +501,7 @@ void endspent(void) } int getspent_r(struct spwd *resultbuf, char *buffer, - size_t buflen, struct spwd **result) + size_t buflen, struct spwd **result) { int rv; diff --git a/release/src/router/busybox/loginutils/add-remove-shell.c b/release/src/router/busybox/loginutils/add-remove-shell.c index 9a1454430b..e492b6e5a8 100644 --- a/release/src/router/busybox/loginutils/add-remove-shell.c +++ b/release/src/router/busybox/loginutils/add-remove-shell.c @@ -8,8 +8,8 @@ * for details. */ -//applet:IF_ADD_SHELL( APPLET_ODDNAME(add-shell , add_remove_shell, BB_DIR_USR_BIN, BB_SUID_DROP, add_shell )) -//applet:IF_REMOVE_SHELL(APPLET_ODDNAME(remove-shell, add_remove_shell, BB_DIR_USR_BIN, BB_SUID_DROP, remove_shell)) +//applet:IF_ADD_SHELL( APPLET_ODDNAME(add-shell , add_remove_shell, BB_DIR_USR_SBIN, BB_SUID_DROP, add_shell )) +//applet:IF_REMOVE_SHELL(APPLET_ODDNAME(remove-shell, add_remove_shell, BB_DIR_USR_SBIN, BB_SUID_DROP, remove_shell)) //kbuild:lib-$(CONFIG_ADD_SHELL) += add-remove-shell.o //kbuild:lib-$(CONFIG_REMOVE_SHELL) += add-remove-shell.o diff --git a/release/src/router/busybox/loginutils/adduser.c b/release/src/router/busybox/loginutils/adduser.c index 1d082c8767..dc02444766 100644 --- a/release/src/router/busybox/loginutils/adduser.c +++ b/release/src/router/busybox/loginutils/adduser.c @@ -9,9 +9,9 @@ */ //usage:#define adduser_trivial_usage -//usage: "[OPTIONS] USER" +//usage: "[OPTIONS] USER [GROUP]" //usage:#define adduser_full_usage "\n\n" -//usage: "Add a user\n" +//usage: "Create new user, or add USER to GROUP\n" //usage: "\n -h DIR Home directory" //usage: "\n -g GECOS GECOS field" //usage: "\n -s SHELL Login shell" @@ -80,7 +80,7 @@ static void passwd_study(struct passwd *p) } } -static void addgroup_wrapper(struct passwd *p, const char *group_name) +static int addgroup_wrapper(struct passwd *p, const char *group_name) { char *argv[6]; @@ -110,7 +110,7 @@ static void addgroup_wrapper(struct passwd *p, const char *group_name) argv[5] = NULL; } - spawn_and_wait(argv); + return spawn_and_wait(argv); } static void passwd_wrapper(const char *login_name) NORETURN; @@ -162,9 +162,9 @@ int adduser_main(int argc UNUSED_PARAM, char **argv) pw.pw_shell = (char *)get_shell_name(); pw.pw_dir = NULL; - /* exactly one non-option arg */ + /* at most two non-option args */ /* disable interactive passwd for system accounts */ - opt_complementary = "=1:SD:u+"; + opt_complementary = "?2:SD:u+"; if (sizeof(pw.pw_uid) == sizeof(int)) { opts = getopt32(argv, "h:g:s:G:DSHu:", &pw.pw_dir, &pw.pw_gecos, &pw.pw_shell, &usegroup, &pw.pw_uid); } else { @@ -175,9 +175,16 @@ int adduser_main(int argc UNUSED_PARAM, char **argv) } } argv += optind; + pw.pw_name = argv[0]; + + if (!opts && argv[1]) { + /* if called with two non-option arguments, adduser + * will add an existing user to an existing group. + */ + return addgroup_wrapper(&pw, argv[1]); + } /* fill in the passwd struct */ - pw.pw_name = argv[0]; die_if_bad_username(pw.pw_name); if (!pw.pw_dir) { /* create string for $HOME if not specified already */ @@ -205,7 +212,6 @@ int adduser_main(int argc UNUSED_PARAM, char **argv) } if (ENABLE_FEATURE_CLEAN_UP) free(p); - #if ENABLE_FEATURE_SHADOWPASSWDS /* /etc/shadow fields: * 1. username diff --git a/release/src/router/busybox/loginutils/getty.c b/release/src/router/busybox/loginutils/getty.c index bbb5a96b42..e5d13bed6b 100644 --- a/release/src/router/busybox/loginutils/getty.c +++ b/release/src/router/busybox/loginutils/getty.c @@ -548,8 +548,15 @@ int getty_main(int argc UNUSED_PARAM, char **argv) * a session leader - which is quite possible for getty! */ pid = getpid(); - if (getsid(0) != pid) + if (getsid(0) != pid) { + //for debugging: + //bb_perror_msg_and_die("setsid failed:" + // " pid %d ppid %d" + // " sid %d pgid %d", + // pid, getppid(), + // getsid(0), getpgid(0)); bb_perror_msg_and_die("setsid"); + } /* Looks like we are already a session leader. * In this case (setsid failed) we may still have ctty, * and it may be different from tty we need to control! diff --git a/release/src/router/busybox/loginutils/login.c b/release/src/router/busybox/loginutils/login.c index bf43f3aba7..6ec8dc42e1 100644 --- a/release/src/router/busybox/loginutils/login.c +++ b/release/src/router/busybox/loginutils/login.c @@ -37,7 +37,8 @@ static const struct pam_conv conv = { enum { TIMEOUT = 60, EMPTY_USERNAME_COUNT = 10, - USERNAME_SIZE = 32, + /* Some users found 32 chars limit to be too low: */ + USERNAME_SIZE = 64, TTYNAME_SIZE = 32, }; diff --git a/release/src/router/busybox/loginutils/passwd.c b/release/src/router/busybox/loginutils/passwd.c index b83db00836..a7006f0548 100644 --- a/release/src/router/busybox/loginutils/passwd.c +++ b/release/src/router/busybox/loginutils/passwd.c @@ -15,6 +15,7 @@ #include "libbb.h" #include +#include /* setrlimit */ static void nuke_str(char *str) { diff --git a/release/src/router/busybox/loginutils/su.c b/release/src/router/busybox/loginutils/su.c index 57ea738f4c..2ec05e1255 100644 --- a/release/src/router/busybox/loginutils/su.c +++ b/release/src/router/busybox/loginutils/su.c @@ -131,7 +131,8 @@ int su_main(int argc UNUSED_PARAM, char **argv) change_identity(pw); setup_environment(opt_shell, ((flags & SU_OPT_l) / SU_OPT_l * SETUP_ENV_CLEARENV) - + (!(flags & SU_OPT_mp) * SETUP_ENV_CHANGEENV), + + (!(flags & SU_OPT_mp) * SETUP_ENV_CHANGEENV) + + (!(flags & SU_OPT_l) * SETUP_ENV_NO_CHDIR), pw); IF_SELINUX(set_current_security_context(NULL);) diff --git a/release/src/router/busybox/mailutils/sendmail.c b/release/src/router/busybox/mailutils/sendmail.c index aa381c60fe..c426e9d851 100644 --- a/release/src/router/busybox/mailutils/sendmail.c +++ b/release/src/router/busybox/mailutils/sendmail.c @@ -118,7 +118,7 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) char *opt_from; char *s; llist_t *list = NULL; - char *domain = sane_address(safe_getdomainname()); + char *host = sane_address(safe_gethostname()); unsigned nheaders = 0; int code; @@ -222,8 +222,9 @@ int sendmail_main(int argc UNUSED_PARAM, char **argv) } // we should start with modern EHLO - if (250 != smtp_checkp("EHLO %s", domain, -1)) - smtp_checkp("HELO %s", domain, 250); + if (250 != smtp_checkp("EHLO %s", host, -1)) + smtp_checkp("HELO %s", host, 250); + free(host); // perform authentication if (opts & OPT_a) { diff --git a/release/src/router/busybox/miscutils/crond.c b/release/src/router/busybox/miscutils/crond.c index a0b73c7749..582dc991a3 100644 --- a/release/src/router/busybox/miscutils/crond.c +++ b/release/src/router/busybox/miscutils/crond.c @@ -885,7 +885,7 @@ int crond_main(int argc UNUSED_PARAM, char **argv) xsetenv("SHELL", DEFAULT_SHELL); /* once, for all future children */ crondlog(LVL8 "crond (busybox "BB_VER") started, log level %d", G.log_level); rescan_crontab_dir(); - write_pidfile("/var/run/crond.pid"); + write_pidfile(CONFIG_PID_FILE_PATH "/crond.pid"); /* Main loop */ t2 = time(NULL); diff --git a/release/src/router/busybox/miscutils/dc.c b/release/src/router/busybox/miscutils/dc.c index 6903761e4f..6bcfbe2493 100644 --- a/release/src/router/busybox/miscutils/dc.c +++ b/release/src/router/busybox/miscutils/dc.c @@ -11,11 +11,11 @@ //usage: //usage:#define dc_full_usage "\n\n" //usage: "Tiny RPN calculator. Operations:\n" -//usage: "+, add, -, sub, *, mul, /, div, %, mod, "IF_FEATURE_DC_LIBM("**, exp, ")"and, or, not, eor,\n" +//usage: "+, add, -, sub, *, mul, /, div, %, mod, "IF_FEATURE_DC_LIBM("**, exp, ")"and, or, not, xor,\n" //usage: "p - print top of the stack (without popping),\n" //usage: "f - print entire stack,\n" //usage: "o - pop the value and set output radix (must be 10, 16, 8 or 2).\n" -//usage: "Examples: 'dc 2 2 add p' -> 4, 'dc 8 8 * 2 2 + / p' -> 16" +//usage: "Examples: 'dc 2 2 add p' -> 4, 'dc 8 8 mul 2 2 + / p' -> 16" //usage: //usage:#define dc_example_usage //usage: "$ dc 2 2 + p\n" @@ -219,29 +219,29 @@ static const struct op operators[] = { {"p", print_no_pop}, {"f", print_stack_no_pop}, {"o", set_output_base}, - { "", NULL } }; static void stack_machine(const char *argument) { - char *endPointer; + char *end; double d; - const struct op *o = operators; + const struct op *o; - d = strtod(argument, &endPointer); - - if (endPointer != argument && *endPointer == '\0') { + d = strtod(argument, &end); + if (end != argument && *end == '\0') { push(d); return; } - while (o->function) { + o = operators; + do { if (strcmp(o->name, argument) == 0) { o->function(); return; } o++; - } + } while (o != operators + ARRAY_SIZE(operators)); + bb_error_msg_and_die("syntax error at '%s'", argument); } diff --git a/release/src/router/busybox/miscutils/devfsd.c b/release/src/router/busybox/miscutils/devfsd.c index 6493fe4f1c..24c953bacd 100644 --- a/release/src/router/busybox/miscutils/devfsd.c +++ b/release/src/router/busybox/miscutils/devfsd.c @@ -219,7 +219,7 @@ static void action_execute(const struct devfsd_notify_struct *, const struct con const regmatch_t *, unsigned); static void action_modload(const struct devfsd_notify_struct *info, const struct config_entry_struct *entry); static void action_copy(const struct devfsd_notify_struct *, const struct config_entry_struct *, - const regmatch_t *, unsigned); + const regmatch_t *, unsigned); static void action_compat(const struct devfsd_notify_struct *, unsigned); static void free_config(void); static void restore(char *spath, struct stat source_stat, int rootlen); @@ -229,12 +229,12 @@ static void signal_handler(int); static const char *get_variable(const char *, void *); static int make_dir_tree(const char *); static int expand_expression(char *, unsigned, const char *, const char *(*)(const char *, void *), void *, - const char *, const regmatch_t *, unsigned); + const char *, const regmatch_t *, unsigned); static void expand_regexp(char *, size_t, const char *, const char *, const regmatch_t *, unsigned); static const char *expand_variable( char *, unsigned, unsigned *, const char *, const char *(*)(const char *, void *), void *); static const char *get_variable_v2(const char *, const char *(*)(const char *, void *), void *); -static char get_old_ide_name(unsigned , unsigned); +static char get_old_ide_name(unsigned, unsigned); static char *write_old_sd_name(char *, unsigned, unsigned, const char *); /* busybox functions */ @@ -580,9 +580,9 @@ static void process_config_line(const char *line, unsigned long *event_mask) /*This action will pass "/dev/$devname"(i.e. "/dev/" prefixed to the device name) to the module loading facility. In addition, the /etc/modules.devfs configuration file is used.*/ - if (ENABLE_DEVFSD_MODLOAD) + if (ENABLE_DEVFSD_MODLOAD) new->action.what = AC_MODLOAD; - break; + break; case 6: /* EXECUTE */ new->action.what = AC_EXECUTE; num_args -= 3; @@ -750,7 +750,7 @@ static void action_permissions(const struct devfsd_notify_struct *info, } /* End Function action_permissions */ static void action_modload(const struct devfsd_notify_struct *info, - const struct config_entry_struct *entry UNUSED_PARAM) + const struct config_entry_struct *entry UNUSED_PARAM) /* [SUMMARY] Load a module. The devfs change. The config file entry. @@ -771,8 +771,8 @@ static void action_modload(const struct devfsd_notify_struct *info, } /* End Function action_modload */ static void action_execute(const struct devfsd_notify_struct *info, - const struct config_entry_struct *entry, - const regmatch_t *regexpr, unsigned int numexpr) + const struct config_entry_struct *entry, + const regmatch_t *regexpr, unsigned int numexpr) /* [SUMMARY] Execute a programme. The devfs change. The config file entry. @@ -803,8 +803,8 @@ static void action_execute(const struct devfsd_notify_struct *info, static void action_copy(const struct devfsd_notify_struct *info, - const struct config_entry_struct *entry, - const regmatch_t *regexpr, unsigned int numexpr) + const struct config_entry_struct *entry, + const regmatch_t *regexpr, unsigned int numexpr) /* [SUMMARY] Copy permissions. The devfs change. The config file entry. @@ -1259,11 +1259,11 @@ static int make_dir_tree(const char *path) } /* End Function make_dir_tree */ static int expand_expression(char *output, unsigned int outsize, - const char *input, - const char *(*get_variable_func)(const char *variable, void *info), - void *info, - const char *devname, - const regmatch_t *ex, unsigned int numexp) + const char *input, + const char *(*get_variable_func)(const char *variable, void *info), + void *info, + const char *devname, + const regmatch_t *ex, unsigned int numexp) /* [SUMMARY] Expand environment variables and regular subexpressions in string. The output expanded expression is written here. The size of the output buffer. @@ -1288,8 +1288,8 @@ static int expand_expression(char *output, unsigned int outsize, } /* End Function expand_expression */ static void expand_regexp(char *output, size_t outsize, const char *input, - const char *devname, - const regmatch_t *ex, unsigned int numex) + const char *devname, + const regmatch_t *ex, unsigned int numex) /* [SUMMARY] Expand all occurrences of the regular subexpressions \0 to \9. The output expanded expression is written here. The size of the output buffer. @@ -1385,7 +1385,7 @@ static struct translate_struct translate_table[] = }; const char *get_old_name(const char *devname, unsigned int namelen, - char *buffer, unsigned int major, unsigned int minor) + char *buffer, unsigned int major, unsigned int minor) /* [SUMMARY] Translate a kernel-supplied name into an old name. The device name provided by the kernel. The length of the name. @@ -1423,7 +1423,7 @@ const char *get_old_name(const char *devname, unsigned int namelen, }; for (trans = translate_table; trans->match != NULL; ++trans) { - len = strlen(trans->match); + len = strlen(trans->match); if (strncmp(devname, trans->match, len) == 0) { if (trans->format == NULL) @@ -1549,9 +1549,9 @@ static char *write_old_sd_name(char *buffer, /*EXPERIMENTAL_FUNCTION*/ int st_expr_expand(char *output, unsigned int length, const char *input, - const char *(*get_variable_func)(const char *variable, - void *info), - void *info) + const char *(*get_variable_func)(const char *variable, + void *info), + void *info) /* [SUMMARY] Expand an expression using Borne Shell-like unquoted rules. The output expanded expression is written here. The size of the output buffer. @@ -1641,10 +1641,10 @@ st_expr_expand_out: /* Private functions follow */ static const char *expand_variable(char *buffer, unsigned int length, - unsigned int *out_pos, const char *input, - const char *(*func)(const char *variable, - void *info), - void *info) + unsigned int *out_pos, const char *input, + const char *(*func)(const char *variable, + void *info), + void *info) /* [SUMMARY] Expand a variable. The buffer to write to. The length of the output buffer. @@ -1786,8 +1786,8 @@ expand_variable_out: static const char *get_variable_v2(const char *variable, - const char *(*func)(const char *variable, void *info), - void *info) + const char *(*func)(const char *variable, void *info), + void *info) /* [SUMMARY] Get a variable from the environment or . The variable name. A function which will be used to get the variable. If this returns diff --git a/release/src/router/busybox/miscutils/fbsplash.c b/release/src/router/busybox/miscutils/fbsplash.c index 988439b25a..12a77b70f0 100644 --- a/release/src/router/busybox/miscutils/fbsplash.c +++ b/release/src/router/busybox/miscutils/fbsplash.c @@ -50,6 +50,10 @@ struct globals { struct fb_var_screeninfo scr_var; struct fb_fix_screeninfo scr_fix; unsigned bytes_per_pixel; + // cached (8 - scr_var.COLOR.length): + unsigned red_shift; + unsigned green_shift; + unsigned blue_shift; }; #define G (*ptr_to_globals) #define INIT_G() do { \ @@ -139,11 +143,14 @@ static void fb_open(const char *strfb_device) break; } + G.red_shift = 8 - G.scr_var.red.length; + G.green_shift = 8 - G.scr_var.green.length; + G.blue_shift = 8 - G.scr_var.blue.length; G.bytes_per_pixel = (G.scr_var.bits_per_pixel + 7) >> 3; // map the device in memory G.addr = mmap(NULL, - G.scr_var.yres * G.scr_fix.line_length, + G.scr_var.yres * G.scr_fix.line_length, PROT_WRITE, MAP_SHARED, fbfd, 0); if (G.addr == MAP_FAILED) bb_perror_msg_and_die("mmap"); @@ -155,10 +162,13 @@ static void fb_open(const char *strfb_device) /** - * Return pixel value of the passed RGB color + * Return pixel value of the passed RGB color. + * This is performance critical fn. */ static unsigned fb_pixel_value(unsigned r, unsigned g, unsigned b) { + /* We assume that the r,g,b values are <= 255 */ + if (G.bytes_per_pixel == 1) { r = r & 0xe0; // 3-bit red g = (g >> 3) & 0x1c; // 3-bit green @@ -166,10 +176,17 @@ static unsigned fb_pixel_value(unsigned r, unsigned g, unsigned b) return r + g + b; } if (G.bytes_per_pixel == 2) { - r = (r & 0xf8) << 8; // 5-bit red - g = (g & 0xfc) << 3; // 6-bit green - b = b >> 3; // 5-bit blue - return r + g + b; + // ARM PL110 on Integrator/CP has RGBA5551 bit arrangement. + // We want to support bit locations like that. + // + // First shift out unused bits + r = r >> G.red_shift; + g = g >> G.green_shift; + b = b >> G.blue_shift; + // Then shift the remaining bits to their offset + return (r << G.scr_var.red.offset) + + (g << G.scr_var.green.offset) + + (b << G.scr_var.blue.offset); } // RGB 888 return b + (g << 8) + (r << 16); @@ -295,8 +312,7 @@ static void fb_drawprogressbar(unsigned percent) pos_x = left_x; if (percent > 0) { - int y; - unsigned i; + int i, y; // actual progress bar pos_x += (unsigned)(width * percent) / 100; @@ -308,7 +324,7 @@ static void fb_drawprogressbar(unsigned percent) while (i >= 0) { // draw one-line thick "rectangle" // top line will have gray lvl 200, bottom one 100 - unsigned gray_level = 100 + i*100 / height; + unsigned gray_level = 100 + (unsigned)i*100 / height; fb_drawfullrectangle( left_x, y, pos_x, y, gray_level, gray_level, gray_level); diff --git a/release/src/router/busybox/miscutils/flashcp.c b/release/src/router/busybox/miscutils/flashcp.c index 790f9c01f8..81cde9072d 100644 --- a/release/src/router/busybox/miscutils/flashcp.c +++ b/release/src/router/busybox/miscutils/flashcp.c @@ -50,7 +50,6 @@ int flashcp_main(int argc UNUSED_PARAM, char **argv) int fd_f, fd_d; /* input file and mtd device file descriptors */ int i; uoff_t erase_count; - unsigned opts; struct mtd_info_user mtd; struct erase_info_user e; struct stat statb; @@ -59,7 +58,7 @@ int flashcp_main(int argc UNUSED_PARAM, char **argv) RESERVE_CONFIG_UBUFFER(buf2, BUFSIZE); opt_complementary = "=2"; /* exactly 2 non-option args: file, dev */ - opts = getopt32(argv, "v"); + /*opts =*/ getopt32(argv, "v"); argv += optind; // filename = *argv++; // devicename = *argv; diff --git a/release/src/router/busybox/miscutils/hdparm.c b/release/src/router/busybox/miscutils/hdparm.c index a97f3e7b59..69726ae729 100644 --- a/release/src/router/busybox/miscutils/hdparm.c +++ b/release/src/router/busybox/miscutils/hdparm.c @@ -1022,8 +1022,8 @@ static void identify(uint16_t *val) } if ((like_std > 3) && (val[CMDS_SUPP_1] & 0x0008)) { /* We print out elsewhere whether the APM feature is enabled or - not. If it's not enabled, let's not repeat the info; just print - nothing here. */ + * not. If it's not enabled, let's not repeat the info; just print + * nothing here. */ printf("\tAdvancedPM level: "); if ((val[ADV_PWR] & 0xFF00) == 0x4000) { uint8_t apm_level = val[ADV_PWR] & 0x00FF; @@ -1038,7 +1038,7 @@ static void identify(uint16_t *val) val[ACOUSTIC] & 0x00ff); } } else { - /* ATAPI */ + /* ATAPI */ if (eqpt != CDROM && (val[CAPAB_0] & SWRST_REQ)) printf("\tATA sw reset required\n"); diff --git a/release/src/router/busybox/miscutils/last.c b/release/src/router/busybox/miscutils/last.c index d527803743..24f6e1c782 100644 --- a/release/src/router/busybox/miscutils/last.c +++ b/release/src/router/busybox/miscutils/last.c @@ -71,7 +71,7 @@ int last_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) file = xopen(bb_path_wtmp_file, O_RDONLY); printf("%-10s %-14s %-18s %-12.12s %s\n", - "USER", "TTY", "HOST", "LOGIN", "TIME"); + "USER", "TTY", "HOST", "LOGIN", "TIME"); /* yikes. We reverse over the file and that is a not too elegant way */ pos = xlseek(file, 0, SEEK_END); pos = lseek(file, pos - sizeof(ut), SEEK_SET); @@ -131,7 +131,7 @@ int last_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) * but some systems have it wrong */ t_tmp = (time_t)ut.ut_tv.tv_sec; printf("%-10s %-14s %-18s %-12.12s\n", - ut.ut_user, ut.ut_line, ut.ut_host, ctime(&t_tmp) + 4); + ut.ut_user, ut.ut_line, ut.ut_host, ctime(&t_tmp) + 4); next: pos -= sizeof(ut); if (pos <= 0) diff --git a/release/src/router/busybox/miscutils/last_fancy.c b/release/src/router/busybox/miscutils/last_fancy.c index dc09b65fb6..f687d7e16c 100644 --- a/release/src/router/busybox/miscutils/last_fancy.c +++ b/release/src/router/busybox/miscutils/last_fancy.c @@ -93,14 +93,14 @@ static void show_entry(struct utmp *ut, int state, time_t dur_secs) } printf(HEADER_FORMAT, - ut->ut_user, - ut->ut_line, - show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN, - show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN, - ut->ut_host, - login_time, - logout_str, - duration_str); + ut->ut_user, + ut->ut_line, + show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN, + show_wide ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN, + ut->ut_host, + login_time, + logout_str, + duration_str); } static int get_ut_type(struct utmp *ut) diff --git a/release/src/router/busybox/miscutils/less.c b/release/src/router/busybox/miscutils/less.c index f0187bf8ae..5ce0a12030 100644 --- a/release/src/router/busybox/miscutils/less.c +++ b/release/src/router/busybox/miscutils/less.c @@ -709,9 +709,9 @@ static void print_found(const char *line) /* buf[] holds quarantined version of str */ /* Each part of the line that matches has the HIGHLIGHT - and NORMAL escape sequences placed around it. - NB: we regex against line, but insert text - from quarantined copy (buf[]) */ + * and NORMAL escape sequences placed around it. + * NB: we regex against line, but insert text + * from quarantined copy (buf[]) */ str = buf; growline = NULL; eflags = 0; diff --git a/release/src/router/busybox/miscutils/nandwrite.c b/release/src/router/busybox/miscutils/nandwrite.c index 2ba6e3fe55..5908ac7734 100644 --- a/release/src/router/busybox/miscutils/nandwrite.c +++ b/release/src/router/busybox/miscutils/nandwrite.c @@ -39,7 +39,7 @@ //usage: "[-o] [-b] [-s ADDR] [-f FILE] MTD_DEVICE" //usage:#define nanddump_full_usage "\n\n" //usage: "Dump the specified MTD device\n" -//usage: "\n -o Omit oob data" +//usage: "\n -o Dump oob data" //usage: "\n -b Omit bad block from the dump" //usage: "\n -s ADDR Start address" //usage: "\n -l LEN Length" @@ -129,7 +129,7 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv) xmove_fd(tmp_fd, IS_NANDDUMP ? STDOUT_FILENO : STDIN_FILENO); } - fd = xopen(argv[0], O_RDWR); + fd = xopen(argv[0], IS_NANDWRITE ? O_RDWR : O_RDONLY); xioctl(fd, MEMGETINFO, &meminfo); mtdoffset = xstrtou(opt_s, 0); @@ -162,9 +162,9 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv) tmp = next_good_eraseblock(fd, &meminfo, blockstart); if (tmp != blockstart) { /* bad block(s), advance mtdoffset */ - if (IS_NANDDUMP & !(opts & OPT_b)) { + if (IS_NANDDUMP && !(opts & OPT_b)) { int bad_len = MIN(tmp, end_addr) - mtdoffset; - dump_bad(&meminfo, bad_len, !(opts & OPT_o)); + dump_bad(&meminfo, bad_len, opts & OPT_o); } mtdoffset = tmp; } @@ -182,9 +182,9 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv) mtdoffset = next_good_eraseblock(fd, &meminfo, blockstart); if (IS_NANDWRITE) printf("Writing at 0x%08x\n", mtdoffset); - else if (mtdoffset > blockstart) { + else if (mtdoffset > blockstart && !(opts & OPT_b)) { int bad_len = MIN(mtdoffset, limit) - blockstart; - dump_bad(&meminfo, bad_len, !(opts & OPT_o)); + dump_bad(&meminfo, bad_len, opts & OPT_o); } if (mtdoffset >= limit) break; @@ -210,7 +210,7 @@ int nandwrite_main(int argc UNUSED_PARAM, char **argv) } xwrite(output_fd, filebuf, meminfo_writesize); - if (IS_NANDDUMP && !(opts & OPT_o)) { + if (IS_NANDDUMP && (opts & OPT_o)) { /* Dump OOB data */ oob.start = mtdoffset; xioctl(fd, MEMREADOOB, &oob); diff --git a/release/src/router/busybox/miscutils/rx.c b/release/src/router/busybox/miscutils/rx.c index af597320ce..1dffb593af 100644 --- a/release/src/router/busybox/miscutils/rx.c +++ b/release/src/router/busybox/miscutils/rx.c @@ -193,8 +193,8 @@ static int receive(/*int read_fd, */int file_fd) } if (cksum_or_crc != expected) { bb_error_msg(do_crc ? "crc error, expected 0x%04x, got 0x%04x" - : "checksum error, expected 0x%02x, got 0x%02x", - expected, cksum_or_crc); + : "checksum error, expected 0x%02x, got 0x%02x", + expected, cksum_or_crc); goto error; } diff --git a/release/src/router/busybox/miscutils/time.c b/release/src/router/busybox/miscutils/time.c index 945f15f0d5..19b0b44c91 100644 --- a/release/src/router/busybox/miscutils/time.c +++ b/release/src/router/busybox/miscutils/time.c @@ -16,6 +16,7 @@ //usage: "\n -v Verbose" #include "libbb.h" +#include /* getrusage */ /* Information on the resources used by a child process. */ typedef struct { @@ -69,7 +70,7 @@ static void resuse_end(pid_t pid, resource_t *resp) pid_t caught; /* Ignore signals, but don't ignore the children. When wait3 - returns the child process, set the time the command finished. */ + * returns the child process, set the time the command finished. */ while ((caught = wait3(&resp->waitstatus, 0, &resp->ru)) != pid) { if (caught == -1 && errno != EINTR) { bb_perror_msg("wait"); diff --git a/release/src/router/busybox/miscutils/watchdog.c b/release/src/router/busybox/miscutils/watchdog.c index ee28dc30d3..d3a76edf07 100644 --- a/release/src/router/busybox/miscutils/watchdog.c +++ b/release/src/router/busybox/miscutils/watchdog.c @@ -31,6 +31,7 @@ static void watchdog_shutdown(int sig UNUSED_PARAM) { static const char V = 'V'; + remove_pidfile(CONFIG_PID_FILE_PATH "/watchdog.pid"); write(3, &V, 1); /* Magic, see watchdog-api.txt in kernel */ if (ENABLE_FEATURE_CLEAN_UP) close(3); @@ -95,6 +96,8 @@ int watchdog_main(int argc, char **argv) stimer_duration, htimer_duration * 1000); #endif + write_pidfile(CONFIG_PID_FILE_PATH "/watchdog.pid"); + while (1) { /* * Make sure we clear the counter before sleeping, diff --git a/release/src/router/busybox/modutils/depmod.c b/release/src/router/busybox/modutils/depmod.c index 7752361261..aa228ec856 100644 --- a/release/src/router/busybox/modutils/depmod.c +++ b/release/src/router/busybox/modutils/depmod.c @@ -31,7 +31,7 @@ typedef struct module_info { } module_info; static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARAM, - void *data, int depth UNUSED_PARAM) + void *data, int depth UNUSED_PARAM) { char modname[MODULE_NAME_LEN]; module_info **first = (module_info **) data; @@ -95,7 +95,7 @@ static module_info *find_module(module_info *modules, const char *modname) } static void order_dep_list(module_info *modules, module_info *start, - llist_t *add) + llist_t *add) { module_info *m; llist_t *n; @@ -216,7 +216,7 @@ int depmod_main(int argc UNUSED_PARAM, char **argv) } while (*++argv); } else { recursive_action(".", ACTION_RECURSE, - parse_module, NULL, &modules, 0); + parse_module, NULL, &modules, 0); } /* Generate dependency and alias files */ diff --git a/release/src/router/busybox/modutils/modinfo.c b/release/src/router/busybox/modutils/modinfo.c index c0910ffedf..7c978d1da5 100644 --- a/release/src/router/busybox/modutils/modinfo.c +++ b/release/src/router/busybox/modutils/modinfo.c @@ -24,9 +24,9 @@ enum { - OPT_TAGS = (1 << 8) - 1, - OPT_F = (1 << 8), /* field name */ - OPT_0 = (1 << 9), /* \0 as separator */ + OPT_TAGS = (1 << 12) - 1, /* shortcut count */ + OPT_F = (1 << 12), /* field name */ + OPT_0 = (1 << 13), /* \0 as separator */ }; struct modinfo_env { @@ -49,13 +49,17 @@ static void modinfo(const char *path, const char *version, { static const char *const shortcuts[] = { "filename", - "description", - "author", "license", + "author", + "description", + "version", + "alias", + "srcversion", + "depends", + "uts_release", "vermagic", "parm", "firmware", - "depends", }; size_t len; int j, length; @@ -97,8 +101,11 @@ static void modinfo(const char *path, const char *version, if (ptr == NULL) /* no occurance left, done */ break; if (strncmp(ptr, pattern, length) == 0 && ptr[length] == '=') { - ptr += length + 1; - ptr += display(ptr, pattern, (1<name, - xhw->print((unsigned char *) &ifr.ifr_hwaddr.sa_data)); + ifname, xhw->name, + xhw->print((unsigned char *) &ifr.ifr_hwaddr.sa_data)); } } @@ -345,7 +345,7 @@ static int arp_set(char **args) /* Print the contents of an ARP request block. */ static void arp_disp(const char *name, char *ip, int type, int arp_flags, - char *hwa, char *mask, char *dev) + char *hwa, char *mask, char *dev) { static const int arp_masks[] = { ATF_PERM, ATF_PUBL, @@ -428,7 +428,7 @@ static int arp_show(char *name) /* All these strings can't overflow * because fgets above reads limited amount of data */ num = sscanf(line, "%s 0x%x 0x%x %s %s %s\n", - ip, &type, &flags, hwa, mask, dev); + ip, &type, &flags, hwa, mask, dev); if (num < 4) break; @@ -461,7 +461,7 @@ static int arp_show(char *name) } if (option_mask32 & ARP_OPT_v) printf("Entries: %d\tSkipped: %d\tFound: %d\n", - entries, entries - shown, shown); + entries, entries - shown, shown); if (!shown) { if (hw_set || host || device[0]) @@ -517,7 +517,7 @@ int arp_main(int argc UNUSED_PARAM, char **argv) if (hw->alen <= 0) { bb_error_msg_and_die("%s: %s without ARP support", - hw->name, "hardware type"); + hw->name, "hardware type"); } /* Now see what we have to do here... */ diff --git a/release/src/router/busybox/networking/brctl.c b/release/src/router/busybox/networking/brctl.c index 19f474fce3..207b069aad 100644 --- a/release/src/router/busybox/networking/brctl.c +++ b/release/src/router/busybox/networking/brctl.c @@ -67,7 +67,7 @@ # include /* FIXME: These 4 funcs are not really clean and could be improved */ -static ALWAYS_INLINE void strtotimeval(struct timeval *tv, +static ALWAYS_INLINE void bb_strtotimeval(struct timeval *tv, const char *time_str) { double secs; @@ -104,7 +104,7 @@ static void jiffies_to_tv(struct timeval *tv, unsigned long jiffies) static unsigned long str_to_jiffies(const char *time_str) { struct timeval tv; - strtotimeval(&tv, time_str); + bb_strtotimeval(&tv, time_str); return tv_to_jiffies(&tv); } @@ -129,15 +129,15 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) "setageing\0" "setfd\0" "sethello\0" "setmaxage\0" "setpathcost\0" "setportprio\0" "setbridgeprio\0" ) - IF_FEATURE_BRCTL_SHOW("showmacs\0" "show\0"); + IF_FEATURE_BRCTL_SHOW("show\0"); enum { ARG_addbr = 0, ARG_delbr, ARG_addif, ARG_delif IF_FEATURE_BRCTL_FANCY(, - ARG_stp, - ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage, - ARG_setpathcost, ARG_setportprio, ARG_setbridgeprio + ARG_stp, + ARG_setageing, ARG_setfd, ARG_sethello, ARG_setmaxage, + ARG_setpathcost, ARG_setportprio, ARG_setbridgeprio ) - IF_FEATURE_BRCTL_SHOW(, ARG_showmacs, ARG_show) + IF_FEATURE_BRCTL_SHOW(, ARG_show) }; int fd; @@ -285,7 +285,7 @@ int brctl_main(int argc UNUSED_PARAM, char **argv) bb_error_msg_and_die(bb_msg_invalid_arg, *argv, "port"); memset(ifidx, 0, sizeof ifidx); arm_ioctl(args, BRCTL_GET_PORT_LIST, (unsigned long)ifidx, - MAX_PORTS); + MAX_PORTS); xioctl(fd, SIOCDEVPRIVATE, &ifr); for (i = 0; i < MAX_PORTS; i++) { if (ifidx[i] == port) { diff --git a/release/src/router/busybox/networking/ether-wake.c b/release/src/router/busybox/networking/ether-wake.c index 6a88279f4e..bf09cd529d 100644 --- a/release/src/router/busybox/networking/ether-wake.c +++ b/release/src/router/busybox/networking/ether-wake.c @@ -49,9 +49,9 @@ * Copyright 1999-2003 Donald Becker and Scyld Computing Corporation. * * The author may be reached as becker@scyld, or C/O - * Scyld Computing Corporation - * 914 Bay Ridge Road, Suite 220 - * Annapolis MD 21403 + * Scyld Computing Corporation + * 914 Bay Ridge Road, Suite 220 + * Annapolis MD 21403 * * Notes: * On some systems dropping root capability allows the process to be @@ -113,7 +113,7 @@ void bb_debug_dump_packet(unsigned char *outpack, int pktsize) * Host name * IP address string * MAC address string -*/ + */ static void get_dest_addr(const char *hostid, struct ether_addr *eaddr) { struct ether_addr *eap; @@ -238,9 +238,9 @@ int ether_wake_main(int argc UNUSED_PARAM, char **argv) { unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data; printf("The hardware address (SIOCGIFHWADDR) of %s is type %d " - "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n\n", ifname, - if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1], - hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); + "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n\n", ifname, + if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1], + hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]); } # endif } diff --git a/release/src/router/busybox/networking/ftpd.c b/release/src/router/busybox/networking/ftpd.c index 1c97df564f..33db964fa4 100644 --- a/release/src/router/busybox/networking/ftpd.c +++ b/release/src/router/busybox/networking/ftpd.c @@ -821,7 +821,7 @@ handle_size_or_mdtm(int need_size) gmtime_r(&statbuf.st_mtime, &broken_out); sprintf(buf, STR(FTP_STATFILE_OK)" %04u%02u%02u%02u%02u%02u\r\n", broken_out.tm_year + 1900, - broken_out.tm_mon, + broken_out.tm_mon + 1, broken_out.tm_mday, broken_out.tm_hour, broken_out.tm_min, @@ -927,6 +927,7 @@ handle_upload_common(int is_append, int is_unique) || fstat(local_file_fd, &statbuf) != 0 || !S_ISREG(statbuf.st_mode) ) { + free(tempname); WRITE_ERR(FTP_UPLOADFAIL); if (local_file_fd >= 0) goto close_local_and_bail; diff --git a/release/src/router/busybox/networking/httpd.c b/release/src/router/busybox/networking/httpd.c index 12218a0a32..1934bb27eb 100644 --- a/release/src/router/busybox/networking/httpd.c +++ b/release/src/router/busybox/networking/httpd.c @@ -796,9 +796,9 @@ static void parse_conf(const char *path, int flag) /* the line is not recognized */ config_error: bb_error_msg("config error '%s' in '%s'", buf, filename); - } /* while (fgets) */ + } /* while (fgets) */ - fclose(f); + fclose(f); } #if ENABLE_FEATURE_HTTPD_ENCODE_URL_STR @@ -1414,7 +1414,7 @@ static void send_cgi_and_exit( if (script != url) { /* paranoia */ *script = '\0'; if (chdir(url + 1) != 0) { - bb_perror_msg("chdir(%s)", url + 1); + bb_perror_msg("can't change directory to '%s'", url + 1); goto error_execing_cgi; } // not needed: *script = '/'; @@ -1708,7 +1708,7 @@ static int pam_talker(int num_msg, case PAM_PROMPT_ECHO_OFF: s = userinfo->pw; break; - case PAM_ERROR_MSG: + case PAM_ERROR_MSG: case PAM_TEXT_INFO: s = ""; break; diff --git a/release/src/router/busybox/networking/httpd_indexcgi.c b/release/src/router/busybox/networking/httpd_indexcgi.c index d732cd4f8a..562cd7fbef 100644 --- a/release/src/router/busybox/networking/httpd_indexcgi.c +++ b/release/src/router/busybox/networking/httpd_indexcgi.c @@ -35,6 +35,7 @@ httpd_indexcgi.c -o index.cgi * 2576 4 2048 4628 1214 index.cgi.o */ +#define _GNU_SOURCE 1 /* for strchrnul */ #include #include #include diff --git a/release/src/router/busybox/networking/httpd_ssi.c b/release/src/router/busybox/networking/httpd_ssi.c index cfe64eb46e..4bd9a6d97d 100644 --- a/release/src/router/busybox/networking/httpd_ssi.c +++ b/release/src/router/busybox/networking/httpd_ssi.c @@ -133,7 +133,7 @@ static void process_includes(const char *filename) process_includes(include_directive); /* Print everything after directive */ - if (end) { + if (end) { fputs(end, stdout); free(end); } diff --git a/release/src/router/busybox/networking/ifconfig.c b/release/src/router/busybox/networking/ifconfig.c index b6604f5d15..782374b35b 100644 --- a/release/src/router/busybox/networking/ifconfig.c +++ b/release/src/router/busybox/networking/ifconfig.c @@ -174,10 +174,6 @@ struct in6_ifreq { #define ARG_ADD_DEL (A_CAST_HOST_COPY_RESOLVE | A_SET_AFTER) -/* - * Set up the tables. Warning! They must have corresponding order! - */ - struct arg1opt { const char *name; unsigned short selector; @@ -198,6 +194,10 @@ struct options { #define ifreq_offsetof(x) offsetof(struct ifreq, x) +/* + * Set up the tables. Warning! They must have corresponding order! + */ + static const struct arg1opt Arg1Opt[] = { { "SIFMETRIC", SIOCSIFMETRIC, ifreq_offsetof(ifr_metric) }, { "SIFMTU", SIOCSIFMTU, ifreq_offsetof(ifr_mtu) }, @@ -220,11 +220,11 @@ static const struct arg1opt Arg1Opt[] = { { "SIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.base_addr) }, { "SIFMAP", SIOCSIFMAP, ifreq_offsetof(ifr_map.irq) }, #endif - /* Last entry if for unmatched (possibly hostname) arg. */ #if ENABLE_FEATURE_IPV6 { "SIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr) }, /* IPv6 version ignores the offset */ { "DIFADDR", SIOCDIFADDR, ifreq_offsetof(ifr_addr) }, /* IPv6 version ignores the offset */ #endif + /* Last entry is for unmatched (assumed to be hostname/address) arg. */ { "SIFADDR", SIOCSIFADDR, ifreq_offsetof(ifr_addr) }, }; @@ -265,16 +265,49 @@ static const struct options OptArray[] = { { NULL, 0, ARG_HOSTNAME, (IFF_UP | IFF_RUNNING) } }; -/* - * A couple of prototypes. - */ #if ENABLE_FEATURE_IFCONFIG_HW -static int in_ether(const char *bufp, struct sockaddr *sap); +/* Input an Ethernet address and convert to binary. */ +static int in_ether(const char *bufp, struct sockaddr *sap) +{ + char *ptr; + int i, j; + unsigned char val; + unsigned char c; + + sap->sa_family = ARPHRD_ETHER; + ptr = (char *) sap->sa_data; + + i = 0; + do { + j = val = 0; + + /* We might get a semicolon here - not required. */ + if (i && (*bufp == ':')) { + bufp++; + } + + do { + c = *bufp; + if (((unsigned char)(c - '0')) <= 9) { + c -= '0'; + } else if ((unsigned char)((c|0x20) - 'a') <= 5) { + c = (unsigned char)((c|0x20) - 'a') + 10; + } else if (j && (c == ':' || c == 0)) { + break; + } else { + return -1; + } + ++bufp; + val <<= 4; + val += c; + } while (++j < 2); + *ptr++ = val; + } while (++i < ETH_ALEN); + + return *bufp; /* Error if we don't end at end of string. */ +} #endif -/* - * Our main function. - */ int ifconfig_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int ifconfig_main(int argc UNUSED_PARAM, char **argv) { @@ -330,7 +363,7 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv) strncpy_IFNAMSIZ(ifr.ifr_name, *argv); /* Process the remaining arguments. */ - while (*++argv != (char *) NULL) { + while (*++argv != NULL) { p = *argv; mask = N_MASK; if (*p == '-') { /* If the arg starts with '-'... */ @@ -356,9 +389,9 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv) FOUND_ARG: if (mask & ARG_MASK) { mask = op->arg_flags; - a1op = Arg1Opt + (op - OptArray); if (mask & A_NETMASK & did_flags) bb_show_usage(); + a1op = Arg1Opt + (op - OptArray); if (*++argv == NULL) { if (mask & A_ARG_REQ) bb_show_usage(); @@ -371,19 +404,9 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_IFCONFIG_HW if (mask & A_CAST_RESOLVE) { #endif -#if ENABLE_FEATURE_IPV6 - char *prefix; - int prefix_len = 0; -#endif - /*safe_strncpy(host, *argv, (sizeof host));*/ host = *argv; -#if ENABLE_FEATURE_IPV6 - prefix = strchr(host, '/'); - if (prefix) { - prefix_len = xatou_range(prefix + 1, 0, 128); - *prefix = '\0'; - } -#endif + if (strcmp(host, "inet") == 0) + continue; /* compat stuff */ sai.sin_family = AF_INET; sai.sin_port = 0; if (strcmp(host, "default") == 0) { @@ -391,7 +414,8 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv) sai.sin_addr.s_addr = INADDR_ANY; } #if ENABLE_FEATURE_IFCONFIG_BROADCAST_PLUS - else if ((host[0] == '+' && !host[1]) && (mask & A_BROADCAST) + else if ((host[0] == '+' && !host[1]) + && (mask & A_BROADCAST) && (did_flags & (A_NETMASK|A_HOSTNAME)) == (A_NETMASK|A_HOSTNAME) ) { /* + is special, meaning broadcast is derived. */ @@ -400,23 +424,36 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv) #endif else { len_and_sockaddr *lsa; - if (strcmp(host, "inet") == 0) - continue; /* compat stuff */ +#if ENABLE_FEATURE_IPV6 + char *prefix; + int prefix_len = 0; + prefix = strchr(host, '/'); + if (prefix) { + prefix_len = xatou_range(prefix + 1, 0, 128); + *prefix = '\0'; + } + resolve: +#endif lsa = xhost2sockaddr(host, 0); #if ENABLE_FEATURE_IPV6 + if (lsa->u.sa.sa_family != AF_INET6 && prefix) { +/* TODO: we do not support "ifconfig eth0 up 1.2.3.4/17". + * For now, just make it fail instead of silently ignoring "/17" part: + */ + *prefix = '/'; + goto resolve; + } if (lsa->u.sa.sa_family == AF_INET6) { int sockfd6; struct in6_ifreq ifr6; - memcpy((char *) &ifr6.ifr6_addr, - (char *) &(lsa->u.sin6.sin6_addr), - sizeof(struct in6_addr)); - - /* Create a channel to the NET kernel. */ sockfd6 = xsocket(AF_INET6, SOCK_DGRAM, 0); - xioctl(sockfd6, SIOGIFINDEX, &ifr); + xioctl(sockfd6, SIOCGIFINDEX, &ifr); ifr6.ifr6_ifindex = ifr.ifr_ifindex; ifr6.ifr6_prefixlen = prefix_len; + memcpy(&ifr6.ifr6_addr, + &lsa->u.sin6.sin6_addr, + sizeof(struct in6_addr)); ioctl_or_perror_and_die(sockfd6, a1op->selector, &ifr6, "SIOC%s", a1op->name); if (ENABLE_FEATURE_CLEAN_UP) free(lsa); @@ -437,19 +474,18 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_IFCONFIG_HW } else { /* A_CAST_HOST_COPY_IN_ETHER */ /* This is the "hw" arg case. */ - smalluint hw_class= index_in_substrings("ether\0" + smalluint hw_class = index_in_substrings("ether\0" IF_FEATURE_HWIB("infiniband\0"), *argv) + 1; if (!hw_class || !*++argv) bb_show_usage(); - /*safe_strncpy(host, *argv, sizeof(host));*/ host = *argv; if (hw_class == 1 ? in_ether(host, &sa) : in_ib(host, &sa)) bb_error_msg_and_die("invalid hw-addr %s", host); p = (char *) &sa; } #endif - memcpy( (((char *)&ifr) + a1op->ifr_offset), - p, sizeof(struct sockaddr)); + memcpy( ((char *)&ifr) + a1op->ifr_offset, + p, sizeof(struct sockaddr)); } else { /* FIXME: error check?? */ unsigned long i = strtoul(*argv, NULL, 0); @@ -458,17 +494,17 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv) if (mask & A_MAP_TYPE) { xioctl(sockfd, SIOCGIFMAP, &ifr); if ((mask & A_MAP_UCHAR) == A_MAP_UCHAR) - *((unsigned char *) p) = i; + *(unsigned char *) p = i; else if (mask & A_MAP_USHORT) - *((unsigned short *) p) = i; + *(unsigned short *) p = i; else - *((unsigned long *) p) = i; + *(unsigned long *) p = i; } else #endif if (mask & A_CAST_CHAR_PTR) - *((caddr_t *) p) = (caddr_t) i; + *(caddr_t *) p = (caddr_t) i; else /* A_CAST_INT */ - *((int *) p) = i; + *(int *) p = i; } ioctl_or_perror_and_die(sockfd, a1op->selector, &ifr, "SIOC%s", a1op->name); @@ -494,7 +530,7 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv) if (!(mask & A_SET_AFTER)) continue; mask = N_SET; - } + } /* if (mask & ARG_MASK) */ xioctl(sockfd, SIOCGIFFLAGS, &ifr); selector = op->selector; @@ -509,46 +545,3 @@ int ifconfig_main(int argc UNUSED_PARAM, char **argv) close(sockfd); return 0; } - -#if ENABLE_FEATURE_IFCONFIG_HW -/* Input an Ethernet address and convert to binary. */ -static int in_ether(const char *bufp, struct sockaddr *sap) -{ - char *ptr; - int i, j; - unsigned char val; - unsigned char c; - - sap->sa_family = ARPHRD_ETHER; - ptr = (char *) sap->sa_data; - - i = 0; - do { - j = val = 0; - - /* We might get a semicolon here - not required. */ - if (i && (*bufp == ':')) { - bufp++; - } - - do { - c = *bufp; - if (((unsigned char)(c - '0')) <= 9) { - c -= '0'; - } else if (((unsigned char)((c|0x20) - 'a')) <= 5) { - c = (c|0x20) - ('a'-10); - } else if (j && (c == ':' || c == 0)) { - break; - } else { - return -1; - } - ++bufp; - val <<= 4; - val += c; - } while (++j < 2); - *ptr++ = val; - } while (++i < ETH_ALEN); - - return *bufp; /* Error if we don't end at end of string. */ -} -#endif diff --git a/release/src/router/busybox/networking/ifenslave.c b/release/src/router/busybox/networking/ifenslave.c index ae7719f52f..c3be8180b6 100644 --- a/release/src/router/busybox/networking/ifenslave.c +++ b/release/src/router/busybox/networking/ifenslave.c @@ -270,7 +270,7 @@ static int set_if_addr(char *master_ifname, char *slave_ifname) if (res < 0) { ifr.ifr_addr.sa_family = AF_INET; memset(ifr.ifr_addr.sa_data, 0, - sizeof(ifr.ifr_addr.sa_data)); + sizeof(ifr.ifr_addr.sa_data)); } res = set_ifrname_and_do_ioctl(ifra[i].s_ioctl, &ifr, slave_ifname); @@ -546,7 +546,7 @@ int ifenslave_main(int argc UNUSED_PARAM, char **argv) #ifdef WHY_BOTHER /* Neither -c[hange] nor -d[etach] -> it's "enslave" then; * and -f[orce] is not there too. Check that it's ethernet. */ - if (!(opt & (OPT_d|OPT_c|OPT_f)) { + if (!(opt & (OPT_d|OPT_c|OPT_f))) { /* The family '1' is ARPHRD_ETHER for ethernet. */ if (master.hwaddr.ifr_hwaddr.sa_family != 1) { bb_error_msg_and_die( diff --git a/release/src/router/busybox/networking/ifplugd.c b/release/src/router/busybox/networking/ifplugd.c index d8358cdfd5..86586f0fe1 100644 --- a/release/src/router/busybox/networking/ifplugd.c +++ b/release/src/router/busybox/networking/ifplugd.c @@ -22,9 +22,9 @@ //usage: "\n -r PROG Script to run" //usage: "\n -x ARG Extra argument for script" //usage: "\n -I Don't exit on nonzero exit code from script" -//usage: "\n -p Don't run script on daemon startup" -//usage: "\n -q Don't run script on daemon quit" -//usage: "\n -l Run script on startup even if no cable is detected" +//usage: "\n -p Don't run \"up\" script on startup" +//usage: "\n -q Don't run \"down\" script on exit" +//usage: "\n -l Always run script on startup" //usage: "\n -t SECS Poll time in seconds" //usage: "\n -u SECS Delay before running script after link up" //usage: "\n -d SECS Delay after link down" @@ -551,7 +551,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv) applet_name = xasprintf("ifplugd(%s)", G.iface); #if ENABLE_FEATURE_PIDFILE - pidfile_name = xasprintf(_PATH_VARRUN"ifplugd.%s.pid", G.iface); + pidfile_name = xasprintf(CONFIG_PID_FILE_PATH "/ifplugd.%s.pid", G.iface); pid_from_pidfile = read_pid(pidfile_name); if (opts & FLAG_KILL) { diff --git a/release/src/router/busybox/networking/ifupdown.c b/release/src/router/busybox/networking/ifupdown.c index 9b34986964..818048284a 100644 --- a/release/src/router/busybox/networking/ifupdown.c +++ b/release/src/router/busybox/networking/ifupdown.c @@ -49,9 +49,6 @@ #include #define MAX_OPT_DEPTH 10 -#define EUNBALBRACK 10001 -#define EUNDEFVAR 10002 -#define EUNBALPER 10000 #if ENABLE_FEATURE_IFUPDOWN_MAPPING #define MAX_INTERFACE_LENGTH 10 @@ -233,7 +230,7 @@ static int count_netmask_bits(const char *dotted_quad) static char *parse(const char *command, struct interface_defn_t *ifd) { size_t old_pos[MAX_OPT_DEPTH] = { 0 }; - int okay[MAX_OPT_DEPTH] = { 1 }; + smallint okay[MAX_OPT_DEPTH] = { 1 }; int opt_depth = 1; char *result = NULL; @@ -244,13 +241,10 @@ static char *parse(const char *command, struct interface_defn_t *ifd) command++; break; case '\\': - if (command[1]) { - addstr(&result, command + 1, 1); - command += 2; - } else { - addstr(&result, command, 1); + if (command[1]) command++; - } + addstr(&result, command, 1); + command++; break; case '[': if (command[1] == '[' && opt_depth < MAX_OPT_DEPTH) { @@ -259,7 +253,7 @@ static char *parse(const char *command, struct interface_defn_t *ifd) opt_depth++; command += 2; } else { - addstr(&result, "[", 1); + addstr(&result, command, 1); command++; } break; @@ -271,7 +265,7 @@ static char *parse(const char *command, struct interface_defn_t *ifd) } command += 2; } else { - addstr(&result, "]", 1); + addstr(&result, command, 1); command++; } break; @@ -283,7 +277,7 @@ static char *parse(const char *command, struct interface_defn_t *ifd) command++; nextpercent = strchr(command, '%'); if (!nextpercent) { - errno = EUNBALPER; + /* Unterminated %var% */ free(result); return NULL; } @@ -328,13 +322,13 @@ static char *parse(const char *command, struct interface_defn_t *ifd) } if (opt_depth > 1) { - errno = EUNBALBRACK; + /* Unbalanced bracket */ free(result); return NULL; } if (!okay[0]) { - errno = EUNDEFVAR; + /* Undefined variable and we aren't in a bracket */ free(result); return NULL; } @@ -1058,7 +1052,7 @@ static int iface_up(struct interface_defn_t *iface) static int iface_down(struct interface_defn_t *iface) { - if (!iface->method->down(iface,check)) return -1; + if (!iface->method->down(iface, check)) return -1; set_environ(iface, "stop", "pre-down"); if (!execute_all(iface, "down")) return 0; if (!iface->method->down(iface, doit)) return 0; diff --git a/release/src/router/busybox/networking/inetd.c b/release/src/router/busybox/networking/inetd.c index 26b66992d4..584c5e5e40 100644 --- a/release/src/router/busybox/networking/inetd.c +++ b/release/src/router/busybox/networking/inetd.c @@ -165,6 +165,8 @@ //usage: "\n (default: 0 - disabled)" #include +#include /* setrlimit */ +#include /* un.h may need this */ #include #include "libbb.h" @@ -184,8 +186,6 @@ #define ENABLE_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN 0 #endif -#define _PATH_INETDPID "/var/run/inetd.pid" - #define CNT_INTERVAL 60 /* servers in CNT_INTERVAL sec. */ #define RETRYTIME 60 /* retry after bind or server fail */ @@ -1130,7 +1130,7 @@ static void clean_up_and_exit(int sig UNUSED_PARAM) if (ENABLE_FEATURE_CLEAN_UP) close(sep->se_fd); } - remove_pidfile(_PATH_INETDPID); + remove_pidfile(CONFIG_PID_FILE_PATH "/inetd.pid"); exit(EXIT_SUCCESS); } @@ -1179,7 +1179,7 @@ int inetd_main(int argc UNUSED_PARAM, char **argv) setgroups(1, &gid); } - write_pidfile(_PATH_INETDPID); + write_pidfile(CONFIG_PID_FILE_PATH "/inetd.pid"); /* never fails under Linux (except if you pass it bad arguments) */ getrlimit(RLIMIT_NOFILE, &rlim_ofile); diff --git a/release/src/router/busybox/networking/interface.c b/release/src/router/busybox/networking/interface.c index 4a319bfb3b..73a2fdd851 100644 --- a/release/src/router/busybox/networking/interface.c +++ b/release/src/router/busybox/networking/interface.c @@ -27,7 +27,7 @@ * {1.34} - 19980630 - Arnaldo Carvalho de Melo * - gettext instead of catgets for i18n * 10/1998 - Andi Kleen. Use interface list primitives. - * 20001008 - Bernd Eckenfels, Patch from RH for setting mtu + * 20001008 - Bernd Eckenfels, Patch from RH for setting mtu * (default AF was wrong) */ @@ -950,8 +950,8 @@ static void ife_print6(struct interface *ptr) (struct sockaddr *) &sap.sin6_addr); sap.sin6_family = AF_INET6; printf(" inet6 addr: %s/%d", - INET6_sprint((struct sockaddr *) &sap, 1), - plen); + INET6_sprint((struct sockaddr *) &sap, 1), + plen); printf(" Scope:"); switch (scope & IPV6_ADDR_SCOPE_MASK) { case 0: @@ -1019,7 +1019,7 @@ static void ife_print(struct interface *ptr) if (ptr->has_ip) { printf(" %s addr:%s ", ap->name, - ap->sprint(&ptr->addr, 1)); + ap->sprint(&ptr->addr, 1)); if (ptr->flags & IFF_POINTOPOINT) { printf(" P-t-P:%s ", ap->sprint(&ptr->dstaddr, 1)); } @@ -1102,17 +1102,17 @@ static void ife_print(struct interface *ptr) printf(" "); printf("RX packets:%llu errors:%lu dropped:%lu overruns:%lu frame:%lu\n", - ptr->stats.rx_packets, ptr->stats.rx_errors, - ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors, - ptr->stats.rx_frame_errors); + ptr->stats.rx_packets, ptr->stats.rx_errors, + ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors, + ptr->stats.rx_frame_errors); if (can_compress) printf(" compressed:%lu\n", - ptr->stats.rx_compressed); + ptr->stats.rx_compressed); printf(" "); printf("TX packets:%llu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n", - ptr->stats.tx_packets, ptr->stats.tx_errors, - ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors, - ptr->stats.tx_carrier_errors); + ptr->stats.tx_packets, ptr->stats.tx_errors, + ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors, + ptr->stats.tx_carrier_errors); printf(" collisions:%lu ", ptr->stats.collisions); if (can_compress) printf("compressed:%lu ", ptr->stats.tx_compressed); @@ -1129,13 +1129,12 @@ static void ife_print(struct interface *ptr) printf(" "); if (ptr->map.irq) printf("Interrupt:%d ", ptr->map.irq); - if (ptr->map.base_addr >= 0x100) /* Only print devices using it for - I/O maps */ + if (ptr->map.base_addr >= 0x100) /* Only print devices using it for I/O maps */ printf("Base address:0x%lx ", - (unsigned long) ptr->map.base_addr); + (unsigned long) ptr->map.base_addr); if (ptr->map.mem_start) { printf("Memory:%lx-%lx ", ptr->map.mem_start, - ptr->map.mem_end); + ptr->map.mem_end); } if (ptr->map.dma) printf("DMA chan:%x ", ptr->map.dma); @@ -1168,7 +1167,7 @@ static struct interface *lookup_interface(char *name) #ifdef UNUSED static int for_all_interfaces(int (*doit) (struct interface *, void *), - void *cookie) + void *cookie) { struct interface *ife; diff --git a/release/src/router/busybox/networking/libiproute/ipaddress.c b/release/src/router/busybox/networking/libiproute/ipaddress.c index b3748e8c59..3fd3f44788 100644 --- a/release/src/router/busybox/networking/libiproute/ipaddress.c +++ b/release/src/router/busybox/networking/libiproute/ipaddress.c @@ -314,14 +314,16 @@ static int FAST_FUNC print_addrinfo(const struct sockaddr_nl *who UNUSED_PARAM, if (rta_tb[IFA_BROADCAST]) { printf("brd %s ", rt_addr_n2a(ifa->ifa_family, - RTA_DATA(rta_tb[IFA_BROADCAST]), - abuf, sizeof(abuf))); + RTA_DATA(rta_tb[IFA_BROADCAST]), + abuf, sizeof(abuf)) + ); } if (rta_tb[IFA_ANYCAST]) { printf("any %s ", rt_addr_n2a(ifa->ifa_family, - RTA_DATA(rta_tb[IFA_ANYCAST]), - abuf, sizeof(abuf))); + RTA_DATA(rta_tb[IFA_ANYCAST]), + abuf, sizeof(abuf)) + ); } printf("scope %s ", rtnl_rtscope_n2a(ifa->ifa_scope, b1)); if (ifa->ifa_flags & IFA_F_SECONDARY) { diff --git a/release/src/router/busybox/networking/libiproute/iprule.c b/release/src/router/busybox/networking/libiproute/iprule.c index dd3265c7cd..241a6bf9d0 100644 --- a/release/src/router/busybox/networking/libiproute/iprule.c +++ b/release/src/router/busybox/networking/libiproute/iprule.c @@ -73,15 +73,17 @@ static int FAST_FUNC print_rule(const struct sockaddr_nl *who UNUSED_PARAM, if (tb[RTA_SRC]) { if (r->rtm_src_len != host_len) { printf("%s/%u", rt_addr_n2a(r->rtm_family, - RTA_DATA(tb[RTA_SRC]), - abuf, sizeof(abuf)), + RTA_DATA(tb[RTA_SRC]), + abuf, sizeof(abuf)), r->rtm_src_len - ); + ); } else { fputs(format_host(r->rtm_family, - RTA_PAYLOAD(tb[RTA_SRC]), - RTA_DATA(tb[RTA_SRC]), - abuf, sizeof(abuf)), stdout); + RTA_PAYLOAD(tb[RTA_SRC]), + RTA_DATA(tb[RTA_SRC]), + abuf, sizeof(abuf)), + stdout + ); } } else if (r->rtm_src_len) { printf("0/%d", r->rtm_src_len); diff --git a/release/src/router/busybox/networking/libiproute/iptunnel.c b/release/src/router/busybox/networking/libiproute/iptunnel.c index 5942feafc4..2b651b9266 100644 --- a/release/src/router/busybox/networking/libiproute/iptunnel.c +++ b/release/src/router/busybox/networking/libiproute/iptunnel.c @@ -438,7 +438,7 @@ static void print_tunnel(struct ip_tunnel_parm *p) printf(" inherit"); if (p->iph.tos & ~1) printf("%c%s ", p->iph.tos & 1 ? '/' : ' ', - rtnl_dsfield_n2a(p->iph.tos & ~1, b1)); + rtnl_dsfield_n2a(p->iph.tos & ~1, b1)); } if (!(p->iph.frag_off & htons(IP_DF))) printf(" nopmtudisc"); diff --git a/release/src/router/busybox/networking/libiproute/ll_proto.c b/release/src/router/busybox/networking/libiproute/ll_proto.c index 7aac8364d3..da2b53cbff 100644 --- a/release/src/router/busybox/networking/libiproute/ll_proto.c +++ b/release/src/router/busybox/networking/libiproute/ll_proto.c @@ -14,19 +14,10 @@ #include -#if !ENABLE_WERROR -#warning de-bloat -#endif -/* Before re-enabling this, please (1) conditionalize exotic protocols - * on CONFIG_something, and (2) decouple strings and numbers - * (use llproto_ids[] = n,n,n..; and llproto_names[] = "loop\0" "pup\0" ...;) - */ +/* Please conditionalize exotic protocols on CONFIG_something */ -#define __PF(f,n) { ETH_P_##f, #n }, -static struct { - int id; - const char *name; -} llproto_names[] = { +static const uint16_t llproto_ids[] = { +#define __PF(f,n) ETH_P_##f, __PF(LOOP,loop) __PF(PUP,pup) #ifdef ETH_P_PUPAT @@ -86,33 +77,104 @@ __PF(IRDA,irda) __PF(ECONET,econet) #endif -{ 0x8100, "802.1Q" }, -{ ETH_P_IP, "ipv4" }, +0x8100, +ETH_P_IP }; #undef __PF +/* Keep declarations above and below in sync! */ + +static const char llproto_names[] = +#define __PF(f,n) #n "\0" +__PF(LOOP,loop) +__PF(PUP,pup) +#ifdef ETH_P_PUPAT +__PF(PUPAT,pupat) +#endif +__PF(IP,ip) +__PF(X25,x25) +__PF(ARP,arp) +__PF(BPQ,bpq) +#ifdef ETH_P_IEEEPUP +__PF(IEEEPUP,ieeepup) +#endif +#ifdef ETH_P_IEEEPUPAT +__PF(IEEEPUPAT,ieeepupat) +#endif +__PF(DEC,dec) +__PF(DNA_DL,dna_dl) +__PF(DNA_RC,dna_rc) +__PF(DNA_RT,dna_rt) +__PF(LAT,lat) +__PF(DIAG,diag) +__PF(CUST,cust) +__PF(SCA,sca) +__PF(RARP,rarp) +__PF(ATALK,atalk) +__PF(AARP,aarp) +__PF(IPX,ipx) +__PF(IPV6,ipv6) +#ifdef ETH_P_PPP_DISC +__PF(PPP_DISC,ppp_disc) +#endif +#ifdef ETH_P_PPP_SES +__PF(PPP_SES,ppp_ses) +#endif +#ifdef ETH_P_ATMMPOA +__PF(ATMMPOA,atmmpoa) +#endif +#ifdef ETH_P_ATMFATE +__PF(ATMFATE,atmfate) +#endif + +__PF(802_3,802_3) +__PF(AX25,ax25) +__PF(ALL,all) +__PF(802_2,802_2) +__PF(SNAP,snap) +__PF(DDCMP,ddcmp) +__PF(WAN_PPP,wan_ppp) +__PF(PPP_MP,ppp_mp) +__PF(LOCALTALK,localtalk) +__PF(PPPTALK,ppptalk) +__PF(TR_802_2,tr_802_2) +__PF(MOBITEX,mobitex) +__PF(CONTROL,control) +__PF(IRDA,irda) +#ifdef ETH_P_ECONET +__PF(ECONET,econet) +#endif + +"802.1Q" "\0" +"ipv4" "\0" +; +#undef __PF + const char* FAST_FUNC ll_proto_n2a(unsigned short id, char *buf, int len) { unsigned i; id = ntohs(id); - for (i = 0; i < ARRAY_SIZE(llproto_names); i++) { - if (llproto_names[i].id == id) - return llproto_names[i].name; + for (i = 0; i < ARRAY_SIZE(llproto_ids); i++) { + if (llproto_ids[i] == id) + return nth_string(llproto_names, i); } - snprintf(buf, len, "[%d]", id); + snprintf(buf, len, "[%u]", id); return buf; } int FAST_FUNC ll_proto_a2n(unsigned short *id, char *buf) { unsigned i; - for (i = 0; i < ARRAY_SIZE(llproto_names); i++) { - if (strcasecmp(llproto_names[i].name, buf) == 0) { - i = llproto_names[i].id; - goto good; - } + const char *name = llproto_names; + for (i = 0; i < ARRAY_SIZE(llproto_ids); i++) { + if (strcasecmp(name, buf) == 0) { + i = llproto_ids[i]; + goto good; + } + name += strlen(name) + 1; } + errno = 0; i = bb_strtou(buf, NULL, 0); if (errno || i > 0xffff) return -1; diff --git a/release/src/router/busybox/networking/nc.c b/release/src/router/busybox/networking/nc.c index 1b32e3aa33..0c843a6862 100644 --- a/release/src/router/busybox/networking/nc.c +++ b/release/src/router/busybox/networking/nc.c @@ -120,7 +120,7 @@ int nc_main(int argc, char **argv) /* getopt32 is _almost_ usable: ** it cannot handle "... -e PROG -prog-opt" */ while ((opt = getopt(argc, argv, - "" IF_NC_SERVER("lp:") IF_NC_EXTRA("w:i:f:e:") )) > 0 + "" IF_NC_SERVER("lp:") IF_NC_EXTRA("w:i:f:e:") )) > 0 ) { if (ENABLE_NC_SERVER && opt == 'l') IF_NC_SERVER(do_listen++); diff --git a/release/src/router/busybox/networking/netstat.c b/release/src/router/busybox/networking/netstat.c index 9c239579fe..c0c6ba5010 100644 --- a/release/src/router/busybox/networking/netstat.c +++ b/release/src/router/busybox/networking/netstat.c @@ -187,7 +187,7 @@ static void prg_cache_add(long inode, char *name) for (pnp = prg_hash + hi; (pn = *pnp) != NULL; pnp = &pn->next) { if (pn->inode == inode) { /* Some warning should be appropriate here - as we got multiple processes for one i-node */ + * as we got multiple processes for one i-node */ return; } } diff --git a/release/src/router/busybox/networking/ntpd.c b/release/src/router/busybox/networking/ntpd.c index 603801ec60..79b7c37936 100644 --- a/release/src/router/busybox/networking/ntpd.c +++ b/release/src/router/busybox/networking/ntpd.c @@ -46,6 +46,7 @@ #include "libbb.h" #include #include /* For IPTOS_LOWDELAY definition */ +#include /* setpriority */ #include #ifndef IPTOS_LOWDELAY # define IPTOS_LOWDELAY 0x10 @@ -220,14 +221,14 @@ typedef struct { typedef struct { len_and_sockaddr *p_lsa; char *p_dotted; - /* when to send new query (if p_fd == -1) - * or when receive times out (if p_fd >= 0): */ int p_fd; int datapoint_idx; uint32_t lastpkt_refid; uint8_t lastpkt_status; uint8_t lastpkt_stratum; uint8_t reachable_bits; + /* when to send new query (if p_fd == -1) + * or when receive times out (if p_fd >= 0): */ double next_action_time; double p_xmttime; double lastpkt_recv_time; @@ -895,6 +896,11 @@ step_time(double offset) /* Correct various fields which contain time-relative values: */ + /* Globals: */ + G.cur_time += offset; + G.last_update_recv_time += offset; + G.last_script_run += offset; + /* p->lastpkt_recv_time, p->next_action_time and such: */ for (item = G.ntp_peers; item != NULL; item = item->link) { peer_t *pp = (peer_t *) item->data; @@ -902,11 +908,16 @@ step_time(double offset) //bb_error_msg("offset:%+f pp->next_action_time:%f -> %f", // offset, pp->next_action_time, pp->next_action_time + offset); pp->next_action_time += offset; + if (pp->p_fd >= 0) { + /* We wait for reply from this peer too. + * But due to step we are doing, reply's data is no longer + * useful (in fact, it'll be bogus). Stop waiting for it. + */ + close(pp->p_fd); + pp->p_fd = -1; + set_next(pp, RETRY_INTERVAL); + } } - /* Globals: */ - G.cur_time += offset; - G.last_update_recv_time += offset; - G.last_script_run += offset; } @@ -1623,22 +1634,30 @@ recv_and_process_peer_pkt(peer_t *p) ) { //TODO: always do this? interval = retry_interval(); - goto set_next_and_close_sock; + goto set_next_and_ret; } xfunc_die(); } if (size != NTP_MSGSIZE_NOAUTH && size != NTP_MSGSIZE) { bb_error_msg("malformed packet received from %s", p->p_dotted); - goto bail; + return; } if (msg.m_orgtime.int_partl != p->p_xmt_msg.m_xmttime.int_partl || msg.m_orgtime.fractionl != p->p_xmt_msg.m_xmttime.fractionl ) { - goto bail; + /* Somebody else's packet */ + return; } + /* We do not expect any more packets from this peer for now. + * Closing the socket informs kernel about it. + * We open a new socket when we send a new query. + */ + close(p->p_fd); + p->p_fd = -1; + if ((msg.m_status & LI_ALARM) == LI_ALARM || msg.m_stratum == 0 || msg.m_stratum > NTP_MAXSTRATUM @@ -1647,8 +1666,8 @@ recv_and_process_peer_pkt(peer_t *p) // "DENY", "RSTR" - peer does not like us at all // "RATE" - peer is overloaded, reduce polling freq interval = poll_interval(0); - bb_error_msg("reply from %s: not synced, next query in %us", p->p_dotted, interval); - goto set_next_and_close_sock; + bb_error_msg("reply from %s: peer is unsynced, next query in %us", p->p_dotted, interval); + goto set_next_and_ret; } // /* Verify valid root distance */ @@ -1794,16 +1813,8 @@ recv_and_process_peer_pkt(peer_t *p) /* Decide when to send new query for this peer */ interval = poll_interval(0); - set_next_and_close_sock: + set_next_and_ret: set_next(p, interval); - /* We do not expect any more packets from this peer for now. - * Closing the socket informs kernel about it. - * We open a new socket when we send a new query. - */ - close(p->p_fd); - p->p_fd = -1; - bail: - return; } #if ENABLE_FEATURE_NTPD_SERVER @@ -1840,10 +1851,10 @@ recv_and_process_client_pkt(void /*int fd*/) /* Build a reply packet */ memset(&msg, 0, sizeof(msg)); - msg.m_status = G.stratum < MAXSTRAT ? G.ntp_status : LI_ALARM; + msg.m_status = G.stratum < MAXSTRAT ? (G.ntp_status & LI_MASK) : LI_ALARM; msg.m_status |= (query_status & VERSION_MASK); msg.m_status |= ((query_status & MODE_MASK) == MODE_CLIENT) ? - MODE_SERVER : MODE_SYM_PAS; + MODE_SERVER : MODE_SYM_PAS; msg.m_stratum = G.stratum; msg.m_ppoll = G.poll_exp; msg.m_precision_exp = G_precision_exp; @@ -2069,6 +2080,8 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) */ cnt = G.peer_cnt * (INITIAL_SAMPLES + 1); + write_pidfile(CONFIG_PID_FILE_PATH "/ntpd.pid"); + while (!bb_got_signal) { llist_t *item; unsigned i, j; @@ -2184,6 +2197,7 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv) } } /* while (!bb_got_signal) */ + remove_pidfile(CONFIG_PID_FILE_PATH "/ntpd.pid"); kill_myself_with_sig(bb_got_signal); } @@ -2314,14 +2328,13 @@ set_freq(double freq) /* frequency update */ if (pps_enable) { if (!(pll_status & STA_PPSTIME)) report_event(EVNT_KERN, - NULL, "PPS enabled"); + NULL, "PPS enabled"); ntv.status |= STA_PPSTIME | STA_PPSFREQ; } else { if (pll_status & STA_PPSTIME) report_event(EVNT_KERN, - NULL, "PPS disabled"); - ntv.status &= ~(STA_PPSTIME | - STA_PPSFREQ); + NULL, "PPS disabled"); + ntv.status &= ~(STA_PPSTIME | STA_PPSFREQ); } if (sys_leap == LEAP_ADDSECOND) ntv.status |= STA_INS; @@ -2337,7 +2350,7 @@ set_freq(double freq) /* frequency update */ if (ntp_adjtime(&ntv) == TIME_ERROR) { if (!(ntv.status & STA_PPSSIGNAL)) report_event(EVNT_KERN, NULL, - "PPS no signal"); + "PPS no signal"); } pll_status = ntv.status; #ifdef STA_NANO diff --git a/release/src/router/busybox/networking/ntpd_simple.c b/release/src/router/busybox/networking/ntpd_simple.c index 4ad44e4f35..55bded8ffe 100644 --- a/release/src/router/busybox/networking/ntpd_simple.c +++ b/release/src/router/busybox/networking/ntpd_simple.c @@ -7,6 +7,7 @@ */ #include "libbb.h" #include /* For IPTOS_LOWDELAY definition */ +#include /* setpriority */ #ifndef IPTOS_LOWDELAY # define IPTOS_LOWDELAY 0x10 #endif @@ -709,7 +710,7 @@ recv_and_process_client_pkt(void /*int fd*/) msg.m_status = G.synced ? G.leap : LI_ALARM; msg.m_status |= (query_status & VERSION_MASK); msg.m_status |= ((query_status & MODE_MASK) == MODE_CLIENT) ? - MODE_SERVER : MODE_SYM_PAS; + MODE_SERVER : MODE_SYM_PAS; msg.m_stratum = G.stratum; msg.m_ppoll = query_ppoll; msg.m_precision_exp = G_precision_exp; diff --git a/release/src/router/busybox/networking/ping.c b/release/src/router/busybox/networking/ping.c index b8a438ba82..3df67f5c39 100644 --- a/release/src/router/busybox/networking/ping.c +++ b/release/src/router/busybox/networking/ping.c @@ -724,7 +724,7 @@ static void ping6(len_and_sockaddr *lsa) ICMP6_FILTER_SETPASSALL(&filt); } if (setsockopt(pingsock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt, - sizeof(filt)) < 0) + sizeof(filt)) < 0) bb_error_msg_and_die("setsockopt(ICMP6_FILTER)"); } #endif /*ICMP6_FILTER*/ diff --git a/release/src/router/busybox/networking/route.c b/release/src/router/busybox/networking/route.c index b7b5a02e69..4235ea72cd 100644 --- a/release/src/router/busybox/networking/route.c +++ b/release/src/router/busybox/networking/route.c @@ -409,7 +409,7 @@ static NOINLINE void INET6_setroute(int action, char **args) bb_error_msg_and_die("resolving %s", args_m1); } memcpy(&rt.rtmsg_gateway, sa6.sin6_addr.s6_addr, - sizeof(struct in6_addr)); + sizeof(struct in6_addr)); rt.rtmsg_flags |= RTF_GATEWAY; continue; } @@ -435,7 +435,7 @@ static NOINLINE void INET6_setroute(int action, char **args) struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); strncpy_IFNAMSIZ(ifr.ifr_name, devname); - xioctl(skfd, SIOGIFINDEX, &ifr); + xioctl(skfd, SIOCGIFINDEX, &ifr); rt.rtmsg_ifindex = ifr.ifr_ifindex; } @@ -498,17 +498,17 @@ void FAST_FUNC bb_displayroutes(int noresolve, int netstatfmt) FILE *fp = xfopen_for_read("/proc/net/route"); printf("Kernel IP routing table\n" - "Destination Gateway Genmask Flags %s Iface\n", + "Destination Gateway Genmask Flags %s Iface\n", netstatfmt ? " MSS Window irtt" : "Metric Ref Use"); if (fscanf(fp, "%*[^\n]\n") < 0) { /* Skip the first line. */ - goto ERROR; /* Empty or missing line, or read error. */ + goto ERROR; /* Empty or missing line, or read error. */ } while (1) { int r; r = fscanf(fp, "%63s%lx%lx%X%d%d%d%lx%d%d%d\n", - devname, &d, &g, &flgs, &ref, &use, &metric, &m, - &mtu, &win, &ir); + devname, &d, &g, &flgs, &ref, &use, &metric, &m, + &mtu, &win, &ir); if (r != 11) { if ((r < 0) && feof(fp)) { /* EOF with no (nonspace) chars read. */ break; @@ -567,8 +567,8 @@ static void INET6_displayroutes(void) FILE *fp = xfopen_for_read("/proc/net/ipv6_route"); printf("Kernel IPv6 routing table\n%-44s%-40s" - "Flags Metric Ref Use Iface\n", - "Destination", "Next Hop"); + "Flags Metric Ref Use Iface\n", + "Destination", "Next Hop"); while (1) { int r; @@ -618,8 +618,8 @@ static void INET6_displayroutes(void) (struct sockaddr *) &snaddr6.sin6_addr); snaddr6.sin6_family = AF_INET6; naddr6 = INET6_rresolve((struct sockaddr_in6 *) &snaddr6, - 0x0fff /* Apparently, upstream never resolves. */ - ); + 0x0fff /* Apparently, upstream never resolves. */ + ); if (!r) { /* 1st pass */ snprintf(addr6, sizeof(addr6), "%s/%d", naddr6, prefix_len); diff --git a/release/src/router/busybox/networking/tc.c b/release/src/router/busybox/networking/tc.c index 1574353a5c..f968707a92 100644 --- a/release/src/router/busybox/networking/tc.c +++ b/release/src/router/busybox/networking/tc.c @@ -391,7 +391,7 @@ static int print_class(const struct sockaddr_nl *who UNUSED_PARAM, printf("root "); else if (msg->tcm_parent) { classid = print_tc_classid(filter_qdisc ? - TC_H_MIN(msg->tcm_parent) : msg->tcm_parent); + TC_H_MIN(msg->tcm_parent) : msg->tcm_parent); printf("parent %s ", classid); if (ENABLE_FEATURE_CLEAN_UP) free(classid); @@ -526,7 +526,8 @@ int tc_main(int argc UNUSED_PARAM, char **argv) duparg(*argv, "handle"); /* reject LONG_MIN || LONG_MAX */ /* TODO: for fw - if ((slash = strchr(handle, '/')) != NULL) + slash = strchr(handle, '/'); + if (slash != NULL) *slash = '\0'; */ msg.tcm_handle = get_u32(*argv, "handle"); diff --git a/release/src/router/busybox/networking/telnet.c b/release/src/router/busybox/networking/telnet.c index e8e51dce4a..58a691916e 100644 --- a/release/src/router/busybox/networking/telnet.c +++ b/release/src/router/busybox/networking/telnet.c @@ -186,40 +186,35 @@ static void con_escape(void) static void handle_net_output(int len) { - /* here we could do smart tricks how to handle 0xFF:s in output - * stream like writing twice every sequence of FF:s (thus doing - * many write()s. But I think interactive telnet application does - * not need to be 100% 8-bit clean, so changing every 0xff:s to - * 0x7f:s - * - * 2002-mar-21, Przemyslaw Czerpak (druzus@polbox.com) - * I don't agree. - * first - I cannot use programs like sz/rz - * second - the 0x0D is sent as one character and if the next - * char is 0x0A then it's eaten by a server side. - * third - why do you have to make 'many write()s'? - * I don't understand. - * So I implemented it. It's really useful for me. I hope that - * other people will find it interesting too. - */ byte outbuf[2 * DATABUFSIZE]; - byte *p = (byte*)G.buf; - int j = 0; + byte *dst = outbuf; + byte *src = (byte*)G.buf; + byte *end = src + len; - for (; len > 0; len--, p++) { - byte c = *p; + while (src < end) { + byte c = *src++; if (c == 0x1d) { con_escape(); return; } - outbuf[j++] = c; + *dst = c; if (c == IAC) - outbuf[j++] = c; /* IAC -> IAC IAC */ - else if (c == '\r') - outbuf[j++] = '\0'; /* CR -> CR NUL */ + *++dst = c; /* IAC -> IAC IAC */ + else + if (c == '\r' || c == '\n') { + /* Enter key sends '\r' in raw mode and '\n' in cooked one. + * + * See RFC 1123 3.3.1 Telnet End-of-Line Convention. + * Using CR LF instead of other allowed possibilities + * like CR NUL - easier to talk to HTTP/SMTP servers. + */ + *dst = '\r'; /* Enter -> CR LF */ + *++dst = '\n'; + } + dst++; } - if (j > 0) - full_write(netfd, outbuf, j); + if (dst - outbuf != 0) + full_write(netfd, outbuf, dst - outbuf); } static void handle_net_input(int len) @@ -398,20 +393,20 @@ static void put_iac_naws(byte c, int x, int y) } #endif -static char const escapecharis[] ALIGN1 = "\r\nEscape character is "; - static void setConMode(void) { if (G.telflags & UF_ECHO) { if (G.charmode == CHM_TRY) { G.charmode = CHM_ON; - printf("\r\nEntering character mode%s'^]'.\r\n", escapecharis); + printf("\r\nEntering %s mode" + "\r\nEscape character is '^%c'.\r\n", "character", ']'); rawmode(); } } else { if (G.charmode != CHM_OFF) { G.charmode = CHM_OFF; - printf("\r\nEntering line mode%s'^C'.\r\n", escapecharis); + printf("\r\nEntering %s mode" + "\r\nEscape character is '^%c'.\r\n", "line", 'C'); cookmode(); } } diff --git a/release/src/router/busybox/networking/telnetd.c b/release/src/router/busybox/networking/telnetd.c index 0bc595ab9c..615533d84f 100644 --- a/release/src/router/busybox/networking/telnetd.c +++ b/release/src/router/busybox/networking/telnetd.c @@ -125,6 +125,7 @@ remove_iacs(struct tsession *ts, int *pnum_totty) /* We map \r\n ==> \r for pragmatic reasons. * Many client implementations send \r\n when * the user hits the CarriageReturn key. + * See RFC 1123 3.3.1 Telnet End-of-Line Convention. */ if (c == '\r' && ptr < end && (*ptr == '\n' || *ptr == '\0')) ptr++; diff --git a/release/src/router/busybox/networking/tftp.c b/release/src/router/busybox/networking/tftp.c index ce48a1edd5..630fdaf9a8 100644 --- a/release/src/router/busybox/networking/tftp.c +++ b/release/src/router/busybox/networking/tftp.c @@ -116,7 +116,7 @@ enum { struct globals { /* u16 TFTP_ERROR; u16 reason; both network-endian, then error text: */ uint8_t error_pkt[4 + 32]; - char *user_opt; + struct passwd *pw; /* used in tftpd_main(), a bit big for stack: */ char block_buf[TFTP_BLKSIZE_DEFAULT]; #if ENABLE_FEATURE_TFTP_PROGRESS_BAR @@ -130,13 +130,10 @@ struct globals { struct BUG_G_too_big { char BUG_G_too_big[sizeof(G) <= COMMON_BUFSIZE ? 1 : -1]; }; -#define block_buf (G.block_buf ) -#define user_opt (G.user_opt ) -#define error_pkt (G.error_pkt ) #define INIT_G() do { } while (0) -#define error_pkt_reason (error_pkt[3]) -#define error_pkt_str (error_pkt + 4) +#define G_error_pkt_reason (G.error_pkt[3]) +#define G_error_pkt_str ((char*)(G.error_pkt + 4)) #if ENABLE_FEATURE_TFTP_PROGRESS_BAR static void tftp_progress_update(void) @@ -272,12 +269,11 @@ static int tftp_protocol( xconnect(socket_fd, &peer_lsa->u.sa, peer_lsa->len); /* Is there an error already? Send pkt and bail out */ - if (error_pkt_reason || error_pkt_str[0]) + if (G_error_pkt_reason || G_error_pkt_str[0]) goto send_err_pkt; - if (user_opt) { - struct passwd *pw = xgetpwnam(user_opt); - change_identity(pw); /* initgroups, setgid, setuid */ + if (G.pw) { + change_identity(G.pw); /* initgroups, setgid, setuid */ } } @@ -329,8 +325,8 @@ static int tftp_protocol( /* Open file (must be after changing user) */ local_fd = open(local_file, open_mode, 0666); if (local_fd < 0) { - error_pkt_reason = ERR_NOFILE; - strcpy((char*)error_pkt_str, "can't open file"); + G_error_pkt_reason = ERR_NOFILE; + strcpy(G_error_pkt_str, "can't open file"); goto send_err_pkt; } /* gcc 4.3.1 would NOT optimize it out as it should! */ @@ -575,7 +571,7 @@ static int tftp_protocol( if (res) { blksize = tftp_blksize_check(res, blksize); if (blksize < 0) { - error_pkt_reason = ERR_BAD_OPT; + G_error_pkt_reason = ERR_BAD_OPT; goto send_err_pkt; } io_bufsize = blksize + 4; @@ -614,8 +610,8 @@ static int tftp_protocol( if (recv_blk == block_nr) { int sz = full_write(local_fd, &rbuf[4], len - 4); if (sz != len - 4) { - strcpy((char*)error_pkt_str, bb_msg_write_error); - error_pkt_reason = ERR_WRITE; + strcpy(G_error_pkt_str, bb_msg_write_error); + G_error_pkt_reason = ERR_WRITE; goto send_err_pkt; } if (sz != blksize) { @@ -664,12 +660,12 @@ static int tftp_protocol( return finished == 0; /* returns 1 on failure */ send_read_err_pkt: - strcpy((char*)error_pkt_str, bb_msg_read_error); + strcpy(G_error_pkt_str, bb_msg_read_error); send_err_pkt: - if (error_pkt_str[0]) - bb_error_msg("%s", (char*)error_pkt_str); - error_pkt[1] = TFTP_ERROR; - xsendto(socket_fd, error_pkt, 4 + 1 + strlen((char*)error_pkt_str), + if (G_error_pkt_str[0]) + bb_error_msg("%s", G_error_pkt_str); + G.error_pkt[1] = TFTP_ERROR; + xsendto(socket_fd, G.error_pkt, 4 + 1 + strlen(G_error_pkt_str), &peer_lsa->u.sa, peer_lsa->len); return EXIT_FAILURE; #undef remote_file @@ -761,7 +757,7 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv) { len_and_sockaddr *our_lsa; len_and_sockaddr *peer_lsa; - char *local_file, *mode; + char *local_file, *mode, *user_opt; const char *error_msg; int opt, result, opcode; IF_FEATURE_TFTP_BLOCKSIZE(int blksize = TFTP_BLKSIZE_DEFAULT;) @@ -789,18 +785,22 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv) openlog(applet_name, LOG_PID, LOG_DAEMON); logmode = LOGMODE_SYSLOG; } + if (opt & TFTPD_OPT_u) { + /* Must be before xchroot */ + G.pw = xgetpwnam(user_opt); + } if (argv[0]) { xchroot(argv[0]); } - result = recv_from_to(STDIN_FILENO, block_buf, sizeof(block_buf), + result = recv_from_to(STDIN_FILENO, G.block_buf, sizeof(G.block_buf), 0 /* flags */, &peer_lsa->u.sa, &our_lsa->u.sa, our_lsa->len); error_msg = "malformed packet"; - opcode = ntohs(*(uint16_t*)block_buf); - if (result < 4 || result >= sizeof(block_buf) - || block_buf[result-1] != '\0' + opcode = ntohs(*(uint16_t*)G.block_buf); + if (result < 4 || result >= sizeof(G.block_buf) + || G.block_buf[result-1] != '\0' || (IF_FEATURE_TFTP_PUT(opcode != TFTP_RRQ) /* not download */ IF_GETPUT(&&) IF_FEATURE_TFTP_GET(opcode != TFTP_WRQ) /* not upload */ @@ -808,27 +808,27 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv) ) { goto err; } - local_file = block_buf + 2; + local_file = G.block_buf + 2; if (local_file[0] == '.' || strstr(local_file, "/.")) { error_msg = "dot in file name"; goto err; } mode = local_file + strlen(local_file) + 1; /* RFC 1350 says mode string is case independent */ - if (mode >= block_buf + result || strcasecmp(mode, "octet") != 0) { + if (mode >= G.block_buf + result || strcasecmp(mode, "octet") != 0) { goto err; } # if ENABLE_FEATURE_TFTP_BLOCKSIZE { char *res; char *opt_str = mode + sizeof("octet"); - int opt_len = block_buf + result - opt_str; + int opt_len = G.block_buf + result - opt_str; if (opt_len > 0) { res = tftp_get_option("blksize", opt_str, opt_len); if (res) { blksize = tftp_blksize_check(res, 65564); if (blksize < 0) { - error_pkt_reason = ERR_BAD_OPT; + G_error_pkt_reason = ERR_BAD_OPT; /* will just send error pkt */ goto do_proto; } @@ -846,7 +846,7 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv) if (!ENABLE_FEATURE_TFTP_PUT || opcode == TFTP_WRQ) { if (opt & TFTPD_OPT_r) { /* This would mean "disk full" - not true */ - /*error_pkt_reason = ERR_WRITE;*/ + /*G_error_pkt_reason = ERR_WRITE;*/ error_msg = bb_msg_write_error; goto err; } @@ -855,7 +855,7 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv) IF_GETPUT(option_mask32 |= TFTP_OPT_PUT;) /* will send file's data */ } - /* NB: if error_pkt_str or error_pkt_reason is set up, + /* NB: if G_error_pkt_str or G_error_pkt_reason is set up, * tftp_protocol() just sends one error pkt and returns */ do_proto: @@ -870,7 +870,7 @@ int tftpd_main(int argc UNUSED_PARAM, char **argv) return result; err: - strcpy((char*)error_pkt_str, error_msg); + strcpy(G_error_pkt_str, error_msg); goto do_proto; } diff --git a/release/src/router/busybox/networking/traceroute.c b/release/src/router/busybox/networking/traceroute.c index d197e54101..32e29209e9 100644 --- a/release/src/router/busybox/networking/traceroute.c +++ b/release/src/router/busybox/networking/traceroute.c @@ -290,9 +290,10 @@ #endif -#define OPT_STRING "FIlnrdvxt:i:m:p:q:s:w:z:f:" \ - IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:") \ - "4" IF_TRACEROUTE6("6") +#define OPT_STRING \ + "FIlnrdvxt:i:m:p:q:s:w:z:f:" \ + IF_FEATURE_TRACEROUTE_SOURCE_ROUTE("g:") \ + "4" IF_TRACEROUTE6("6") enum { OPT_DONT_FRAGMNT = (1 << 0), /* F */ OPT_USE_ICMP = (1 << 1) * ENABLE_FEATURE_TRACEROUTE_USE_ICMP, /* I */ @@ -902,15 +903,7 @@ common_traceroute_main(int op, char **argv) #if ENABLE_TRACEROUTE6 if (af == AF_INET6) { xmove_fd(xsocket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6), rcvsock); -# ifdef IPV6_RECVPKTINFO - setsockopt(rcvsock, SOL_IPV6, IPV6_RECVPKTINFO, - &const_int_1, sizeof(const_int_1)); - setsockopt(rcvsock, SOL_IPV6, IPV6_2292PKTINFO, - &const_int_1, sizeof(const_int_1)); -# else - setsockopt(rcvsock, SOL_IPV6, IPV6_PKTINFO, - &const_int_1, sizeof(const_int_1)); -# endif + socket_want_pktinfo(rcvsock); } else #endif { diff --git a/release/src/router/busybox/networking/udhcp/Config.src b/release/src/router/busybox/networking/udhcp/Config.src index 7184ab6150..d52bc54300 100644 --- a/release/src/router/busybox/networking/udhcp/Config.src +++ b/release/src/router/busybox/networking/udhcp/Config.src @@ -74,6 +74,17 @@ config UDHCPC The udhcp client negotiates a lease with the DHCP server and runs a script when a lease is obtained or lost. +config UDHCPC_OLD + bool "udhcp client (udhcpc) - old version - for K24" + default n + select PLATFORM_LINUX + help + udhcpc is a DHCP client geared primarily toward embedded systems, + while striving to be fully functional and RFC compliant. + + The udhcp client negotiates a lease with the DHCP server and + runs a script when a lease is obtained or lost. + config FEATURE_UDHCPC_ARPING bool "Verify that the offered address is free, using ARP ping" default y @@ -113,13 +124,6 @@ config FEATURE_UDHCP_RFC3397 search lists via option 119, specified in RFC 3397, and SIP servers option 120, specified in RFC 3361. -config FEATURE_UDHCP_RFC5969 - bool "Support for RFC5969 IPv6 Rapid Deployment (6RD)" - default y - depends on FEATURE_IPV6 && UDHCPC - help - None. - config FEATURE_UDHCP_8021Q bool "Support for 802.1Q VLAN parameters" default y diff --git a/release/src/router/busybox/networking/udhcp/Kbuild.src b/release/src/router/busybox/networking/udhcp/Kbuild.src index b8767baea4..2ed348812c 100644 --- a/release/src/router/busybox/networking/udhcp/Kbuild.src +++ b/release/src/router/busybox/networking/udhcp/Kbuild.src @@ -10,9 +10,11 @@ lib-y:= INSERT lib-$(CONFIG_UDHCPC) += common.o packet.o signalpipe.o socket.o +lib-$(CONFIG_UDHCPC_OLD) += common_old.o packet.o signalpipe.o socket.o lib-$(CONFIG_UDHCPD) += common.o packet.o signalpipe.o socket.o lib-$(CONFIG_UDHCPC) += dhcpc.o +lib-$(CONFIG_UDHCPC_OLD) += dhcpc_old.o lib-$(CONFIG_UDHCPD) += dhcpd.o arpping.o files.o leases.o static_leases.o lib-$(CONFIG_DUMPLEASES) += dumpleases.o lib-$(CONFIG_DHCPRELAY) += dhcprelay.o diff --git a/release/src/router/busybox/networking/udhcp/common.c b/release/src/router/busybox/networking/udhcp/common.c index a15220d352..c6544b1390 100644 --- a/release/src/router/busybox/networking/udhcp/common.c +++ b/release/src/router/busybox/networking/udhcp/common.c @@ -29,15 +29,16 @@ const struct dhcp_optflag dhcp_optflags[] = { // { OPTION_IP | OPTION_LIST , 0x07 }, /* DHCP_LOG_SERVER */ // { OPTION_IP | OPTION_LIST , 0x08 }, /* DHCP_COOKIE_SERVER */ { OPTION_IP | OPTION_LIST , 0x09 }, /* DHCP_LPR_SERVER */ - { OPTION_STRING | OPTION_REQ, 0x0c }, /* DHCP_HOST_NAME */ + { OPTION_STRING_HOST | OPTION_REQ, 0x0c }, /* DHCP_HOST_NAME */ { OPTION_U16 , 0x0d }, /* DHCP_BOOT_SIZE */ - { OPTION_STRING | OPTION_REQ, 0x0f }, /* DHCP_DOMAIN_NAME */ + { OPTION_STRING_HOST | OPTION_REQ, 0x0f }, /* DHCP_DOMAIN_NAME */ { OPTION_IP , 0x10 }, /* DHCP_SWAP_SERVER */ { OPTION_STRING , 0x11 }, /* DHCP_ROOT_PATH */ { OPTION_U8 , 0x17 }, /* DHCP_IP_TTL */ { OPTION_U16 , 0x1a }, /* DHCP_MTU */ { OPTION_IP | OPTION_REQ, 0x1c }, /* DHCP_BROADCAST */ - { OPTION_STRING , 0x28 }, /* DHCP_NIS_DOMAIN */ + { OPTION_IP_PAIR | OPTION_LIST , 0x21 }, /* DHCP_ROUTES */ + { OPTION_STRING_HOST , 0x28 }, /* DHCP_NIS_DOMAIN */ { OPTION_IP | OPTION_LIST , 0x29 }, /* DHCP_NIS_SERVER */ { OPTION_IP | OPTION_LIST | OPTION_REQ, 0x2a }, /* DHCP_NTP_SERVER */ { OPTION_IP | OPTION_LIST , 0x2c }, /* DHCP_WINS_SERVER */ @@ -45,7 +46,7 @@ const struct dhcp_optflag dhcp_optflags[] = { { OPTION_IP , 0x36 }, /* DHCP_SERVER_ID */ { OPTION_STRING , 0x38 }, /* DHCP_ERR_MESSAGE */ //TODO: must be combined with 'sname' and 'file' handling: - { OPTION_STRING , 0x42 }, /* DHCP_TFTP_SERVER_NAME */ + { OPTION_STRING_HOST , 0x42 }, /* DHCP_TFTP_SERVER_NAME */ { OPTION_STRING , 0x43 }, /* DHCP_BOOT_FILE */ //TODO: not a string, but a set of LASCII strings: // { OPTION_STRING , 0x4D }, /* DHCP_USER_CLASS */ @@ -53,13 +54,13 @@ const struct dhcp_optflag dhcp_optflags[] = { { OPTION_DNS_STRING | OPTION_LIST , 0x77 }, /* DHCP_DOMAIN_SEARCH */ { OPTION_SIP_SERVERS , 0x78 }, /* DHCP_SIP_SERVERS */ #endif - { OPTION_STATIC_ROUTES | OPTION_REQ, 0x79 }, /* DHCP_STATIC_ROUTES */ - { OPTION_IP | OPTION_LIST | OPTION_REQ, 0x21 }, /* DHCP_ROUTES */ - { OPTION_STATIC_ROUTES | OPTION_REQ, 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ -#if ENABLE_FEATURE_UDHCP_RFC5969 - { OPTION_6RD , 0xd4 }, /* DHCP_6RD */ - { OPTION_6RD , 0x96 }, /* DHCP_COMCAST_6RD */ + { OPTION_STATIC_ROUTES | OPTION_LIST , 0x79 }, /* DHCP_STATIC_ROUTES */ +#if ENABLE_FEATURE_UDHCP_8021Q + { OPTION_U16 , 0x84 }, /* DHCP_VLAN_ID */ + { OPTION_U8 , 0x85 }, /* DHCP_VLAN_PRIORITY */ #endif + { OPTION_6RD , 0xd4 }, /* DHCP_6RD */ + { OPTION_STATIC_ROUTES | OPTION_LIST , 0xf9 }, /* DHCP_MS_STATIC_ROUTES */ { OPTION_STRING , 0xfc }, /* DHCP_WPAD */ /* Options below have no match in dhcp_option_strings[], @@ -102,6 +103,7 @@ const char dhcp_option_strings[] ALIGN1 = "ipttl" "\0" /* DHCP_IP_TTL */ "mtu" "\0" /* DHCP_MTU */ "broadcast" "\0" /* DHCP_BROADCAST */ + "routes" "\0" /* DHCP_ROUTES */ "nisdomain" "\0" /* DHCP_NIS_DOMAIN */ "nissrv" "\0" /* DHCP_NIS_SERVER */ "ntpsrv" "\0" /* DHCP_NTP_SERVER */ @@ -118,15 +120,13 @@ const char dhcp_option_strings[] ALIGN1 = // is not handled yet by "string->option" conversion code: "sipsrv" "\0" /* DHCP_SIP_SERVERS */ #endif -// doesn't work in udhcpd.conf since OPTION_STATIC_ROUTES -// is not handled yet by "string->option" conversion code: "staticroutes" "\0"/* DHCP_STATIC_ROUTES */ - "routes" "\0" /* DHCP_ROUTES */ - "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ -#if ENABLE_FEATURE_UDHCP_RFC5969 - "6rd" "\0" /* DHCP_6RD */ - "comcast6rd" "\0" /* DHCP_COMCAST_6RD */ +#if ENABLE_FEATURE_UDHCP_8021Q + "vlanid" "\0" /* DHCP_VLAN_ID */ + "vlanpriority" "\0"/* DHCP_VLAN_PRIORITY */ #endif + "ip6rd" "\0" /* DHCP_6RD */ + "msstaticroutes""\0"/* DHCP_MS_STATIC_ROUTES */ "wpad" "\0" /* DHCP_WPAD */ ; @@ -143,6 +143,7 @@ const uint8_t dhcp_option_lengths[] ALIGN1 = { [OPTION_IP_PAIR] = 8, // [OPTION_BOOLEAN] = 1, [OPTION_STRING] = 1, /* ignored by udhcp_str2optset */ + [OPTION_STRING_HOST] = 1, /* ignored by udhcp_str2optset */ #if ENABLE_FEATURE_UDHCP_RFC3397 [OPTION_DNS_STRING] = 1, /* ignored by both udhcp_str2optset and xmalloc_optname_optval */ [OPTION_SIP_SERVERS] = 1, @@ -154,9 +155,7 @@ const uint8_t dhcp_option_lengths[] ALIGN1 = { [OPTION_S32] = 4, /* Just like OPTION_STRING, we use minimum length here */ [OPTION_STATIC_ROUTES] = 5, -#if ENABLE_FEATURE_UDHCP_RFC5969 - [OPTION_6RD] = 22, -#endif + [OPTION_6RD] = 22, /* ignored by udhcp_str2optset */ }; @@ -334,7 +333,8 @@ int FAST_FUNC udhcp_str2nip(const char *str, void *arg) lsa = host_and_af2sockaddr(str, 0, AF_INET); if (!lsa) return 0; - *(uint32_t*)arg = lsa->u.sin.sin_addr.s_addr; + /* arg maybe unaligned */ + move_to_unaligned32((uint32_t*)arg, lsa->u.sin.sin_addr.s_addr); free(lsa); return 1; } @@ -414,7 +414,9 @@ static NOINLINE void attach_option( /* actually 255 is ok too, but adding a space can overlow it */ existing->data = xrealloc(existing->data, OPT_DATA + 1 + old_len + length); - if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING) { + if ((optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING + || (optflag->flags & OPTION_TYPE_MASK) == OPTION_STRING_HOST + ) { /* add space separator between STRING options in a list */ existing->data[OPT_DATA + old_len] = ' '; old_len++; @@ -431,13 +433,14 @@ static NOINLINE void attach_option( int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg) { struct option_set **opt_list = arg; - char *opt, *val, *endptr; + char *opt, *val; char *str; const struct dhcp_optflag *optflag; struct dhcp_optflag bin_optflag; unsigned optcode; int retval, length; - char buffer[8] ALIGNED(4); + /* IP_PAIR needs 8 bytes, STATIC_ROUTES needs 9 max */ + char buffer[9] ALIGNED(4); uint16_t *result_u16 = (uint16_t *) buffer; uint32_t *result_u32 = (uint32_t *) buffer; @@ -478,6 +481,7 @@ int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg) retval = udhcp_str2nip(val, buffer + 4); break; case OPTION_STRING: + case OPTION_STRING_HOST: #if ENABLE_FEATURE_UDHCP_RFC3397 case OPTION_DNS_STRING: #endif @@ -494,34 +498,53 @@ int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg) // break; // } case OPTION_U8: - buffer[0] = strtoul(val, &endptr, 0); - retval = (endptr[0] == '\0'); + buffer[0] = bb_strtou32(val, NULL, 0); + retval = (errno == 0); break; /* htonX are macros in older libc's, using temp var * in code below for safety */ /* TODO: use bb_strtoX? */ case OPTION_U16: { - unsigned long tmp = strtoul(val, &endptr, 0); + uint32_t tmp = bb_strtou32(val, NULL, 0); *result_u16 = htons(tmp); - retval = (endptr[0] == '\0' /*&& tmp < 0x10000*/); + retval = (errno == 0 /*&& tmp < 0x10000*/); break; } // case OPTION_S16: { -// long tmp = strtol(val, &endptr, 0); +// long tmp = bb_strtoi32(val, NULL, 0); // *result_u16 = htons(tmp); -// retval = (endptr[0] == '\0'); +// retval = (errno == 0); // break; // } case OPTION_U32: { - unsigned long tmp = strtoul(val, &endptr, 0); + uint32_t tmp = bb_strtou32(val, NULL, 0); *result_u32 = htonl(tmp); - retval = (endptr[0] == '\0'); + retval = (errno == 0); break; } case OPTION_S32: { - long tmp = strtol(val, &endptr, 0); + int32_t tmp = bb_strtoi32(val, NULL, 0); *result_u32 = htonl(tmp); - retval = (endptr[0] == '\0'); + retval = (errno == 0); + break; + } + case OPTION_STATIC_ROUTES: { + /* Input: "a.b.c.d/m" */ + /* Output: mask(1 byte),pfx(0-4 bytes),gw(4 bytes) */ + unsigned mask; + char *slash = strchr(val, '/'); + if (slash) { + *slash = '\0'; + retval = udhcp_str2nip(val, buffer + 1); + buffer[0] = mask = bb_strtou(slash + 1, NULL, 10); + val = strtok(NULL, ", \t/-"); + if (!val || mask > 32 || errno) + retval = 0; + if (retval) { + length = ((mask + 7) >> 3) + 5; + retval = udhcp_str2nip(val, buffer + (length - 4)); + } + } break; } case OPTION_BIN: /* handled in attach_option() */ @@ -532,7 +555,7 @@ int FAST_FUNC udhcp_str2optset(const char *const_str, void *arg) } if (retval) attach_option(opt_list, optflag, opt, length); - } while (retval && optflag->flags & OPTION_LIST); + } while (retval && (optflag->flags & OPTION_LIST)); return retval; } diff --git a/release/src/router/busybox/networking/udhcp/common.h b/release/src/router/busybox/networking/udhcp/common.h index 331ef42421..d02c682e49 100644 --- a/release/src/router/busybox/networking/udhcp/common.h +++ b/release/src/router/busybox/networking/udhcp/common.h @@ -1,4 +1,4 @@ -/* vi: set sw=4 ts=4: */ + /* vi: set sw=4 ts=4: */ /* * Russ Dill September 2001 * Rewritten by Vladimir Oleynik (C) 2003 @@ -14,7 +14,7 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN -extern const uint8_t MAC_BCAST_ADDR[6]; /* six all-ones */ +extern const uint8_t MAC_BCAST_ADDR[6] ALIGN2; /* six all-ones */ /*** DHCP packet ***/ @@ -93,13 +93,11 @@ enum { OPTION_S32, OPTION_BIN, OPTION_STATIC_ROUTES, + OPTION_6RD, #if ENABLE_FEATURE_UDHCP_RFC3397 OPTION_DNS_STRING, /* RFC1035 compressed domain name list */ OPTION_SIP_SERVERS, #endif -#if ENABLE_FEATURE_UDHCP_RFC5969 - OPTION_6RD, -#endif OPTION_TYPE_MASK = 0x0f, /* Client requests this option by default */ @@ -111,7 +109,7 @@ enum { /* DHCP option codes (partial list). See RFC 2132 and * http://www.iana.org/assignments/bootp-dhcp-parameters/ * Commented out options are handled by common option machinery, - * uncommented ones have spacial cases (grep for them to see). + * uncommented ones have special cases (grep for them to see). */ #define DHCP_PADDING 0x00 #define DHCP_SUBNET 0x01 @@ -153,9 +151,9 @@ enum { //#define DHCP_DOMAIN_SEARCH 0x77 /* RFC 3397. set of ASCIZ string, DNS-style compressed */ //#define DHCP_SIP_SERVERS 0x78 /* RFC 3361. flag byte, then: 0: domain names, 1: IP addrs */ //#define DHCP_STATIC_ROUTES 0x79 /* RFC 3442. (mask,ip,router) tuples */ +#define DHCP_VLAN_ID 0x84 /* 802.1P VLAN ID */ +#define DHCP_VLAN_PRIORITY 0x85 /* 802.1Q VLAN priority */ //#define DHCP_MS_STATIC_ROUTES 0xf9 /* Microsoft's pre-RFC 3442 code for 0x79? */ -//#define DHCP_6RD 0xd4 /* RFC 5969 6RD option */ -//#define DHCP_COMCAST_6RD 0x96 /* Comcast ISP RFC 5969 compatible 6RD option */ //#define DHCP_WPAD 0xfc /* MSIE's Web Proxy Autodiscovery Protocol */ #define DHCP_END 0xff @@ -191,8 +189,8 @@ struct option_set { }; extern const struct dhcp_optflag dhcp_optflags[]; -extern const char dhcp_option_strings[]; -extern const uint8_t dhcp_option_lengths[]; +extern const char dhcp_option_strings[] ALIGN1; +extern const uint8_t dhcp_option_lengths[] ALIGN1; unsigned FAST_FUNC udhcp_option_idx(const char *name); @@ -316,7 +314,7 @@ int arpping(uint32_t test_nip, const char *interface) FAST_FUNC; /* note: ip is a pointer to an IPv6 in network order, possibly misaliged */ -int sprint_nip6(char *dest, /* const char *pre, */ const uint8_t *ip) FAST_FUNC; +int sprint_nip6(char *dest, /*const char *pre,*/ const uint8_t *ip) FAST_FUNC; POP_SAVED_FUNCTION_VISIBILITY diff --git a/release/src/router/busybox/networking/udhcp/common.c b/release/src/router/busybox/networking/udhcp/common_old.c similarity index 100% copy from release/src/router/busybox/networking/udhcp/common.c copy to release/src/router/busybox/networking/udhcp/common_old.c diff --git a/release/src/router/busybox/networking/udhcp/common.h b/release/src/router/busybox/networking/udhcp/common_old.h similarity index 100% copy from release/src/router/busybox/networking/udhcp/common.h copy to release/src/router/busybox/networking/udhcp/common_old.h diff --git a/release/src/router/busybox/networking/udhcp/d6_dhcpc.c b/release/src/router/busybox/networking/udhcp/d6_dhcpc.c index a792a9dcab..c44220bf94 100644 --- a/release/src/router/busybox/networking/udhcp/d6_dhcpc.c +++ b/release/src/router/busybox/networking/udhcp/d6_dhcpc.c @@ -12,10 +12,11 @@ */ //config:config UDHCPC6 -//config: bool "udhcp client for DHCPv6 (udhcpc6)" -//config: default n # not yet ready -//config: help -//config: udhcpc6 is a DHCPv6 client +//config: bool "udhcp client for DHCPv6 (udhcpc6)" +//config: default n # not yet ready +//config: depends on FEATURE_IPV6 +//config: help +//config: udhcpc6 is a DHCPv6 client //applet:IF_UDHCPC6(APPLET(udhcpc6, BB_DIR_USR_BIN, BB_SUID_DROP)) @@ -964,8 +965,6 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) SERVER_PORT = CLIENT_PORT - 1; } #endif - if (opt & OPT_o) - client_config.no_default_options = 1; while (list_O) { char *optstr = llist_pop(&list_O); unsigned n = bb_strtou(optstr, NULL, 0); @@ -975,6 +974,16 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) } client_config.opt_mask[n >> 3] |= 1 << (n & 7); } + if (!(opt & OPT_o)) { + /* + unsigned i, n; + for (i = 0; (n = dhcp_optflags[i].code) != 0; i++) { + if (dhcp_optflags[i].flags & OPTION_REQ) { + client_config.opt_mask[n >> 3] |= 1 << (n & 7); + } + } + */ + } while (list_x) { char *optstr = llist_pop(&list_x); char *colon = strchr(optstr, ':'); @@ -1065,8 +1074,8 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) retval = 0; /* If we already timed out, fall through with retval = 0, else... */ if ((int)tv.tv_sec > 0) { + log1("Waiting on select %u seconds", (int)tv.tv_sec); timestamp_before_wait = (unsigned)monotonic_sec(); - log1("Waiting on select..."); retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); if (retval < 0) { /* EINTR? A signal was caught, don't panic */ @@ -1102,7 +1111,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) switch (state) { case INIT_SELECTING: - if (packet_num < discover_retries) { + if (!discover_retries || packet_num < discover_retries) { if (packet_num == 0) xid = random_xid(); /* multicast */ @@ -1131,7 +1140,7 @@ int udhcpc6_main(int argc UNUSED_PARAM, char **argv) packet_num = 0; continue; case REQUESTING: - if (packet_num < discover_retries) { + if (!discover_retries || packet_num < discover_retries) { /* send multicast select packet */ send_d6_select(xid); timeout = discover_timeout; diff --git a/release/src/router/busybox/networking/udhcp/dhcpc.c b/release/src/router/busybox/networking/udhcp/dhcpc.c index d7b7862e78..bb06d02081 100644 --- a/release/src/router/busybox/networking/udhcp/dhcpc.c +++ b/release/src/router/busybox/networking/udhcp/dhcpc.c @@ -26,17 +26,16 @@ #include "dhcpc.h" #include -#if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined(_NEWLIB_VERSION) -# include -# include -#else +/*#if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined(_NEWLIB_VERSION) +# include +# include +#else */ # include # include -#endif +/*#endif*/ #include -/* struct client_config_t client_config is in bb_common_bufsiz1 */ - +/* "struct client_config_t client_config" is in bb_common_bufsiz1 */ #if ENABLE_LONG_OPTS static const char udhcpc_longopts[] ALIGN1 = @@ -107,10 +106,9 @@ static const uint8_t len_of_option_as_string[] = { [OPTION_IP ] = sizeof("255.255.255.255 "), [OPTION_IP_PAIR ] = sizeof("255.255.255.255 ") * 2, [OPTION_STATIC_ROUTES ] = sizeof("255.255.255.255/32 255.255.255.255 "), -#if ENABLE_FEATURE_UDHCP_RFC5969 [OPTION_6RD ] = sizeof("32 128 FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF 255.255.255.255 "), -#endif [OPTION_STRING ] = 1, + [OPTION_STRING_HOST ] = 1, #if ENABLE_FEATURE_UDHCP_RFC3397 [OPTION_DNS_STRING ] = 1, /* unused */ /* Hmmm, this severely overestimates size if SIP_SERVERS option @@ -145,6 +143,63 @@ static int mton(uint32_t mask) return i; } +/* Check if a given label represents a valid DNS label + * Return pointer to the first character after the label upon success, + * NULL otherwise. + * See RFC1035, 2.3.1 + */ +/* We don't need to be particularly anal. For example, allowing _, hyphen + * at the end, or leading and trailing dots would be ok, since it + * can't be used for attacks. (Leading hyphen can be, if someone uses + * cmd "$hostname" + * in the script: then hostname may be treated as an option) + */ +static const char *valid_domain_label(const char *label) +{ + unsigned char ch; + unsigned pos = 0; + + for (;;) { + ch = *label; + if ((ch|0x20) < 'a' || (ch|0x20) > 'z') { + if (pos == 0) { + /* label must begin with letter */ + return NULL; + } + if (ch < '0' || ch > '9') { + if (ch == '\0' || ch == '.') + return label; + /* DNS allows only '-', but we are more permissive */ + if (ch != '-' && ch != '_') + return NULL; + } + } + label++; + pos++; + //Do we want this? + //if (pos > 63) /* NS_MAXLABEL; labels must be 63 chars or less */ + // return NULL; + } +} + +/* Check if a given name represents a valid DNS name */ +/* See RFC1035, 2.3.1 */ +static int good_hostname(const char *name) +{ + //const char *start = name; + + for (;;) { + name = valid_domain_label(name); + if (!name) + return 0; + if (!name[0]) + return 1; + //Do we want this? + //return ((name - start) < 1025); /* NS_MAXDNAME */ + name++; + } +} + /* Create "opt_name=opt_value" string */ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_optflag *optflag, const char *opt_name) { @@ -152,27 +207,25 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ int len, type, optlen; char *dest, *ret; - /* option points to OPT_DATA, need to go back and get OPT_LEN */ - len = option[OPT_LEN - OPT_DATA]; + /* option points to OPT_DATA, need to go back to get OPT_LEN */ + len = option[-OPT_DATA + OPT_LEN]; type = optflag->flags & OPTION_TYPE_MASK; optlen = dhcp_option_lengths[type]; - upper_length = len_of_option_as_string[type] * ((unsigned)len / (unsigned)optlen); + upper_length = len_of_option_as_string[type] + * ((unsigned)(len + optlen - 1) / (unsigned)optlen); dest = ret = xmalloc(upper_length + strlen(opt_name) + 2); dest += sprintf(ret, "%s=", opt_name); while (len >= optlen) { - unsigned ip_ofs = 0; - switch (type) { + case OPTION_IP: case OPTION_IP_PAIR: dest += sprint_nip(dest, "", option); - *dest++ = '/'; - ip_ofs = 4; - /* fall through */ - case OPTION_IP: - dest += sprint_nip(dest, "", option + ip_ofs); + if (type == OPTION_IP) + break; + dest += sprint_nip(dest, "/", option + 4); break; // case OPTION_BOOLEAN: // dest += sprintf(dest, *option ? "yes" : "no"); @@ -194,10 +247,17 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ dest += sprintf(dest, type == OPTION_U32 ? "%lu" : "%ld", (unsigned long) ntohl(val_u32)); break; } + /* Note: options which use 'return' instead of 'break' + * (for example, OPTION_STRING) skip the code which handles + * the case of list of options. + */ case OPTION_STRING: + case OPTION_STRING_HOST: memcpy(dest, option, len); dest[len] = '\0'; - return ret; /* Short circuit this case */ + if (type == OPTION_STRING_HOST && !good_hostname(dest)) + safe_strncpy(dest, "bad", len); + return ret; case OPTION_STATIC_ROUTES: { /* Option binary format: * mask [one byte, 0..32] @@ -242,6 +302,53 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ return ret; } + case OPTION_6RD: + /* Option binary format (see RFC 5969): + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | OPTION_6RD | option-length | IPv4MaskLen | 6rdPrefixLen | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | 6rdPrefix | + * ... (16 octets) ... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * ... 6rdBRIPv4Address(es) ... + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * We convert it to a string + * "IPv4MaskLen 6rdPrefixLen 6rdPrefix 6rdBRIPv4Address..." + * + * Sanity check: ensure that our length is at least 22 bytes, that + * IPv4MaskLen <= 32, + * 6rdPrefixLen <= 128, + * 6rdPrefixLen + (32 - IPv4MaskLen) <= 128 + * (2nd condition need no check - it follows from 1st and 3rd). + * Else, return envvar with empty value ("optname=") + */ + if (len >= (1 + 1 + 16 + 4) + && option[0] <= 32 + && (option[1] + 32 - option[0]) <= 128 + ) { + /* IPv4MaskLen */ + dest += sprintf(dest, "%u ", *option++); + /* 6rdPrefixLen */ + dest += sprintf(dest, "%u ", *option++); + /* 6rdPrefix */ + dest += sprint_nip6(dest, /* "", */ option); + option += 16; + len -= 1 + 1 + 16 + 4; + /* "+ 4" above corresponds to the length of IPv4 addr + * we consume in the loop below */ + while (1) { + /* 6rdBRIPv4Address(es) */ + dest += sprint_nip(dest, " ", option); + option += 4; + len -= 4; /* do we have yet another 4+ bytes? */ + if (len < 0) + break; /* no */ + } + } + + return ret; #if ENABLE_FEATURE_UDHCP_RFC3397 case OPTION_DNS_STRING: /* unpack option into dest; use ret for prefix (i.e., "optname=") */ @@ -280,82 +387,22 @@ static NOINLINE char *xmalloc_optname_optval(uint8_t *option, const struct dhcp_ } return ret; #endif -#if ENABLE_FEATURE_UDHCP_RFC5969 - case OPTION_6RD: - /* Option binary format: - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | OPTION_6RD | option-length | IPv4MaskLen | 6rdPrefixLen | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | | - * | 6rdPrefix | - * | (16 octets) | - * | | - * | | - * | | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | 6rdBRIPv4Address(es) | - * . . - * . . - * . . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * - * We convert it to a string "IPv4MaskLen 6rdPrefixLen 6rdPrefix 6rdBRIPv4Address" - */ - - /* Sanity check: ensure that our length is at least 22 bytes, that - * IPv4MaskLen is <= 32, 6rdPrefixLen <= 128 and that the sum of - * (32 - IPv4MaskLen) + 6rdPrefixLen is less than or equal to 128. - * If any of these requirements is not fulfilled, return with empty - * value. - */ - if ((len >= 22) && (*option <= 32) && (*(option+1) <= 128) && - (((32 - *option) + *(option+1)) <= 128)) - { - /* IPv4MaskLen */ - dest += sprintf(dest, "%u ", *option++); - len--; - - /* 6rdPrefixLen */ - dest += sprintf(dest, "%u ", *option++); - len--; - - /* 6rdPrefix */ - dest += sprint_nip6(dest, /* "", */ option); - option += 16; - len -= 16; - - /* 6rdBRIPv4Addresses */ - while (len >= 4) - { - dest += sprint_nip(dest, " ", option); - option += 4; - len -= 4; - - /* the code to determine the option size fails to work with - * lengths that are not a multiple of the minimum length, - * adding all advertised 6rdBRIPv4Addresses here would - * overflow the destination buffer, therefore skip the rest - * for now - */ - break; - } - } - - return ret; -#endif } /* switch */ + + /* If we are here, try to format any remaining data + * in the option as another, similarly-formatted option + */ option += optlen; len -= optlen; // TODO: it can be a list only if (optflag->flags & OPTION_LIST). // Should we bail out/warn if we see multi-ip option which is // not allowed to be such (for example, DHCP_BROADCAST)? - - if (len <= 0 /* || !(optflag->flags & OPTION_LIST) */) + if (len < optlen /* || !(optflag->flags & OPTION_LIST) */) break; *dest++ = ' '; *dest = '\0'; - } + } /* while */ + return ret; } @@ -369,6 +416,14 @@ static char **fill_envp(struct dhcp_packet *packet) uint8_t *temp; uint8_t overload = 0; +#define BITMAP unsigned +#define BBITS (sizeof(BITMAP) * 8) +#define BMASK(i) (1 << (i & (sizeof(BITMAP) * 8 - 1))) +#define FOUND_OPTS(i) (found_opts[(unsigned)i / BBITS]) + BITMAP found_opts[256 / BBITS]; + + memset(found_opts, 0, sizeof(found_opts)); + /* We need 6 elements for: * "interface=IFACE" * "ip=N.N.N.N" from packet->yiaddr @@ -380,18 +435,22 @@ static char **fill_envp(struct dhcp_packet *packet) envc = 6; /* +1 element for each option, +2 for subnet option: */ if (packet) { - for (i = 0; dhcp_optflags[i].code; i++) { - if (udhcp_get_option(packet, dhcp_optflags[i].code)) { - if (dhcp_optflags[i].code == DHCP_SUBNET) - envc++; /* for mton */ + /* note: do not search for "pad" (0) and "end" (255) options */ +//TODO: change logic to scan packet _once_ + for (i = 1; i < 255; i++) { + temp = udhcp_get_option(packet, i); + if (temp) { + if (i == DHCP_OPTION_OVERLOAD) + overload = *temp; + else if (i == DHCP_SUBNET) + envc++; /* for $mask */ envc++; + /*if (i != DHCP_MESSAGE_TYPE)*/ + FOUND_OPTS(i) |= BMASK(i); } } - temp = udhcp_get_option(packet, DHCP_OPTION_OVERLOAD); - if (temp) - overload = *temp; } - curr = envp = xzalloc(sizeof(char *) * envc); + curr = envp = xzalloc(sizeof(envp[0]) * envc); *curr = xasprintf("interface=%s", client_config.interface); putenv(*curr++); @@ -399,44 +458,88 @@ static char **fill_envp(struct dhcp_packet *packet) if (!packet) return envp; + /* Export BOOTP fields. Fields we don't (yet?) export: + * uint8_t op; // always BOOTREPLY + * uint8_t htype; // hardware address type. 1 = 10mb ethernet + * uint8_t hlen; // hardware address length + * uint8_t hops; // used by relay agents only + * uint32_t xid; + * uint16_t secs; // elapsed since client began acquisition/renewal + * uint16_t flags; // only one flag so far: bcast. Never set by server + * uint32_t ciaddr; // client IP (usually == yiaddr. can it be different + * // if during renew server wants to give us differn IP?) + * uint32_t gateway_nip; // relay agent IP address + * uint8_t chaddr[16]; // link-layer client hardware address (MAC) + * TODO: export gateway_nip as $giaddr? + */ + /* Most important one: yiaddr as $ip */ *curr = xmalloc(sizeof("ip=255.255.255.255")); sprint_nip(*curr, "ip=", (uint8_t *) &packet->yiaddr); putenv(*curr++); + if (packet->siaddr_nip) { + /* IP address of next server to use in bootstrap */ + *curr = xmalloc(sizeof("siaddr=255.255.255.255")); + sprint_nip(*curr, "siaddr=", (uint8_t *) &packet->siaddr_nip); + putenv(*curr++); + } + if (!(overload & FILE_FIELD) && packet->file[0]) { + /* watch out for invalid packets */ + *curr = xasprintf("boot_file=%."DHCP_PKT_FILE_LEN_STR"s", packet->file); + putenv(*curr++); + } + if (!(overload & SNAME_FIELD) && packet->sname[0]) { + /* watch out for invalid packets */ + *curr = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname); + putenv(*curr++); + } + /* Export known DHCP options */ opt_name = dhcp_option_strings; i = 0; while (*opt_name) { - temp = udhcp_get_option(packet, dhcp_optflags[i].code); - if (!temp) + uint8_t code = dhcp_optflags[i].code; + BITMAP *found_ptr = &FOUND_OPTS(code); + BITMAP found_mask = BMASK(code); + if (!(*found_ptr & found_mask)) goto next; + *found_ptr &= ~found_mask; /* leave only unknown options */ + temp = udhcp_get_option(packet, code); *curr = xmalloc_optname_optval(temp, &dhcp_optflags[i], opt_name); putenv(*curr++); - if (dhcp_optflags[i].code == DHCP_SUBNET) { + if (code == DHCP_SUBNET) { /* Subnet option: make things like "$ip/$mask" possible */ uint32_t subnet; move_from_unaligned32(subnet, temp); - *curr = xasprintf("mask=%d", mton(subnet)); + *curr = xasprintf("mask=%u", mton(subnet)); putenv(*curr++); } next: opt_name += strlen(opt_name) + 1; i++; } - if (packet->siaddr_nip) { - *curr = xmalloc(sizeof("siaddr=255.255.255.255")); - sprint_nip(*curr, "siaddr=", (uint8_t *) &packet->siaddr_nip); - putenv(*curr++); - } - if (!(overload & FILE_FIELD) && packet->file[0]) { - /* watch out for invalid packets */ - *curr = xasprintf("boot_file=%."DHCP_PKT_FILE_LEN_STR"s", packet->file); - putenv(*curr++); - } - if (!(overload & SNAME_FIELD) && packet->sname[0]) { - /* watch out for invalid packets */ - *curr = xasprintf("sname=%."DHCP_PKT_SNAME_LEN_STR"s", packet->sname); - putenv(*curr++); + /* Export unknown options */ + for (i = 0; i < 256;) { + BITMAP bitmap = FOUND_OPTS(i); + if (!bitmap) { + i += BBITS; + continue; + } + if (bitmap & BMASK(i)) { + unsigned len, ofs; + + temp = udhcp_get_option(packet, i); + /* udhcp_get_option returns ptr to data portion, + * need to go back to get len + */ + len = temp[-OPT_DATA + OPT_LEN]; + *curr = xmalloc(sizeof("optNNN=") + 1 + len*2); + ofs = sprintf(*curr, "opt%u=", i); + *bin2hex(*curr + ofs, (void*) temp, len) = '\0'; + putenv(*curr++); + } + i++; } + return envp; } @@ -446,9 +549,6 @@ static void udhcp_run_script(struct dhcp_packet *packet, const char *name) char **envp, **curr; char *argv[3]; - if (client_config.script == NULL) - return; - envp = fill_envp(packet); /* call script */ @@ -496,7 +596,6 @@ static void init_packet(struct dhcp_packet *packet, char type) static void add_client_options(struct dhcp_packet *packet) { - uint8_t c; int i, end, len; len = sizeof(struct ip_udp_dhcp_packet); @@ -509,13 +608,9 @@ static void add_client_options(struct dhcp_packet *packet) * No bounds checking because it goes towards the head of the packet. */ end = udhcp_end_option(packet->options); len = 0; - for (i = 0; (c = dhcp_optflags[i].code) != 0; i++) { - if (( (dhcp_optflags[i].flags & OPTION_REQ) - && !client_config.no_default_options - ) - || (client_config.opt_mask[c >> 3] & (1 << (c & 7))) - ) { - packet->options[end + OPT_DATA + len] = c; + for (i = 1; i < DHCP_END; i++) { + if (client_config.opt_mask[i >> 3] & (1 << (i & 7))) { + packet->options[end + OPT_DATA + len] = i; len++; } } @@ -536,6 +631,10 @@ static void add_client_options(struct dhcp_packet *packet) if ((option_mask32 & OPT_B) && packet->ciaddr == 0) packet->flags |= htons(BROADCAST_FLAG); + /* Request broadcast replies if we have no IP addr */ + if ((option_mask32 & OPT_B) && packet->ciaddr == 0) + packet->flags |= htons(BROADCAST_FLAG); + /* Add -x options if any */ { struct option_set *curr = client_config.options; @@ -548,6 +647,12 @@ static void add_client_options(struct dhcp_packet *packet) // if (client_config.boot_file) // strncpy((char*)packet->file, client_config.boot_file, sizeof(packet->file) - 1); } + + // This will be needed if we remove -V VENDOR_STR in favor of + // -x vendor:VENDOR_STR + //if (!udhcp_find_option(packet.options, DHCP_VENDOR)) + // /* not set, set the default vendor ID */ + // ...add (DHCP_VENDOR, "udhcp "BB_VER) opt... } /* RFC 2131 @@ -694,7 +799,7 @@ static NOINLINE int send_renew(uint32_t xid, uint32_t server, uint32_t ciaddr) #if ENABLE_FEATURE_UDHCPC_ARPING /* Broadcast a DHCP decline message */ /* NOINLINE: limit stack usage in caller */ -static NOINLINE int send_decline(uint32_t xid, uint32_t server, uint32_t requested) +static NOINLINE int send_decline(/*uint32_t xid,*/ uint32_t server, uint32_t requested) { struct dhcp_packet packet; @@ -703,12 +808,14 @@ static NOINLINE int send_decline(uint32_t xid, uint32_t server, uint32_t request */ init_packet(&packet, DHCPDECLINE); +#if 0 /* RFC 2131 says DHCPDECLINE's xid is randomly selected by client, * but in case the server is buggy and wants DHCPDECLINE's xid * to match the xid which started entire handshake, * we use the same xid we used in initial DHCPDISCOVER: */ packet.xid = xid; +#endif /* DHCPDECLINE uses "requested ip", not ciaddr, to store offered IP */ udhcp_add_simple_option(&packet, DHCP_REQUESTED_IP, requested); @@ -745,13 +852,31 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) int bytes; struct ip_udp_dhcp_packet packet; uint16_t check; + unsigned char cmsgbuf[CMSG_LEN(sizeof(struct tpacket_auxdata))]; + struct iovec iov; + struct msghdr msg; + struct cmsghdr *cmsg; - memset(&packet, 0, sizeof(packet)); - bytes = safe_read(fd, &packet, sizeof(packet)); - if (bytes < 0) { - log1("Packet read error, ignoring"); - /* NB: possible down interface, etc. Caller should pause. */ - return bytes; /* returns -1 */ + /* used to use just safe_read(fd, &packet, sizeof(packet)) + * but we need to check for TP_STATUS_CSUMNOTREADY :( + */ + iov.iov_base = &packet; + iov.iov_len = sizeof(packet); + memset(&msg, 0, sizeof(msg)); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = cmsgbuf; + msg.msg_controllen = sizeof(cmsgbuf); + for (;;) { + bytes = recvmsg(fd, &msg, 0); + if (bytes < 0) { + if (errno == EINTR) + continue; + log1("Packet read error, ignoring"); + /* NB: possible down interface, etc. Caller should pause. */ + return bytes; /* returns -1 */ + } + break; } if (bytes < (int) (sizeof(packet.ip) + sizeof(packet.udp))) { @@ -769,7 +894,8 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) bytes = ntohs(packet.ip.tot_len); /* make sure its the right packet for us, and that it passes sanity checks */ - if (packet.ip.protocol != IPPROTO_UDP || packet.ip.version != IPVERSION + if (packet.ip.protocol != IPPROTO_UDP + || packet.ip.version != IPVERSION || packet.ip.ihl != (sizeof(packet.ip) >> 2) || packet.udp.dest != htons(CLIENT_PORT) /* || bytes > (int) sizeof(packet) - can't happen */ @@ -787,6 +913,20 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) return -2; } + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level == SOL_PACKET + && cmsg->cmsg_type == PACKET_AUXDATA + ) { + /* some VMs don't checksum UDP and TCP data + * they send to the same physical machine, + * here we detect this case: + */ + struct tpacket_auxdata *aux = (void *)CMSG_DATA(cmsg); + if (aux->tp_status & TP_STATUS_CSUMNOTREADY) + goto skip_udp_sum_check; + } + } + /* verify UDP checksum. IP header has to be modified for this */ memset(&packet.ip, 0, offsetof(struct iphdr, protocol)); /* ip.xx fields which are not memset: protocol, check, saddr, daddr */ @@ -797,16 +937,19 @@ static NOINLINE int udhcp_recv_raw_packet(struct dhcp_packet *dhcp_pkt, int fd) log1("Packet with bad UDP checksum received, ignoring"); return -2; } + skip_udp_sum_check: - memcpy(dhcp_pkt, &packet.data, bytes - (sizeof(packet.ip) + sizeof(packet.udp))); - - if (dhcp_pkt->cookie != htonl(DHCP_MAGIC)) { + if (packet.data.cookie != htonl(DHCP_MAGIC)) { bb_info_msg("Packet with bad magic, ignoring"); return -2; } - log1("Got valid DHCP packet"); - udhcp_dump_packet(dhcp_pkt); - return bytes - (sizeof(packet.ip) + sizeof(packet.udp)); + + log1("Received a packet"); + udhcp_dump_packet(&packet.data); + + bytes -= sizeof(packet.ip) + sizeof(packet.udp); + memcpy(dhcp_pkt, &packet.data, bytes); + return bytes; } @@ -890,7 +1033,7 @@ static int udhcp_raw_socket(int ifindex) log1("Opening raw socket on ifindex %d", ifindex); //log2? fd = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP)); - log1("Got raw socket fd %d", fd); //log2? + log1("Got raw socket fd"); //log2? sock.sll_family = AF_PACKET; sock.sll_protocol = htons(ETH_P_IP); @@ -902,7 +1045,14 @@ static int udhcp_raw_socket(int ifindex) /* Ignoring error (kernel may lack support for this) */ if (setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog, sizeof(filter_prog)) >= 0) - log1("Attached filter to raw socket fd %d", fd); // log? + log1("Attached filter to raw socket fd"); // log? + } + + if (setsockopt(fd, SOL_PACKET, PACKET_AUXDATA, + &const_int_1, sizeof(int)) < 0 + ) { + if (errno != ENOPROTOOPT) + log1("Can't set PACKET_AUXDATA on raw socket"); } log1("Created raw socket"); @@ -952,7 +1102,7 @@ static void perform_renew(void) } } -static void perform_release(uint32_t requested_ip, uint32_t server_addr) +static void perform_release(uint32_t server_addr, uint32_t requested_ip) { char buffer[sizeof("255.255.255.255")]; struct in_addr temp_addr; @@ -1001,7 +1151,7 @@ static void client_background(void) //usage:#endif //usage:#define udhcpc_trivial_usage //usage: "[-fbnq"IF_UDHCP_VERBOSE("v")"oCRB] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE]\n" -//usage: " [-H HOSTNAME] [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]") +//usage: " [-V VENDOR] [-x OPT:VAL]... [-O OPT]..." IF_FEATURE_UDHCP_PORT(" [-P N]") //usage:#define udhcpc_full_usage "\n" //usage: IF_LONG_OPTS( //usage: "\n -i,--interface IFACE Interface to use (default eth0)" @@ -1034,7 +1184,6 @@ static void client_background(void) //usage: "\n -x lease:3600 - option 51 (lease time)" //usage: "\n -x 0x3d:0100BEEFC0FFEE - option 61 (client id)" //usage: "\n -F,--fqdn NAME Ask server to update DNS mapping for NAME" -//usage: "\n -H,-h,--hostname NAME Send NAME as client hostname (default none)" //usage: "\n -V,--vendorclass VENDOR Vendor identifier (default 'udhcp VERSION')" //usage: "\n -C,--clientid-none Don't send MAC as client identifier" //usage: IF_UDHCP_VERBOSE( @@ -1098,16 +1247,13 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) int discover_retries = 5; uint32_t server_addr = server_addr; /* for compiler */ uint32_t requested_ip = 0; - uint32_t xid = 0; - uint32_t lease_seconds = 0; /* can be given as 32-bit quantity */ + uint32_t xid = xid; /* for compiler */ int packet_num; int timeout; /* must be signed */ unsigned already_waited_sec; unsigned opt; int max_fd; int retval; - struct timeval tv; - struct dhcp_packet packet; fd_set rfds; /* Default options */ @@ -1119,11 +1265,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* Parse command line */ /* O,x: list; -T,-t,-A take numeric param */ - opt_complementary = "O::x::T+:t+:A+" -#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 - ":vv" -#endif - ; + opt_complementary = "O::x::T+:t+:A+" IF_UDHCP_VERBOSE(":vv") ; + IF_LONG_OPTS(applet_long_options = udhcpc_longopts;) opt = getopt32(argv, "CV:H:h:F:i:np:qRr:s:T:t:SA:O:ox:fB" "m" // zzz @@ -1138,12 +1281,13 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) , &list_O , &list_x IF_FEATURE_UDHCP_PORT(, &str_P) -#if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 1 - , &dhcp_verbose -#endif - ); - if (opt & (OPT_h|OPT_H)) + IF_UDHCP_VERBOSE(, &dhcp_verbose) + ); + if (opt & (OPT_h|OPT_H)) { + //msg added 2011-11 + bb_error_msg("option -h NAME is deprecated, use -x hostname:NAME"); client_config.hostname = alloc_dhcp_option(DHCP_HOST_NAME, str_h, 0); + } if (opt & OPT_F) { /* FQDN option format: [0x51][len][flags][0][0] */ client_config.fqdn = alloc_dhcp_option(DHCP_FQDN, str_F, 3); @@ -1167,14 +1311,23 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) SERVER_PORT = CLIENT_PORT - 1; } #endif - if (opt & OPT_o) - client_config.no_default_options = 1; while (list_O) { char *optstr = llist_pop(&list_O); - unsigned n = udhcp_option_idx(optstr); - n = dhcp_optflags[n].code; + unsigned n = bb_strtou(optstr, NULL, 0); + if (errno || n > 254) { + n = udhcp_option_idx(optstr); + n = dhcp_optflags[n].code; + } client_config.opt_mask[n >> 3] |= 1 << (n & 7); } + if (!(opt & OPT_o)) { + unsigned i, n; + for (i = 0; (n = dhcp_optflags[i].code) != 0; i++) { + if (dhcp_optflags[i].flags & OPTION_REQ) { + client_config.opt_mask[n >> 3] |= 1 << (n & 7); + } + } + } while (list_x) { char *optstr = llist_pop(&list_x); char *colon = strchr(optstr, ':'); @@ -1205,8 +1358,16 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) clientid_mac_ptr = client_config.clientid + OPT_DATA+1; memcpy(clientid_mac_ptr, client_config.client_mac, 6); } - if (str_V[0] != '\0') + if (str_V[0] != '\0') { + // can drop -V, str_V, client_config.vendorclass, + // but need to add "vendor" to the list of recognized + // string opts for this to work; + // and need to tweak add_client_options() too... + // ...so the question is, should we? + //bb_error_msg("option -V VENDOR is deprecated, use -x vendor:VENDOR"); client_config.vendorclass = alloc_dhcp_option(DHCP_VENDOR, str_V, 0); + } + #if !BB_MMU /* on NOMMU reexec (i.e., background) early */ if (!(opt & OPT_f)) { @@ -1244,6 +1405,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) * "continue" statements in code below jump to the top of the loop. */ for (;;) { + struct timeval tv; + struct dhcp_packet packet; /* silence "uninitialized!" warning */ unsigned timestamp_before_wait = timestamp_before_wait; @@ -1263,8 +1426,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) retval = 0; /* If we already timed out, fall through with retval = 0, else... */ if ((int)tv.tv_sec > 0) { + log1("Waiting on select %u seconds", (int)tv.tv_sec); timestamp_before_wait = (unsigned)monotonic_sec(); - log1("Waiting on select..."); retval = select(max_fd + 1, &rfds, NULL, NULL, &tv); if (retval < 0) { /* EINTR? A signal was caught, don't panic */ @@ -1292,7 +1455,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) client_config.client_mac, &client_config.client_mtu) ) { - return 1; /* iface is gone? */ + goto ret0; /* iface is gone? */ } if (clientid_mac_ptr) memcpy(clientid_mac_ptr, client_config.client_mac, 6); @@ -1302,7 +1465,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) switch (state) { case INIT_SELECTING: - if (packet_num < discover_retries) { + if (!discover_retries || packet_num < discover_retries) { if (packet_num == 0) xid = random_xid(); /* broadcast */ @@ -1331,7 +1494,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) packet_num = 0; continue; case REQUESTING: - if (packet_num < discover_retries) { + if (!discover_retries || packet_num < discover_retries) { /* send broadcast select packet */ send_select(xid, server_addr, requested_ip); timeout = discover_timeout; @@ -1406,8 +1569,11 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) switch (udhcp_sp_read(&rfds)) { case SIGUSR1: client_config.first_secs = 0; /* make secs field count from 0 */ +// already_waited_sec = 0; /* shibby - this broke tomato renew button */ perform_renew(); if (state == RENEW_REQUESTED) +// if (timeout > tryagain_timeout) /* shibby - this broke tomato renew button */ +// timeout = tryagain_timeout; /* shibby - this broke tomato renew button */ goto case_RENEW_REQUESTED; /* Start things over */ packet_num = 0; @@ -1415,13 +1581,11 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) timeout = 0; continue; case SIGUSR2: - perform_release(requested_ip, server_addr); + perform_release(server_addr, requested_ip); timeout = INT_MAX; continue; case SIGTERM: bb_info_msg("Received SIGTERM"); - if (opt & OPT_R) /* release on quit */ - perform_release(requested_ip, server_addr); goto ret0; } @@ -1474,9 +1638,27 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) switch (state) { case INIT_SELECTING: - /* Must be a DHCPOFFER to one of our xid's */ + /* Must be a DHCPOFFER */ if (*message == DHCPOFFER) { - /* TODO: why we don't just fetch server's IP from IP header? */ +/* What exactly is server's IP? There are several values. + * Example DHCP offer captured with tchdump: + * + * 10.34.25.254:67 > 10.34.25.202:68 // IP header's src + * BOOTP fields: + * Your-IP 10.34.25.202 + * Server-IP 10.34.32.125 // "next server" IP + * Gateway-IP 10.34.25.254 // relay's address (if DHCP relays are in use) + * DHCP options: + * DHCP-Message Option 53, length 1: Offer + * Server-ID Option 54, length 4: 10.34.255.7 // "server ID" + * Default-Gateway Option 3, length 4: 10.34.25.254 // router + * + * We think that real server IP (one to use in renew/release) + * is one in Server-ID option. But I am not 100% sure. + * IP header's src and Gateway-IP (same in this example) + * might work too. + * "Next server" and router are definitely wrong ones to use, though... + */ temp = udhcp_get_option(&packet, DHCP_SERVER_ID); if (!temp) { bb_error_msg("no server ID, ignoring packet"); @@ -1500,6 +1682,9 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) case RENEW_REQUESTED: case REBINDING: if (*message == DHCPACK) { + uint32_t lease_seconds; + struct in_addr temp_addr; + temp = udhcp_get_option(&packet, DHCP_LEASE_TIME); if (!temp) { bb_error_msg("no lease time with ACK, using 1 hour lease"); @@ -1508,9 +1693,11 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) /* it IS unaligned sometimes, don't "optimize" */ move_from_unaligned32(lease_seconds, temp); lease_seconds = ntohl(lease_seconds); - lease_seconds &= 0x0fffffff; /* paranoia: must not be prone to overflows */ - if (lease_seconds < 10) /* and not too small */ - lease_seconds = 10; + /* paranoia: must not be too small and not prone to overflows */ + if (lease_seconds < 0x10) + lease_seconds = 0x10; + if (lease_seconds >= 0x10000000) + lease_seconds = 0x0fffffff; } #if ENABLE_FEATURE_UDHCPC_ARPING if (opt & OPT_a) { @@ -1531,7 +1718,7 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) ) { bb_info_msg("Offered address is in use " "(got ARP reply), declining"); - send_decline(xid, server_addr, packet.yiaddr); + send_decline(/*xid,*/ server_addr, packet.yiaddr); if (state != REQUESTING) udhcp_run_script(NULL, "deconfig"); @@ -1548,20 +1735,15 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) #endif /* enter bound state */ timeout = lease_seconds / 2; - { - struct in_addr temp_addr; - temp_addr.s_addr = packet.yiaddr; - bb_info_msg("Lease of %s obtained, lease time %u", - inet_ntoa(temp_addr), (unsigned)lease_seconds); - } + temp_addr.s_addr = packet.yiaddr; + bb_info_msg("Lease of %s obtained, lease time %u", + inet_ntoa(temp_addr), (unsigned)lease_seconds); requested_ip = packet.yiaddr; udhcp_run_script(&packet, state == REQUESTING ? "bound" : "renew"); state = BOUND; change_listen_mode(LISTEN_NONE); if (opt & OPT_q) { /* quit after lease */ - if (opt & OPT_R) /* release on quit */ - perform_release(requested_ip, server_addr); goto ret0; } /* future renew failures should not exit (JM) */ @@ -1573,6 +1755,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) opt = ((opt & ~OPT_b) | OPT_f); } #endif + /* make future renew packets use different xid */ + /* xid = random_xid(); ...but why bother? */ already_waited_sec = 0; continue; /* back to main loop */ } @@ -1599,6 +1783,8 @@ int udhcpc_main(int argc UNUSED_PARAM, char **argv) } /* for (;;) - main loop ends */ ret0: + if (opt & OPT_R) /* release on quit */ + perform_release(server_addr, requested_ip); retval = 0; ret: /*if (client_config.pidfile) - remove_pidfile has its own check */ diff --git a/release/src/router/busybox/networking/udhcp/dhcpc.h b/release/src/router/busybox/networking/udhcp/dhcpc.h index 3c941c65b8..c9b1f398bb 100644 --- a/release/src/router/busybox/networking/udhcp/dhcpc.h +++ b/release/src/router/busybox/networking/udhcp/dhcpc.h @@ -10,7 +10,6 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN struct client_config_t { uint8_t client_mac[6]; /* Our mac address */ uint16_t client_mtu; /* Our mtu */ - char no_default_options; /* Do not include default options in request */ IF_FEATURE_UDHCP_PORT(uint16_t port;) int ifindex; /* Index number of the interface to use */ uint8_t opt_mask[256 / 8]; /* Bitmask of options to send (-O option) */ diff --git a/release/src/router/busybox/networking/udhcp/dhcpc.c b/release/src/router/busybox/networking/udhcp/dhcpc_old.c similarity index 99% copy from release/src/router/busybox/networking/udhcp/dhcpc.c copy to release/src/router/busybox/networking/udhcp/dhcpc_old.c index d7b7862e78..c2f7a715cd 100644 --- a/release/src/router/busybox/networking/udhcp/dhcpc.c +++ b/release/src/router/busybox/networking/udhcp/dhcpc_old.c @@ -21,9 +21,9 @@ #include /* Override ENABLE_FEATURE_PIDFILE - ifupdown needs our pidfile to always exist */ #define WANT_PIDFILE 1 -#include "common.h" +#include "common_old.h" #include "dhcpd.h" -#include "dhcpc.h" +#include "dhcpc_old.h" #include #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined(_NEWLIB_VERSION) diff --git a/release/src/router/busybox/networking/udhcp/dhcpc.h b/release/src/router/busybox/networking/udhcp/dhcpc_old.h similarity index 100% copy from release/src/router/busybox/networking/udhcp/dhcpc.h copy to release/src/router/busybox/networking/udhcp/dhcpc_old.h diff --git a/release/src/router/busybox/networking/udhcp/dhcpd.c b/release/src/router/busybox/networking/udhcp/dhcpd.c index d85c11490c..66e5465d8c 100644 --- a/release/src/router/busybox/networking/udhcp/dhcpd.c +++ b/release/src/router/busybox/networking/udhcp/dhcpd.c @@ -378,6 +378,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) /* Setup the signal pipe */ udhcp_sp_setup(); + continue_with_autotime: timeout_end = monotonic_sec() + server_config.auto_time; while (1) { /* loop until universe collapses */ fd_set rfds; @@ -407,8 +408,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) } if (retval == 0) { write_leases(); - timeout_end = monotonic_sec() + server_config.auto_time; - continue; + goto continue_with_autotime; } if (retval < 0 && errno != EINTR) { log1("Error on select"); @@ -420,10 +420,10 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv) bb_info_msg("Received SIGUSR1"); write_leases(); /* why not just reset the timeout, eh */ - timeout_end = monotonic_sec() + server_config.auto_time; - continue; + goto continue_with_autotime; case SIGTERM: bb_info_msg("Received SIGTERM"); + write_leases(); goto ret0; case 0: /* no signal: read a packet */ break; diff --git a/release/src/router/busybox/networking/udhcp/socket.c b/release/src/router/busybox/networking/udhcp/socket.c index 35915e8964..27c79619e5 100644 --- a/release/src/router/busybox/networking/udhcp/socket.c +++ b/release/src/router/busybox/networking/udhcp/socket.c @@ -99,6 +99,7 @@ int FAST_FUNC udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf) { int fd; struct sockaddr_in addr; + char *colon; log1("Opening listen socket on *:%d %s", port, inf); fd = xsocket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); @@ -107,10 +108,17 @@ int FAST_FUNC udhcp_listen_socket(/*uint32_t ip,*/ int port, const char *inf) if (setsockopt_broadcast(fd) == -1) bb_perror_msg_and_die("SO_BROADCAST"); - /* NB: bug 1032 says this doesn't work on ethernet aliases (ethN:M) */ + /* SO_BINDTODEVICE doesn't work on ethernet aliases (ethN:M) */ + colon = strrchr(inf, ':'); + if (colon) + *colon = '\0'; + if (setsockopt_bindtodevice(fd, inf)) xfunc_die(); /* warning is already printed */ + if (colon) + *colon = ':'; + memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); diff --git a/release/src/router/busybox/networking/wget.c b/release/src/router/busybox/networking/wget.c index 1991a10728..4eafebe401 100644 --- a/release/src/router/busybox/networking/wget.c +++ b/release/src/router/busybox/networking/wget.c @@ -13,8 +13,9 @@ //usage: IF_FEATURE_WGET_LONG_OPTIONS( //usage: "[-c|--continue] [-s|--spider] [-q|--quiet] [-O|--output-document FILE]\n" //usage: " [--header 'header: value'] [-Y|--proxy on/off] [-P DIR]\n" -//usage: " [--no-check-certificate] [-U|--user-agent AGENT]" -//usage: IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." +/* Since we ignore these opts, we don't show them in --help */ +/* //usage: " [--no-check-certificate] [--no-cache]" */ +//usage: " [-U|--user-agent AGENT]" IF_FEATURE_WGET_TIMEOUT(" [-T SEC]") " URL..." //usage: ) //usage: IF_NOT_FEATURE_WGET_LONG_OPTIONS( //usage: "[-csq] [-O FILE] [-Y on/off] [-P DIR] [-U AGENT]" @@ -35,8 +36,11 @@ #include "libbb.h" -//#define log_io(...) bb_error_msg(__VA_ARGS__) -#define log_io(...) ((void)0) +#if 0 +# define log_io(...) bb_error_msg(__VA_ARGS__) +#else +# define log_io(...) ((void)0) +#endif struct host_info { @@ -316,8 +320,6 @@ static char *gethdr(FILE *fp) char *s, *hdrval; int c; - /* *istrunc = 0; */ - /* retrieve header line */ c = fgets_and_trim(fp); @@ -348,6 +350,15 @@ static char *gethdr(FILE *fp) return hdrval; } +static void reset_beg_range_to_zero(void) +{ + bb_error_msg("restart failed"); + G.beg_range = 0; + xlseek(G.output_fd, 0, SEEK_SET); + /* Done at the end instead: */ + /* ftruncate(G.output_fd, 0); */ +} + static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_sockaddr *lsa) { FILE *sfp; @@ -415,10 +426,12 @@ static FILE* prepare_ftp_session(FILE **dfpp, struct host_info *target, len_and_ *dfpp = open_socket(lsa); - if (G.beg_range) { + if (G.beg_range != 0) { sprintf(G.wget_buf, "REST %"OFF_FMT"u", G.beg_range); if (ftpcmd(G.wget_buf, NULL, sfp) == 350) G.content_len -= G.beg_range; + else + reset_beg_range_to_zero(); } if (ftpcmd("RETR ", target->path, sfp) > 150) @@ -431,7 +444,7 @@ static void NOINLINE retrieve_file_data(FILE *dfp) { #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT # if ENABLE_FEATURE_WGET_TIMEOUT - unsigned second_cnt; + unsigned second_cnt = G.timeout_seconds; # endif struct pollfd polldata; @@ -452,7 +465,7 @@ static void NOINLINE retrieve_file_data(FILE *dfp) * which messes up progress bar and/or timeout logic. * Because of nonblocking I/O, we need to dance * very carefully around EAGAIN. See explanation at - * clearerr() call. + * clearerr() calls. */ ndelay_on(polldata.fd); #endif @@ -460,32 +473,7 @@ static void NOINLINE retrieve_file_data(FILE *dfp) int n; unsigned rdsz; - rdsz = sizeof(G.wget_buf); - if (G.got_clen) { - if (G.content_len < (off_t)sizeof(G.wget_buf)) { - if ((int)G.content_len <= 0) - break; - rdsz = (unsigned)G.content_len; - } - } - #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT -# if ENABLE_FEATURE_WGET_TIMEOUT - second_cnt = G.timeout_seconds; -# endif - while (1) { - if (safe_poll(&polldata, 1, 1000) != 0) - break; /* error, EOF, or data is available */ -# if ENABLE_FEATURE_WGET_TIMEOUT - if (second_cnt != 0 && --second_cnt == 0) { - progress_meter(PROGRESS_END); - bb_error_msg_and_die("download timed out"); - } -# endif - /* Needed for "stalled" indicator */ - progress_meter(PROGRESS_BUMP); - } - /* fread internally uses read loop, which in our case * is usually exited when we get EAGAIN. * In this case, libc sets error marker on the stream. @@ -495,36 +483,71 @@ static void NOINLINE retrieve_file_data(FILE *dfp) * into if (n <= 0) ... */ clearerr(dfp); - errno = 0; #endif + errno = 0; + rdsz = sizeof(G.wget_buf); + if (G.got_clen) { + if (G.content_len < (off_t)sizeof(G.wget_buf)) { + if ((int)G.content_len <= 0) + break; + rdsz = (unsigned)G.content_len; + } + } n = fread(G.wget_buf, 1, rdsz, dfp); - /* man fread: + + if (n > 0) { + xwrite(G.output_fd, G.wget_buf, n); +#if ENABLE_FEATURE_WGET_STATUSBAR + G.transferred += n; +#endif + if (G.got_clen) { + G.content_len -= n; + if (G.content_len == 0) + break; + } +#if ENABLE_FEATURE_WGET_TIMEOUT + second_cnt = G.timeout_seconds; +#endif + continue; + } + + /* n <= 0. + * man fread: * If error occurs, or EOF is reached, the return value * is a short item count (or zero). * fread does not distinguish between EOF and error. */ - if (n <= 0) { -#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT - if (errno == EAGAIN) /* poll lied, there is no data? */ - continue; /* yes */ -#endif - if (ferror(dfp)) + if (errno != EAGAIN) { + if (ferror(dfp)) { + progress_meter(PROGRESS_END); bb_perror_msg_and_die(bb_msg_read_error); + } break; /* EOF, not error */ } - xwrite(G.output_fd, G.wget_buf, n); - -#if ENABLE_FEATURE_WGET_STATUSBAR - G.transferred += n; +#if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT + /* It was EAGAIN. There is no data. Wait up to one second + * then abort if timed out, or update the bar and try reading again. + */ + if (safe_poll(&polldata, 1, 1000) == 0) { +# if ENABLE_FEATURE_WGET_TIMEOUT + if (second_cnt != 0 && --second_cnt == 0) { + progress_meter(PROGRESS_END); + bb_error_msg_and_die("download timed out"); + } +# endif + /* We used to loop back to poll here, + * but there is no great harm in letting fread + * to try reading anyway. + */ + } + /* Need to do it _every_ second for "stalled" indicator + * to be shown properly. + */ progress_meter(PROGRESS_BUMP); #endif - if (G.got_clen) { - G.content_len -= n; - if (G.content_len == 0) - break; - } - } + } /* while (reading data) */ + #if ENABLE_FEATURE_WGET_STATUSBAR || ENABLE_FEATURE_WGET_TIMEOUT clearerr(dfp); ndelay_off(polldata.fd); /* else fgets can get very unhappy */ @@ -540,6 +563,24 @@ static void NOINLINE retrieve_file_data(FILE *dfp) if (G.content_len == 0) break; /* all done! */ G.got_clen = 1; + /* + * Note that fgets may result in some data being buffered in dfp. + * We loop back to fread, which will retrieve this data. + * Also note that code has to be arranged so that fread + * is done _before_ one-second poll wait - poll doesn't know + * about stdio buffering and can result in spurious one second waits! + */ + } + + /* If -c failed, we restart from the beginning, + * but we do not truncate file then, we do it only now, at the end. + * This lets user to ^C if his 99% complete 10 GB file download + * failed to restart *without* losing the almost complete file. + */ + { + off_t pos = lseek(G.output_fd, 0, SEEK_CUR); + if (pos != (off_t)-1) + ftruncate(G.output_fd, pos); } /* Draw full bar and free its resources */ @@ -597,13 +638,11 @@ static void download_one_url(const char *url) if (G.fname_out[0] == '/' || !G.fname_out[0]) G.fname_out = (char*)"index.html"; /* -P DIR is considered only if there was no -O FILE */ + if (G.dir_prefix) + G.fname_out = fname_out_alloc = concat_path_file(G.dir_prefix, G.fname_out); else { - if (G.dir_prefix) - G.fname_out = fname_out_alloc = concat_path_file(G.dir_prefix, G.fname_out); - else { - /* redirects may free target.path later, need to make a copy */ - G.fname_out = fname_out_alloc = xstrdup(G.fname_out); - } + /* redirects may free target.path later, need to make a copy */ + G.fname_out = fname_out_alloc = xstrdup(G.fname_out); } } #if ENABLE_FEATURE_WGET_STATUSBAR @@ -675,7 +714,7 @@ static void download_one_url(const char *url) } #endif - if (G.beg_range) + if (G.beg_range != 0) fprintf(sfp, "Range: bytes=%"OFF_FMT"u-\r\n", G.beg_range); #if ENABLE_FEATURE_WGET_LONG_OPTIONS @@ -742,15 +781,23 @@ However, in real world it was observed that some web servers (e.g. Boa/0.94.14rc21) simply use code 204 when file size is zero. */ case 204: + if (G.beg_range != 0) { + /* "Range:..." was not honored by the server. + * Restart download from the beginning. + */ + reset_beg_range_to_zero(); + } break; case 300: /* redirection */ case 301: case 302: case 303: break; - case 206: - if (G.beg_range) + case 206: /* Partial Content */ + if (G.beg_range != 0) + /* "Range:..." worked. Good. */ break; + /* Partial Content even though we did not ask for it??? */ /* fall through */ default: bb_error_msg_and_die("server returned error: %s", sanitize_string(G.wget_buf)); @@ -878,6 +925,8 @@ int wget_main(int argc UNUSED_PARAM, char **argv) "post-data\0" Required_argument "\xfd" /* Ignored (we don't do ssl) */ "no-check-certificate\0" No_argument "\xfc" + /* Ignored (we don't support caching) */ + "no-cache\0" No_argument "\xfb" ; #endif diff --git a/release/src/router/busybox/printutils/lpr.c b/release/src/router/busybox/printutils/lpr.c index fc6bca9e8d..70cda7717f 100644 --- a/release/src/router/busybox/printutils/lpr.c +++ b/release/src/router/busybox/printutils/lpr.c @@ -89,6 +89,10 @@ int lpqr_main(int argc UNUSED_PARAM, char *argv[]) unsigned opts; int fd; + queue = getenv("PRINTER"); + if (!queue) + queue = "lp"; + // parse options // TODO: set opt_complementary: s,d,f are mutually exclusive opts = getopt32(argv, @@ -98,16 +102,7 @@ int lpqr_main(int argc UNUSED_PARAM, char *argv[]) ); argv += optind; - // if queue is not specified -> use $PRINTER - if (!(opts & OPT_P)) - queue = getenv("PRINTER"); - // if queue is still not specified -> - if (!queue) { - // ... queue defaults to "lp" - // server defaults to "localhost" - queue = "lp"; - // if queue is specified -> - } else { + { // queue name is to the left of '@' char *s = strchr(queue, '@'); if (s) { @@ -186,6 +181,17 @@ int lpqr_main(int argc UNUSED_PARAM, char *argv[]) dfd = xopen(*argv, O_RDONLY); } + st.st_size = 0; /* paranoia: fstat may theoretically fail */ + fstat(dfd, &st); + + /* Apparently, some servers are buggy and won't accept 0-sized jobs. + * Standard lpr works around it by refusing to send such jobs: + */ + if (st.st_size == 0) { + bb_error_msg("nothing to print"); + continue; + } + /* "The name ... should start with ASCII "cfA", * followed by a three digit job number, followed * by the host name which has constructed the file." @@ -210,14 +216,11 @@ int lpqr_main(int argc UNUSED_PARAM, char *argv[]) , (opts & LPR_m) ? user : "" , remote_filename ); - // delete possible "\nX\n" patterns + // delete possible "\nX\n" (that is, one-char) patterns c = controlfile; - cflen = (unsigned)strlen(controlfile); while ((c = strchr(c, '\n')) != NULL) { if (c[1] && c[2] == '\n') { - /* can't use strcpy, results are undefined */ - memmove(c, c+2, cflen - (c-controlfile) - 1); - cflen -= 2; + overlapping_strcpy(c, c+2); } else { c++; } @@ -228,6 +231,7 @@ int lpqr_main(int argc UNUSED_PARAM, char *argv[]) bb_error_msg("sending control file"); /* "Acknowledgement processing must occur as usual * after the command is sent." */ + cflen = (unsigned)strlen(controlfile); fdprintf(fd, "\x2" "%u c%s\n", cflen, remote_filename); get_response_or_say_and_die(fd, "sending control file"); /* "Once all of the contents have @@ -241,8 +245,6 @@ int lpqr_main(int argc UNUSED_PARAM, char *argv[]) // send data file, with name "dfaXXX" if (opts & LPR_V) bb_error_msg("sending data file"); - st.st_size = 0; /* paranoia: fstat may theoretically fail */ - fstat(dfd, &st); fdprintf(fd, "\x3" "%"OFF_FMT"u d%s\n", st.st_size, remote_filename); get_response_or_say_and_die(fd, "sending data file"); if (bb_copyfd_size(dfd, fd, st.st_size) != st.st_size) { diff --git a/release/src/router/busybox/procps/Config.src b/release/src/router/busybox/procps/Config.src index 5cd47c84f5..527d9ee0c4 100644 --- a/release/src/router/busybox/procps/Config.src +++ b/release/src/router/busybox/procps/Config.src @@ -140,60 +140,6 @@ config BB_SYSCTL help Configure kernel parameters at runtime. -config TOP - bool "top" - default y - help - The top program provides a dynamic real-time view of a running - system. - -config FEATURE_TOP_CPU_USAGE_PERCENTAGE - bool "Show CPU per-process usage percentage" - default y - depends on TOP - help - Make top display CPU usage for each process. - This adds about 2k. - -config FEATURE_TOP_CPU_GLOBAL_PERCENTS - bool "Show CPU global usage percentage" - default y - depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE - help - Makes top display "CPU: NN% usr NN% sys..." line. - This adds about 0.5k. - -config FEATURE_TOP_SMP_CPU - bool "SMP CPU usage display ('c' key)" - default y - depends on FEATURE_TOP_CPU_GLOBAL_PERCENTS - help - Allow 'c' key to switch between individual/cumulative CPU stats - This adds about 0.5k. - -config FEATURE_TOP_DECIMALS - bool "Show 1/10th of a percent in CPU/mem statistics" - default y - depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE - help - Show 1/10th of a percent in CPU/mem statistics. - This adds about 0.3k. - -config FEATURE_TOP_SMP_PROCESS - bool "Show CPU process runs on ('j' field)" - default y - depends on TOP - help - Show CPU where process was last found running on. - This is the 'j' field. - -config FEATURE_TOPMEM - bool "Topmem command ('s' key)" - default y - depends on TOP - help - Enable 's' in top (gives lots of memory info). - config FEATURE_SHOW_THREADS bool "Support for showing threads in ps/pstree/top" default y diff --git a/release/src/router/busybox/procps/nmeter.c b/release/src/router/busybox/procps/nmeter.c index ed54790248..6a3b327438 100644 --- a/release/src/router/busybox/procps/nmeter.c +++ b/release/src/router/busybox/procps/nmeter.c @@ -271,7 +271,7 @@ static int rdval_loadavg(const char* p, ullong *vec, ...) } // Parses /proc/diskstats -// 1 2 3 4 5 6(rd) 7 8 9 10(wr) 11 12 13 14 +// 1 2 3 4 5 6(rd) 7 8 9 10(wr) 11 12 13 14 // 3 0 hda 51292 14441 841783 926052 25717 79650 843256 3029804 0 148459 3956933 // 3 1 hda1 0 0 0 0 <- ignore if only 4 fields // Linux 3.0 (maybe earlier) started printing full stats for hda1 too. diff --git a/release/src/router/busybox/procps/powertop.c b/release/src/router/busybox/procps/powertop.c index 008cdfca4e..71988a2955 100644 --- a/release/src/router/busybox/procps/powertop.c +++ b/release/src/router/busybox/procps/powertop.c @@ -9,7 +9,7 @@ * Licensed under GPLv2, see file LICENSE in this source tree. */ -//applet:IF_POWERTOP(APPLET(powertop, BB_DIR_BIN, BB_SUID_DROP)) +//applet:IF_POWERTOP(APPLET(powertop, BB_DIR_USR_SBIN, BB_SUID_DROP)) //kbuild:lib-$(CONFIG_POWERTOP) += powertop.o @@ -493,7 +493,7 @@ static NOINLINE int process_timer_stats(void) * Get information about CPU using CPUID opcode. */ static void cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, - unsigned int *edx) + unsigned int *edx) { /* EAX value specifies what information to return */ __asm__( @@ -650,7 +650,7 @@ static void show_timerstats(void) } else { bb_putchar('\n'); bb_error_msg("no stats available; run as root or" - " enable the cpufreq_stats module"); + " enable the timer_stats module"); } } diff --git a/release/src/router/busybox/procps/ps.c b/release/src/router/busybox/procps/ps.c index 3a5af7c186..efc087ee5a 100644 --- a/release/src/router/busybox/procps/ps.c +++ b/release/src/router/busybox/procps/ps.c @@ -655,9 +655,9 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) time_t now = now; long uptime; #endif - int opts = 0; /* If we support any options, parse argv */ #if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE || ENABLE_FEATURE_PS_LONG + int opts = 0; # if ENABLE_FEATURE_PS_WIDE /* -w is a bit complicated */ int w_count = 0; @@ -711,10 +711,10 @@ int ps_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) * We also show STIME (standard says that -f shows it, -l doesn't). */ puts("S UID PID PPID VSZ RSS TTY STIME TIME CMD"); -#if ENABLE_FEATURE_PS_LONG +# if ENABLE_FEATURE_PS_LONG now = time(NULL); uptime = get_uptime(); -#endif +# endif } else { puts(" PID USER VSZ STAT COMMAND"); diff --git a/release/src/router/busybox/procps/sysctl.c b/release/src/router/busybox/procps/sysctl.c index 5296d0f581..c6a1de21dc 100644 --- a/release/src/router/busybox/procps/sysctl.c +++ b/release/src/router/busybox/procps/sysctl.c @@ -12,21 +12,23 @@ */ //usage:#define sysctl_trivial_usage -//usage: "[OPTIONS] [VALUE]..." +//usage: "[OPTIONS] [KEY[=VALUE]]..." //usage:#define sysctl_full_usage "\n\n" -//usage: "Configure kernel parameters at runtime\n" -//usage: "\n -n Don't print key names" +//usage: "Show/set kernel parameters\n" //usage: "\n -e Don't warn about unknown keys" -//usage: "\n -w Change sysctl setting" -//usage: "\n -p FILE Load sysctl settings from FILE (default /etc/sysctl.conf)" -//usage: "\n -a Display all values" -//usage: "\n -A Display all values in table form" +//usage: "\n -n Don't show key names" +//usage: "\n -a Show all values" +/* Same as -a, no need to show it */ +/* //usage: "\n -A Show all values in table form" */ +//usage: "\n -w Set values" +//usage: "\n -p FILE Set values from FILE (default /etc/sysctl.conf)" +//usage: "\n -q Set values silently" //usage: //usage:#define sysctl_example_usage //usage: "sysctl [-n] [-e] variable...\n" -//usage: "sysctl [-n] [-e] -w variable=value...\n" +//usage: "sysctl [-n] [-e] [-q] -w variable=value...\n" //usage: "sysctl [-n] [-e] -a\n" -//usage: "sysctl [-n] [-e] -p file (default /etc/sysctl.conf)\n" +//usage: "sysctl [-n] [-e] [-q] -p file (default /etc/sysctl.conf)\n" //usage: "sysctl [-n] [-e] -A\n" #include "libbb.h" @@ -37,9 +39,11 @@ enum { FLAG_TABLE_FORMAT = 1 << 2, /* not implemented */ FLAG_SHOW_ALL = 1 << 3, FLAG_PRELOAD_FILE = 1 << 4, +/* TODO: procps 3.2.8 seems to not require -w for KEY=VAL to work: */ FLAG_WRITE = 1 << 5, + FLAG_QUIET = 1 << 6, }; -#define OPTION_STR "neAapw" +#define OPTION_STR "neAapwq" static void sysctl_dots_to_slashes(char *name) { @@ -144,9 +148,11 @@ static int sysctl_act_on_setting(char *setting) //TODO: procps 3.2.7 writes "value\n", note trailing "\n" xwrite_str(fd, value); close(fd); - if (option_mask32 & FLAG_SHOW_KEYS) - printf("%s = ", outname); - puts(value); + if (!(option_mask32 & FLAG_QUIET)) { + if (option_mask32 & FLAG_SHOW_KEYS) + printf("%s = ", outname); + puts(value); + } } else { char c; @@ -199,7 +205,7 @@ static int sysctl_act_recursive(const char *path) continue; /* d_name is "." or ".." */ /* if path was ".", drop "./" prefix: */ retval |= sysctl_act_recursive((next[0] == '.' && next[1] == '/') ? - next + 2 : next); + next + 2 : next); free(next); } closedir(dirp); diff --git a/release/src/router/busybox/procps/top.c b/release/src/router/busybox/procps/top.c index 15eb624cce..2908bd3e77 100644 --- a/release/src/router/busybox/procps/top.c +++ b/release/src/router/busybox/procps/top.c @@ -50,6 +50,60 @@ * chroot . ./top -bn1 >top1.out */ +//config:config TOP +//config: bool "top" +//config: default y +//config: help +//config: The top program provides a dynamic real-time view of a running +//config: system. +//config: +//config:config FEATURE_TOP_CPU_USAGE_PERCENTAGE +//config: bool "Show CPU per-process usage percentage" +//config: default y +//config: depends on TOP +//config: help +//config: Make top display CPU usage for each process. +//config: This adds about 2k. +//config: +//config:config FEATURE_TOP_CPU_GLOBAL_PERCENTS +//config: bool "Show CPU global usage percentage" +//config: default y +//config: depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE +//config: help +//config: Makes top display "CPU: NN% usr NN% sys..." line. +//config: This adds about 0.5k. +//config: +//config:config FEATURE_TOP_SMP_CPU +//config: bool "SMP CPU usage display ('c' key)" +//config: default y +//config: depends on FEATURE_TOP_CPU_GLOBAL_PERCENTS +//config: help +//config: Allow 'c' key to switch between individual/cumulative CPU stats +//config: This adds about 0.5k. +//config: +//config:config FEATURE_TOP_DECIMALS +//config: bool "Show 1/10th of a percent in CPU/mem statistics" +//config: default y +//config: depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE +//config: help +//config: Show 1/10th of a percent in CPU/mem statistics. +//config: This adds about 0.3k. +//config: +//config:config FEATURE_TOP_SMP_PROCESS +//config: bool "Show CPU process runs on ('j' field)" +//config: default y +//config: depends on TOP +//config: help +//config: Show CPU where process was last found running on. +//config: This is the 'j' field. +//config: +//config:config FEATURE_TOPMEM +//config: bool "Topmem command ('s' key)" +//config: default y +//config: depends on TOP +//config: help +//config: Enable 's' in top (gives lots of memory info). + #include "libbb.h" @@ -99,8 +153,13 @@ struct globals { #if ENABLE_FEATURE_TOP_SMP_CPU smallint smp_cpu_info; /* one/many cpu info lines? */ #endif + unsigned lines; /* screen height */ #if ENABLE_FEATURE_USE_TERMIOS struct termios initial_settings; + int scroll_ofs; +#define G_scroll_ofs G.scroll_ofs +#else +#define G_scroll_ofs 0 #endif #if !ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE cmp_funcp sort_function[1]; @@ -118,6 +177,9 @@ struct globals { jiffy_counts_t *cpu_jif, *cpu_prev_jif; int num_cpus; #endif +#if ENABLE_FEATURE_USE_TERMIOS + char kbd_input[KEYCODE_BUFFER_SIZE]; +#endif char line_buf[80]; }; //FIX_ALIASING; - large code growth enum { LINE_BUF_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line_buf) }; @@ -602,9 +664,9 @@ static NOINLINE void display_process_list(int lines_rem, int scr_width) /* Ok, all preliminary data is ready, go through the list */ scr_width += 2; /* account for leading '\n' and trailing NUL */ - if (lines_rem > ntop) - lines_rem = ntop; - s = top; + if (lines_rem > ntop - G_scroll_ofs) + lines_rem = ntop - G_scroll_ofs; + s = top + G_scroll_ofs; while (--lines_rem >= 0) { unsigned col; CALC_STAT(pmem, (s->vsz*pmem_scale + pmem_half) >> pmem_shift); @@ -649,14 +711,14 @@ static void clearmems(void) clear_username_cache(); free(top); top = NULL; - ntop = 0; } #if ENABLE_FEATURE_USE_TERMIOS static void reset_term(void) { - tcsetattr_stdin_TCSANOW(&initial_settings); + if (!OPT_BATCH_MODE) + tcsetattr_stdin_TCSANOW(&initial_settings); if (ENABLE_FEATURE_CLEAN_UP) { clearmems(); # if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE @@ -665,10 +727,10 @@ static void reset_term(void) } } -static void sig_catcher(int sig UNUSED_PARAM) +static void sig_catcher(int sig) { reset_term(); - _exit(EXIT_FAILURE); + kill_myself_with_sig(sig); } #endif /* FEATURE_USE_TERMIOS */ @@ -793,7 +855,7 @@ static NOINLINE void display_topmem_process_list(int lines_rem, int scr_width) { #define HDR_STR " PID VSZ VSZRW RSS (SHR) DIRTY (SHR) STACK" #define MIN_WIDTH sizeof(HDR_STR) - const topmem_status_t *s = topmem; + const topmem_status_t *s = topmem + G_scroll_ofs; display_topmem_header(scr_width, &lines_rem); strcpy(line_buf, HDR_STR " COMMAND"); @@ -801,8 +863,8 @@ static NOINLINE void display_topmem_process_list(int lines_rem, int scr_width) printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width, line_buf); lines_rem--; - if (lines_rem > ntop) - lines_rem = ntop; + if (lines_rem > ntop - G_scroll_ofs) + lines_rem = ntop - G_scroll_ofs; while (--lines_rem >= 0) { /* PID VSZ VSZRW RSS (SHR) DIRTY (SHR) COMMAND */ ulltoa6_and_space(s->pid , &line_buf[0*6]); @@ -856,26 +918,63 @@ enum { #if ENABLE_FEATURE_USE_TERMIOS static unsigned handle_input(unsigned scan_mask, unsigned interval) { - unsigned char c; struct pollfd pfd[1]; + if (option_mask32 & OPT_EOF) { + /* EOF on stdin ("top = ntop) + G_scroll_ofs = ntop - 1; + if (G_scroll_ofs < 0) + G_scroll_ofs = 0; + break; + } + c |= 0x20; /* lowercase */ if (c == 'q') return EXIT_MASK; @@ -896,7 +995,7 @@ static unsigned handle_input(unsigned scan_mask, unsigned interval) } # if ENABLE_FEATURE_SHOW_THREADS if (c == 'h' - IF_FEATURE_TOPMEM(&& scan_mask != TOPMEM_MASK) + IF_FEATURE_TOPMEM(&& scan_mask != TOPMEM_MASK) ) { scan_mask ^= PSSCAN_TASKS; continue; @@ -1011,7 +1110,7 @@ int top_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int top_main(int argc UNUSED_PARAM, char **argv) { int iterations; - unsigned lines, col; + unsigned col; unsigned interval; char *str_interval, *str_iterations; unsigned scan_mask = TOP_MASK; @@ -1062,10 +1161,13 @@ int top_main(int argc UNUSED_PARAM, char **argv) sort_function[0] = mem_sort; #endif + if (OPT_BATCH_MODE) { + option_mask32 |= OPT_EOF; + } #if ENABLE_FEATURE_USE_TERMIOS - tcgetattr(0, (void *) &initial_settings); - memcpy(&new_settings, &initial_settings, sizeof(new_settings)); - if (!OPT_BATCH_MODE) { + else { + tcgetattr(0, (void *) &initial_settings); + memcpy(&new_settings, &initial_settings, sizeof(new_settings)); /* unbuffered input, turn off echo */ new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL); tcsetattr_stdin_TCSANOW(&new_settings); @@ -1081,15 +1183,15 @@ int top_main(int argc UNUSED_PARAM, char **argv) procps_status_t *p = NULL; if (OPT_BATCH_MODE) { - lines = INT_MAX; + G.lines = INT_MAX; col = LINE_BUF_SIZE - 2; /* +2 bytes for '\n', NUL */ } else { - lines = 24; /* default */ + G.lines = 24; /* default */ col = 79; #if ENABLE_FEATURE_USE_TERMIOS /* We output to stdout, we need size of stdout (not stdin)! */ - get_terminal_width_height(STDOUT_FILENO, &col, &lines); - if (lines < 5 || col < 10) { + get_terminal_width_height(STDOUT_FILENO, &col, &G.lines); + if (G.lines < 5 || col < 10) { sleep(interval); continue; } @@ -1099,6 +1201,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) } /* read process IDs & status for all the processes */ + ntop = 0; while ((p = procps_scan(p, scan_mask)) != NULL) { int n; #if ENABLE_FEATURE_TOPMEM @@ -1165,10 +1268,10 @@ int top_main(int argc UNUSED_PARAM, char **argv) } #endif if (scan_mask != TOPMEM_MASK) - display_process_list(lines, col); + display_process_list(G.lines, col); #if ENABLE_FEATURE_TOPMEM else - display_topmem_process_list(lines, col); + display_topmem_process_list(G.lines, col); #endif clearmems(); if (iterations >= 0 && !--iterations) @@ -1176,11 +1279,7 @@ int top_main(int argc UNUSED_PARAM, char **argv) #if !ENABLE_FEATURE_USE_TERMIOS sleep(interval); #else - if (option_mask32 & OPT_EOF) - /* EOF on stdin ("top /* getrlimit */ /* Five applets here: chpst, envdir, envuidgid, setuidgid, softlimit. diff --git a/release/src/router/busybox/runit/runsv.c b/release/src/router/busybox/runit/runsv.c index ad8d84f74e..3e1a3c8e5e 100644 --- a/release/src/router/busybox/runit/runsv.c +++ b/release/src/router/busybox/runit/runsv.c @@ -172,7 +172,7 @@ static void update_status(struct svdir *s) } close(fd); if (rename_or_warn("supervise/pid.new", - s->islog ? "log/supervise/pid" : "log/supervise/pid"+4)) + s->islog ? "log/supervise/pid" : "log/supervise/pid"+4)) return; pidchanged = 0; } diff --git a/release/src/router/busybox/runit/svlogd.c b/release/src/router/busybox/runit/svlogd.c index b0ba21bb63..b7a0a6e713 100644 --- a/release/src/router/busybox/runit/svlogd.c +++ b/release/src/router/busybox/runit/svlogd.c @@ -601,12 +601,12 @@ static int buffer_pwrite(int n, char *s, unsigned len) while (fchdir(ld->fddir) == -1) pause2cannot("change directory, want remove old logfile", - ld->name); + ld->name); oldest[0] = 'A'; oldest[1] = oldest[27] = '\0'; while (!(d = opendir("."))) pause2cannot("open directory, want remove old logfile", - ld->name); + ld->name); errno = 0; while ((f = readdir(d))) if ((f->d_name[0] == '@') && (strlen(f->d_name) == 27)) { diff --git a/release/src/router/busybox/scripts/kconfig/mconf.c b/release/src/router/busybox/scripts/kconfig/mconf.c index d3f69f8f5a..006d037088 100644 --- a/release/src/router/busybox/scripts/kconfig/mconf.c +++ b/release/src/router/busybox/scripts/kconfig/mconf.c @@ -9,6 +9,8 @@ */ #define _XOPEN_SOURCE 700 +/* On Darwin, this may be needed to get SIGWINCH: */ +#define _DARWIN_C_SOURCE 1 #include #include @@ -443,6 +445,7 @@ static struct gstr get_relations_str(struct symbol **sym_arr) pid_t pid; +#ifdef SIGWINCH static void winch_handler(int sig) { if (!do_resize) { @@ -450,11 +453,11 @@ static void winch_handler(int sig) do_resize = 1; } } +#endif static int exec_conf(void) { int pipefd[2], stat, size; - struct sigaction sa; sigset_t sset, osset; sigemptyset(&sset); @@ -463,10 +466,15 @@ static int exec_conf(void) signal(SIGINT, SIG_DFL); - sa.sa_handler = winch_handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; - sigaction(SIGWINCH, &sa, NULL); +#ifdef SIGWINCH + { + struct sigaction sa; + sa.sa_handler = winch_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_RESTART; + sigaction(SIGWINCH, &sa, NULL); + } +#endif *argptr++ = NULL; diff --git a/release/src/router/busybox/selinux/chcon.c b/release/src/router/busybox/selinux/chcon.c index 88d0cfec61..f947c2c128 100644 --- a/release/src/router/busybox/selinux/chcon.c +++ b/release/src/router/busybox/selinux/chcon.c @@ -92,7 +92,7 @@ static int FAST_FUNC change_filedir_context( if (specified_context == NULL) { context = set_security_context_component(file_context, - user, role, type, range); + user, role, type, range); if (!context) { bb_error_msg("can't compute security context from %s", file_context); goto skip; @@ -121,15 +121,15 @@ static int FAST_FUNC change_filedir_context( } if ((option_mask32 & OPT_VERBOSE) || ((option_mask32 & OPT_CHANHES) && !fail)) { printf(!fail - ? "context of %s changed to %s\n" - : "can't change context of %s to %s\n", - fname, context_string); + ? "context of %s changed to %s\n" + : "can't change context of %s to %s\n", + fname, context_string); } if (!fail) { rc = TRUE; } else if ((option_mask32 & OPT_QUIET) == 0) { bb_error_msg("can't change context of %s to %s", - fname, context_string); + fname, context_string); } } else if (option_mask32 & OPT_VERBOSE) { printf("context of %s retained as %s\n", fname, context_string); @@ -181,7 +181,7 @@ int chcon_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_CHCON_LONG_OPTIONS if (option_mask32 & OPT_REFERENCE) { /* FIXME: lgetfilecon() should be used when '-h' is specified. - But current implementation follows the original one. */ + * But current implementation follows the original one. */ if (getfilecon(reference_file, &specified_context) < 0) bb_perror_msg_and_die("getfilecon('%s') failed", reference_file); } else @@ -201,10 +201,10 @@ int chcon_main(int argc UNUSED_PARAM, char **argv) fname[fname_len] = '\0'; if (recursive_action(fname, - 1<nfile.expfname; switch (redir->nfile.type) { case NFROM: - fname = redir->nfile.expfname; f = open(fname, O_RDONLY); if (f < 0) goto eopen; break; case NFROMTO: - fname = redir->nfile.expfname; f = open(fname, O_RDWR|O_CREAT, 0666); if (f < 0) goto ecreate; @@ -5124,7 +5129,6 @@ openredirect(union node *redir) #endif /* Take care of noclobber mode. */ if (Cflag) { - fname = redir->nfile.expfname; f = noclobberopen(fname); if (f < 0) goto ecreate; @@ -5132,13 +5136,11 @@ openredirect(union node *redir) } /* FALLTHROUGH */ case NCLOBBER: - fname = redir->nfile.expfname; f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666); if (f < 0) goto ecreate; break; case NAPPEND: - fname = redir->nfile.expfname; f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666); if (f < 0) goto ecreate; @@ -6138,7 +6140,9 @@ argstr(char *p, int flags, struct strlist *var_str_list) length++; goto addquote; case CTLVAR: + TRACE(("argstr: evalvar('%s')\n", p)); p = evalvar(p, flags, var_str_list); + TRACE(("argstr: evalvar:'%s'\n", (char *)stackblock())); goto start; case CTLBACKQ: c = '\0'; @@ -6335,7 +6339,8 @@ subevalvar(char *p, char *varname, int strloc, int subtype, IF_ASH_BASH_COMPAT(const char *repl = NULL;) IF_ASH_BASH_COMPAT(int pos, len, orig_len;) int saveherefd = herefd; - int amount, workloc, resetloc; + int amount, resetloc; + IF_ASH_BASH_COMPAT(int workloc;) int zero; char *(*scan)(char*, char*, char*, char*, int, int); @@ -6448,9 +6453,9 @@ subevalvar(char *p, char *varname, int strloc, int subtype, rmescend--; str = (char *)stackblock() + strloc; preglob(str, varflags & VSQUOTE, 0); - workloc = expdest - (char *)stackblock(); #if ENABLE_ASH_BASH_COMPAT + workloc = expdest - (char *)stackblock(); if (subtype == VSREPLACE || subtype == VSREPLACEALL) { char *idx, *end; @@ -7248,6 +7253,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag) STARTSTACKSTR(expdest); ifsfirst.next = NULL; ifslastp = NULL; + TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag)); argstr(arg->narg.text, flag, /* var_str_list: */ arglist ? arglist->list : NULL); p = _STPUTC('\0', expdest); @@ -7256,6 +7262,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag) return; /* here document expanded */ } p = grabstackstr(p); + TRACE(("expandarg: p:'%s'\n", p)); exparg.lastp = &exparg.list; /* * TODO - EXP_REDIR @@ -7266,8 +7273,10 @@ expandarg(union node *arg, struct arglist *arglist, int flag) exparg.lastp = &exparg.list; expandmeta(exparg.list /*, flag*/); } else { - if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */ + if (flag & EXP_REDIR) { /*XXX - for now, just remove escapes */ rmescapes(p, 0); + TRACE(("expandarg: rmescapes:'%s'\n", p)); + } sp = stzalloc(sizeof(*sp)); sp->text = p; *exparg.lastp = sp; @@ -7418,11 +7427,29 @@ tryexec(IF_FEATURE_SH_STANDALONE(int applet_no,) char *cmd, char **argv, char ** #else execve(cmd, argv, envp); #endif - if (cmd == (char*) bb_busybox_exec_path) { + if (cmd == (char*) bb_busybox_exec_path) { + /* We already visited ENOEXEC branch below, don't do it again */ +//TODO: try execve(initial_argv0_of_shell, argv, envp) before giving up? free(argv); return; } if (errno == ENOEXEC) { + /* Run "cmd" as a shell script: + * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html + * "If the execve() function fails with ENOEXEC, the shell + * shall execute a command equivalent to having a shell invoked + * with the command name as its first operand, + * with any remaining arguments passed to the new shell" + * + * That is, do not use $SHELL, user's shell, or /bin/sh; + * just call ourselves. + * + * Note that bash reads ~80 chars of the file, and if it sees + * a zero byte before it sees newline, it doesn't try to + * interpret it, but fails with "cannot execute binary file" + * message and exit code 126. For one, this prevents attempts + * to interpret foreign ELF binaries as shell scripts. + */ char **ap; char **new; @@ -8646,9 +8673,21 @@ expredir(union node *n) case NCLOBBER: case NAPPEND: expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); + TRACE(("expredir expanded to '%s'\n", fn.list->text)); #if ENABLE_ASH_BASH_COMPAT store_expfname: #endif +#if 0 +// By the design of stack allocator, the loop of this kind: +// while true; do while true; do break; done nfile.expfname) + stunalloc(redir->nfile.expfname); +// It results in corrupted state of stacked allocations. +#endif redir->nfile.expfname = fn.list->text; break; case NFROMFD: @@ -9284,11 +9323,11 @@ evalcommand(union node *cmd, int flags) /* Now locate the command. */ if (argc) { - const char *oldpath; int cmd_flag = DO_ERR; - +#if ENABLE_ASH_CMDCMD + const char *oldpath = path + 5; +#endif path += 5; - oldpath = path; for (;;) { find_command(argv[0], &cmdentry, cmd_flag, path); if (cmdentry.cmdtype == CMDUNKNOWN) { @@ -11611,8 +11650,9 @@ parsebackq: { INT_ON; if (oldstyle) { /* We must read until the closing backquote, giving special - treatment to some slashes, and then push the string and - reread it as input, interpreting it normally. */ + * treatment to some slashes, and then push the string and + * reread it as input, interpreting it normally. + */ char *pout; size_t psavelen; char *pstr; @@ -12603,18 +12643,27 @@ exportcmd(int argc UNUSED_PARAM, char **argv) char *name; const char *p; char **aptr; - int flag = argv[0][0] == 'r' ? VREADONLY : VEXPORT; - int mask = ~0; - int nopt; - while ((nopt = nextopt("np"))) { - if (nopt == 'n') { - mask = ~flag; - } else { /* p */ - break; - } + char opt; + int flag; + int flag_off; + + /* "readonly" in bash accepts, but ignores -n. + * We do the same: it saves a conditional in nextopt's param. + */ + flag_off = 0; + while ((opt = nextopt("np")) != '\0') { + if (opt == 'n') + flag_off = VEXPORT; + } + flag = VEXPORT; + if (argv[0][0] == 'r') { + flag = VREADONLY; + flag_off = 0; /* readonly ignores -n */ } + flag_off = ~flag_off; - if (nopt != 'p') { + /*if (opt_p_not_specified) - bash doesnt check this. Try "export -p NAME" */ + { aptr = argptr; name = *aptr; if (name) { @@ -12625,17 +12674,19 @@ exportcmd(int argc UNUSED_PARAM, char **argv) } else { vp = *findvar(hashvar(name), name); if (vp) { - vp->flags |= flag; - vp->flags &= mask; + vp->flags = ((vp->flags | flag) & flag_off); continue; } } - setvar(name, p, flag); - setvar(name, p, flag & mask); + setvar(name, p, (flag & flag_off)); } while ((name = *++aptr) != NULL); return 0; } } + + /* No arguments. Show the list of exported or readonly vars. + * -n is ignored. + */ showvars(argv[0], flag, 0); return 0; } @@ -12788,6 +12839,10 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) } } + /* "read -s" needs to save/restore termios, can't allow ^C + * to jump out of it. + */ + INT_OFF; r = shell_builtin_read(setvar2, argptr, bltinlookup("IFS"), /* can be NULL */ @@ -12797,6 +12852,7 @@ readcmd(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) opt_t, opt_u ); + INT_ON; if ((uintptr_t)r > 1) ash_msg_and_raise_error(r); diff --git a/release/src/router/busybox/shell/ash_test/ash-redir/redirA.right b/release/src/router/busybox/shell/ash_test/ash-redir/redirA.right new file mode 100644 index 0000000000..31406e336b --- /dev/null +++ b/release/src/router/busybox/shell/ash_test/ash-redir/redirA.right @@ -0,0 +1,2 @@ +tmp11 +tmp11 diff --git a/release/src/router/busybox/shell/ash_test/ash-redir/redirA.tests b/release/src/router/busybox/shell/ash_test/ash-redir/redirA.tests new file mode 100644 index 0000000000..56833f9386 --- /dev/null +++ b/release/src/router/busybox/shell/ash_test/ash-redir/redirA.tests @@ -0,0 +1,11 @@ +x="tmp11:tmp22" + +# Bug was incorrectly expanding variables in >redir +echo "${x%:*}" >"${x%:*}" +echo tmp1* +rm tmp1* + +# Also try unquoted +echo "${x%:*}" >${x%:*} +echo tmp1* +rm tmp1* diff --git a/release/src/router/busybox/shell/hush.c b/release/src/router/busybox/shell/hush.c index 51d38d3aef..e2dc1e2d00 100644 --- a/release/src/router/busybox/shell/hush.c +++ b/release/src/router/busybox/shell/hush.c @@ -106,10 +106,6 @@ # define PIPE_BUF 4096 /* amount of buffering in a pipe */ #endif -/* Not every libc has sighandler_t. Fix it */ -typedef void (*hush_sighandler_t)(int); -#define sighandler_t hush_sighandler_t - //config:config HUSH //config: bool "hush" //config: default y @@ -4223,7 +4219,7 @@ static struct pipe *parse_stream(char **pstring, /* (this makes bare "&" cmd a no-op. * bash says: "syntax error near unexpected token '&'") */ if (pi->num_cmds == 0 - IF_HAS_KEYWORDS( && pi->res_word == RES_NONE) + IF_HAS_KEYWORDS(&& pi->res_word == RES_NONE) ) { free_pipe_list(pi); pi = NULL; @@ -4376,7 +4372,7 @@ static struct pipe *parse_stream(char **pstring, debug_printf_parse("dest.o_assignment='%s'\n", assignment_flag[dest.o_assignment]); /* Do we sit outside of any if's, loops or case's? */ if (!HAS_KEYWORDS - IF_HAS_KEYWORDS(|| (ctx.ctx_res_w == RES_NONE && ctx.old_flag == 0)) + IF_HAS_KEYWORDS(|| (ctx.ctx_res_w == RES_NONE && ctx.old_flag == 0)) ) { o_free(&dest); #if !BB_MMU @@ -8285,7 +8281,7 @@ static int FAST_FUNC builtin_exit(char **argv) * (if there are _stopped_ jobs, running ones don't count) * # exit * exit - # EEE (then bash exits) + * EEE (then bash exits) * * TODO: we can use G.exiting = -1 as indicator "last cmd was exit" */ diff --git a/release/src/router/busybox/shell/math.c b/release/src/router/busybox/shell/math.c index 760645d0f9..15c0039652 100644 --- a/release/src/router/busybox/shell/math.c +++ b/release/src/router/busybox/shell/math.c @@ -410,7 +410,7 @@ arith_apply(arith_state_t *math_state, operator op, var_or_num_t *numstack, var_ return "exponent less than 0"; c = 1; while (--right_side_val >= 0) - c *= rez; + c *= rez; rez = c; } else if (right_side_val == 0) diff --git a/release/src/router/busybox/shell/shell_common.c b/release/src/router/busybox/shell/shell_common.c index 51c92d60e9..0051f21d9e 100644 --- a/release/src/router/busybox/shell/shell_common.c +++ b/release/src/router/busybox/shell/shell_common.c @@ -18,6 +18,7 @@ */ #include "libbb.h" #include "shell_common.h" +#include /* getrlimit */ const char defifsvar[] ALIGN1 = "IFS= \t\n"; @@ -169,7 +170,7 @@ shell_builtin_read(void FAST_FUNC (*setvar)(const char *name, const char *val), int timeout; if ((bufpos & 0xff) == 0) - buffer = xrealloc(buffer, bufpos + 0x100); + buffer = xrealloc(buffer, bufpos + 0x101); timeout = -1; if (end_ms) { diff --git a/release/src/router/busybox/shell/shell_common.h b/release/src/router/busybox/shell/shell_common.h index f06bc41208..993ed59511 100644 --- a/release/src/router/busybox/shell/shell_common.h +++ b/release/src/router/busybox/shell/shell_common.h @@ -21,7 +21,7 @@ PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN -extern const char defifsvar[]; /* "IFS= \t\n" */ +extern const char defifsvar[] ALIGN1; /* "IFS= \t\n" */ #define defifs (defifsvar + 4) int FAST_FUNC is_well_formed_var_name(const char *s, char terminator); diff --git a/release/src/router/busybox/sysklogd/Config.src b/release/src/router/busybox/sysklogd/Config.src index b7a494eff0..fcf993054f 100644 --- a/release/src/router/busybox/sysklogd/Config.src +++ b/release/src/router/busybox/sysklogd/Config.src @@ -113,6 +113,19 @@ config FEATURE_LOGREAD_REDUCED_LOCKING from circular buffer, minimizing semaphore contention at some minor memory expense. +config FEATURE_KMSG_SYSLOG + bool "Linux kernel printk buffer support" + default y + depends on SYSLOGD + select PLATFORM_LINUX + help + When you enable this feature, the syslogd utility will + write system log message to the Linux kernel's printk buffer. + This can be used as a smaller alternative to the syslogd IPC + support, as klogd and logread aren't needed. + + NOTICE: Syslog facilities in log entries needs kernel 3.5+. + config KLOGD bool "klogd" default y @@ -123,6 +136,9 @@ config KLOGD you wish to record the messages produced by the kernel, you should enable this option. +comment "klogd should not be used together with syslog to kernel printk buffer" + depends on KLOGD && FEATURE_KMSG_SYSLOG + config FEATURE_KLOGD_KLOGCTL bool "Use the klogctl() interface" default y diff --git a/release/src/router/busybox/sysklogd/klogd.c b/release/src/router/busybox/sysklogd/klogd.c index cb9ad1a498..a65053c3a0 100644 --- a/release/src/router/busybox/sysklogd/klogd.c +++ b/release/src/router/busybox/sysklogd/klogd.c @@ -196,6 +196,8 @@ int klogd_main(int argc UNUSED_PARAM, char **argv) syslog(LOG_NOTICE, "klogd started: %s", bb_banner); + write_pidfile(CONFIG_PID_FILE_PATH "/klogd.pid"); + used = 0; cnt = 0; while (!bb_got_signal) { @@ -242,11 +244,8 @@ int klogd_main(int argc UNUSED_PARAM, char **argv) priority = LOG_INFO; if (*start == '<') { start++; - if (*start) { - /* kernel never generates multi-digit prios */ - priority = (*start - '0'); - start++; - } + if (*start) + priority = strtoul(start, &start, 10); if (*start == '>') start++; } @@ -267,6 +266,7 @@ int klogd_main(int argc UNUSED_PARAM, char **argv) klogd_close(); syslog(LOG_NOTICE, "klogd: exiting"); + remove_pidfile(CONFIG_PID_FILE_PATH "/klogd.pid"); if (bb_got_signal) kill_myself_with_sig(bb_got_signal); return EXIT_FAILURE; diff --git a/release/src/router/busybox/sysklogd/syslogd.c b/release/src/router/busybox/sysklogd/syslogd.c index 88da983cc0..3fe3f5348b 100644 --- a/release/src/router/busybox/sysklogd/syslogd.c +++ b/release/src/router/busybox/sysklogd/syslogd.c @@ -43,6 +43,9 @@ //usage: "\n -f FILE Use FILE as config (default:/etc/syslog.conf)" //usage: ) /* //usage: "\n -m MIN Minutes between MARK lines (default:20, 0=off)" */ +//usage: IF_FEATURE_KMSG_SYSLOG( +//usage: "\n -K Log to kernel printk buffer (use dmesg to read it)" +//usage: ) //usage: //usage:#define syslogd_example_usage //usage: "$ syslogd -R masterlog:514\n" @@ -140,6 +143,10 @@ IF_FEATURE_IPC_SYSLOG( \ ) \ IF_FEATURE_SYSLOGD_CFG( \ logRule_t *log_rules; \ +) \ +IF_FEATURE_KMSG_SYSLOG( \ + int kmsgfd; \ + int primask; \ ) struct init_globals { @@ -212,6 +219,7 @@ enum { IF_FEATURE_IPC_SYSLOG( OPTBIT_circularlog,) // -C IF_FEATURE_SYSLOGD_DUP( OPTBIT_dup ,) // -D IF_FEATURE_SYSLOGD_CFG( OPTBIT_cfg ,) // -f + IF_FEATURE_KMSG_SYSLOG( OPTBIT_kmsg ,) // -K OPT_mark = 1 << OPTBIT_mark , OPT_nofork = 1 << OPTBIT_nofork , @@ -225,6 +233,8 @@ enum { OPT_circularlog = IF_FEATURE_IPC_SYSLOG( (1 << OPTBIT_circularlog)) + 0, OPT_dup = IF_FEATURE_SYSLOGD_DUP( (1 << OPTBIT_dup )) + 0, OPT_cfg = IF_FEATURE_SYSLOGD_CFG( (1 << OPTBIT_cfg )) + 0, + OPT_kmsg = IF_FEATURE_KMSG_SYSLOG( (1 << OPTBIT_kmsg )) + 0, + }; #define OPTION_STR "m:nO:l:S" \ IF_FEATURE_ROTATE_LOGFILE("s:" ) \ @@ -233,7 +243,8 @@ enum { IF_FEATURE_REMOTE_LOG( "L" ) \ IF_FEATURE_IPC_SYSLOG( "C::") \ IF_FEATURE_SYSLOGD_DUP( "D" ) \ - IF_FEATURE_SYSLOGD_CFG( "f:" ) + IF_FEATURE_SYSLOGD_CFG( "f:" ) \ + IF_FEATURE_KMSG_SYSLOG( "K" ) #define OPTION_DECL *opt_m, *opt_l \ IF_FEATURE_ROTATE_LOGFILE(,*opt_s) \ IF_FEATURE_ROTATE_LOGFILE(,*opt_b) \ @@ -242,7 +253,7 @@ enum { #define OPTION_PARAM &opt_m, &(G.logFile.path), &opt_l \ IF_FEATURE_ROTATE_LOGFILE(,&opt_s) \ IF_FEATURE_ROTATE_LOGFILE(,&opt_b) \ - IF_FEATURE_REMOTE_LOG( ,&remoteAddrList) \ + IF_FEATURE_REMOTE_LOG( ,&remoteAddrList) \ IF_FEATURE_IPC_SYSLOG( ,&opt_C) \ IF_FEATURE_SYSLOGD_CFG( ,&opt_f) @@ -418,7 +429,9 @@ static void parse_syslogdcfg(const char *file) return; cfgerr: - bb_error_msg_and_die("error in '%s' at line %d", file, parser->lineno); + bb_error_msg_and_die("error in '%s' at line %d", + file ? file : "/etc/syslog.conf", + parser->lineno); } #endif @@ -518,11 +531,48 @@ static void log_to_shmem(const char *msg) printf("tail:%d\n", G.shbuf->tail); } #else -void ipcsyslog_cleanup(void); -void ipcsyslog_init(void); +static void ipcsyslog_cleanup(void) {} +static void ipcsyslog_init(void) {} void log_to_shmem(const char *msg); #endif /* FEATURE_IPC_SYSLOG */ +#if ENABLE_FEATURE_KMSG_SYSLOG +static void kmsg_init(void) +{ + G.kmsgfd = xopen("/dev/kmsg", O_WRONLY); + + /* + * kernel < 3.5 expects single char printk KERN_* priority prefix, + * from 3.5 onwards the full syslog facility/priority format is supported + */ + if (get_linux_version_code() < KERNEL_VERSION(3,5,0)) + G.primask = LOG_PRIMASK; + else + G.primask = -1; +} + +static void kmsg_cleanup(void) +{ + if (ENABLE_FEATURE_CLEAN_UP) + close(G.kmsgfd); +} + +/* Write message to /dev/kmsg */ +static void log_to_kmsg(int pri, const char *msg) +{ + /* + * kernel < 3.5 expects single char printk KERN_* priority prefix, + * from 3.5 onwards the full syslog facility/priority format is supported + */ + pri &= G.primask; + + write(G.kmsgfd, G.printbuf, sprintf(G.printbuf, "<%d>%s\n", pri, msg)); +} +#else +static void kmsg_init(void) {} +static void kmsg_cleanup(void) {} +static void log_to_kmsg(int pri UNUSED_PARAM, const char *msg UNUSED_PARAM) {} +#endif /* FEATURE_KMSG_SYSLOG */ /* Print a message to the log file. */ static void log_locally(time_t now, char *msg, logFile_t *log_file) @@ -658,6 +708,11 @@ static void timestamp_and_log(int pri, char *msg, int len) } timestamp[15] = '\0'; + if (option_mask32 & OPT_kmsg) { + log_to_kmsg(pri, msg); + return; + } + if (option_mask32 & OPT_small) sprintf(G.printbuf, "%s %s\n", timestamp, msg); else { @@ -828,9 +883,11 @@ static void do_syslogd(void) #endif sock_fd = create_socket(); - if (ENABLE_FEATURE_IPC_SYSLOG && (option_mask32 & OPT_circularlog)) { + if (option_mask32 & OPT_circularlog) ipcsyslog_init(); - } + + if (option_mask32 & OPT_kmsg) + kmsg_init(); timestamp_and_log_internal("syslogd started: BusyBox v" BB_VER); @@ -917,8 +974,10 @@ static void do_syslogd(void) timestamp_and_log_internal("syslogd exiting"); puts("syslogd exiting"); - if (ENABLE_FEATURE_IPC_SYSLOG) - ipcsyslog_cleanup(); + remove_pidfile(CONFIG_PID_FILE_PATH "/syslogd.pid"); + ipcsyslog_cleanup(); + if (option_mask32 & OPT_kmsg) + kmsg_cleanup(); kill_myself_with_sig(bb_got_signal); #undef recvbuf } @@ -980,8 +1039,10 @@ int syslogd_main(int argc UNUSED_PARAM, char **argv) if (!(opts & OPT_nofork)) { bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); } + //umask(0); - why?? - write_pidfile("/var/run/syslogd.pid"); + write_pidfile(CONFIG_PID_FILE_PATH "/syslogd.pid"); + do_syslogd(); /* return EXIT_SUCCESS; */ } diff --git a/release/src/router/busybox/testsuite/awk.tests b/release/src/router/busybox/testsuite/awk.tests index 5a323047db..f9c3b6b4d0 100755 --- a/release/src/router/busybox/testsuite/awk.tests +++ b/release/src/router/busybox/testsuite/awk.tests @@ -16,6 +16,13 @@ testing "awk -F case 5" "awk -F '[#]' '{ print NF }'" "4\n" "" "#abc##zz\n" testing "awk -F case 6" "awk -F '[#]' '{ print NF }'" "4\n" "" "z#abc##zz\n" testing "awk -F case 7" "awk -F '[#]' '{ print NF }'" "5\n" "" "z##abc##zz\n" +# conditions and operators +testing "awk if operator == " "awk 'BEGIN{if(23==23) print \"foo\"}'" "foo\n" "" "" +testing "awk if operator != " "awk 'BEGIN{if(23!=23) print \"bar\"}'" "" "" "" +testing "awk if operator >= " "awk 'BEGIN{if(23>=23) print \"foo\"}'" "foo\n" "" "" +testing "awk if operator < " "awk 'BEGIN{if(2 < 13) print \"foo\"}'" "foo\n" "" "" +testing "awk if string == " "awk 'BEGIN{if(\"a\"==\"ab\") print \"bar\"}'" "" "" "" + # 4294967295 = 0xffffffff testing "awk bitwise op" "awk '{ print or(4294967295,1) }'" "4.29497e+09\n" "" "\n" optional DESKTOP @@ -36,6 +43,11 @@ testing "awk long field sep" "awk -F-- '{ print NF, length(\$NF), \$NF }'" \ "" \ "a--\na--b--\na--b--c--\na--b--c--d--" +testing "awk -F handles escapes" "awk -F'\\x21' '{print \$1}'" \ + "a\n" \ + "" \ + "a!b\n" + # '@(samp|code|file)\{' is an invalid extended regex (unmatched '{'), # but gawk 3.1.5 does not bail out on it. testing "awk gsub falls back to non-extended-regex" \ @@ -205,4 +217,11 @@ end d testing "awk handles empty ()" \ "awk 'BEGIN {print()}' 2>&1" "awk: cmd. line:1: Empty sequence\n" "" "" +testing "awk FS assignment" "awk '{FS=\":\"; print \$1}'" \ + "a:b\ne\n" \ + "" \ + "a:b c:d\ne:f g:h" + +# testing "description" "command" "result" "infile" "stdin" + exit $FAILCOUNT diff --git a/release/src/router/busybox/testsuite/du/du-k-works b/release/src/router/busybox/testsuite/du/du-k-works index 229a948ee0..36dcaa85da 100644 --- a/release/src/router/busybox/testsuite/du/du-k-works +++ b/release/src/router/busybox/testsuite/du/du-k-works @@ -3,4 +3,5 @@ cd du.testdir dd if=/dev/zero of=file1 bs=1k count=64 2>/dev/null dd if=/dev/zero of=file2 bs=1k count=16 2>/dev/null test x"`busybox du -k .`" = x"80 ." \ + -o x"`busybox du -k .`" = x"84 ." \ -o x"`busybox du -k .`" = x"88 ." diff --git a/release/src/router/busybox/testsuite/grep.tests b/release/src/router/busybox/testsuite/grep.tests index 006a215e1b..4781f22847 100755 --- a/release/src/router/busybox/testsuite/grep.tests +++ b/release/src/router/busybox/testsuite/grep.tests @@ -115,6 +115,18 @@ testing "grep -v -f EMPTY_FILE" \ "" \ "test\n" +testing "grep -Fw matches only words" \ + "grep -Fw foo input" \ + "" \ + "foop\n" \ + "" + +testing "grep -Fw doesn't stop on 1st mismatch" \ + "grep -Fw foo input" \ + "foop foo\n" \ + "foop foo\n" \ + "" + # testing "test name" "commands" "expected result" "file input" "stdin" # file input will be file called "input" # test can create a file "actual" instead of writing to stdout diff --git a/release/src/router/busybox/testsuite/mdev.tests b/release/src/router/busybox/testsuite/mdev.tests index 7320e17ddb..48d3dcc2c3 100755 --- a/release/src/router/busybox/testsuite/mdev.tests +++ b/release/src/router/busybox/testsuite/mdev.tests @@ -11,7 +11,7 @@ FILTER_LS="grep -v '^total ' | sed -e 's/, */,/g' -e 's/ */ /g' | cut -d' ' -f # cut: remove size+date FILTER_LS2="grep -v '^total ' | sed -e 's/, */,/g' -e 's/ */ /g' | cut -d' ' -f 1-4,9-" -# testing "test name" "options" "expected result" "file input" "stdin" +# testing "test name" "commands" "expected result" "file input" "stdin" rm -rf mdev.testdir mkdir mdev.testdir @@ -128,6 +128,26 @@ SKIP= # continuing to use directory structure from prev test rm -rf mdev.testdir/dev/* +echo "sda 0:0 444 =disk/sd/a" >mdev.testdir/etc/mdev.conf +optional STATIC FEATURE_MDEV_CONF FEATURE_MDEV_RENAME FEATURE_LS_RECURSIVE FEATURE_LS_TIMESTAMPS FEATURE_LS_USERNAME +testing "mdev move rule '=bar/baz/fname'" \ + "env - PATH=$PATH ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1; + ls -lnR mdev.testdir/dev | $FILTER_LS2" \ +"\ +mdev.testdir/dev: +drwxr-xr-x 3 0 0 disk + +mdev.testdir/dev/disk: +drwxr-xr-x 2 0 0 sd + +mdev.testdir/dev/disk/sd: +br--r--r-- 1 0 0 a +" \ + "" "" +SKIP= + +# continuing to use directory structure from prev test +rm -rf mdev.testdir/dev/* # here we complicate things by having non-matching group 1 and using %0 echo "s([0-9])*d([a-z]+) 0:0 644 >sd/%2_%0" >mdev.testdir/etc/mdev.conf optional STATIC FEATURE_MDEV_CONF FEATURE_MDEV_RENAME FEATURE_MDEV_RENAME_REGEXP FEATURE_LS_RECURSIVE FEATURE_LS_TIMESTAMPS FEATURE_LS_USERNAME FEATURE_LS_SORTFILES diff --git a/release/src/router/busybox/testsuite/mkfs.minix.tests b/release/src/router/busybox/testsuite/mkfs.minix.tests index 8a33c16813..324eaafced 100755 --- a/release/src/router/busybox/testsuite/mkfs.minix.tests +++ b/release/src/router/busybox/testsuite/mkfs.minix.tests @@ -8,6 +8,14 @@ # testing "test name" "options" "expected result" "file input" "stdin" +# '\n' produces 10 on little endian, but not on big endian +cr=`echo | od -i | sed 's/ *$//g;s/.* //g;2d'` +if [ x"$cr" = x"10" ]; then + hash=4f35f7afeba07d56055bed1f29ae20b7 +else + hash=5adbc1b3ccd20ca5d0ab5bc1e13ac3fc +fi + testing "mkfs.minix" \ "dd if=/dev/zero of=input bs=1k count=1024 2>/dev/null; mkfs.minix input; md5sum &1 +umount -d mount.dir 2>/dev/null +rmdir mount.dir 2>/dev/null +mkdir -p mount.dir +( +cd mount.dir || { echo 'cd error'; exit 1; } +mkdir z1 z2 || { echo 'mkdir error'; exit 1; } +mount -t tmpfs tmpfs z1 || { echo 'mount tmpfs error'; exit 1; } +dd if=/dev/zero of=z1/e2img count=10 bs=1M 2>/dev/null || { echo 'dd error'; exit 1; } +mke2fs -F z1/e2img 2>/dev/null >&2 || { echo 'mke2fs error'; exit 1; } +mount -r -o loop -t ext2 z1/e2img z2 || { echo 'mount -r -o loop error'; exit 1; } +mount -o remount,ro z1 || { echo 'mount -o remount,ro error'; exit 1; } +) +umount -d mount.dir/z2 +##losetup -d /dev/loop* +umount -d mount.dir/z1 +rm -rf mount.dir +echo DONE +" \ +"DONE\n" "" "" + + exit $FAILCOUNT diff --git a/release/src/router/busybox/testsuite/sed.tests b/release/src/router/busybox/testsuite/sed.tests index ba163e9e92..468565f470 100755 --- a/release/src/router/busybox/testsuite/sed.tests +++ b/release/src/router/busybox/testsuite/sed.tests @@ -48,13 +48,12 @@ testing "sed accepts multiple -e" "sed -e 'i\' -e '1' -e 'a\' -e '3'" \ # substitutions testing "sed -n" "sed -n -e s/foo/bar/ -e s/bar/baz/" "" "" "foo\n" +testing "sed with empty match" "sed 's/z*//g'" "string\n" "" "string\n" testing "sed s//p" "sed -e s/foo/bar/p -e s/bar/baz/p" "bar\nbaz\nbaz\n" \ "" "foo\n" testing "sed -n s//p" "sed -ne s/abc/def/p" "def\n" "" "abc\n" -test x"$SKIP_KNOWN_BUGS" = x"" && { testing "sed s//g (exhaustive)" "sed -e 's/[[:space:]]*/,/g'" ",1,2,3,4,5,\n" \ "" "12345\n" -} testing "sed s arbitrary delimiter" "sed -e 's woo boing '" "boing\n" "" "woo\n" testing "sed s chains" "sed -e s/foo/bar/ -e s/bar/baz/" "baz\n" "" "foo\n" testing "sed s chains2" "sed -e s/foo/bar/ -e s/baz/nee/" "bar\n" "" "foo\n" @@ -295,6 +294,22 @@ testing "sed -i finishes ranges correctly" \ "sed '1,2d' -i input; echo \$?; cat input" \ "0\n3\n4\n" "1\n2\n3\n4\n" "" +testing "sed zero chars match/replace advances correctly 1" \ + "sed 's/l*/@/g'" \ + "@h@e@o@\n" "" "helllo\n" + +testing "sed zero chars match/replace advances correctly 2" \ + "sed 's [^ .]* x g'" \ + "x x.x\n" "" " a.b\n" + +testing "sed zero chars match/replace logic must not falsely trigger here 1" \ + "sed 's/a/A/g'" \ + "_AAA1AA\n" "" "_aaa1aa\n" + +testing "sed zero chars match/replace logic must not falsely trigger here 2" \ + "sed 's/ *$/_/g'" \ + "qwerty_\n" "" "qwerty\n" + # testing "description" "commands" "result" "infile" "stdin" exit $FAILCOUNT diff --git a/release/src/router/busybox/testsuite/sha3sum.tests b/release/src/router/busybox/testsuite/sha3sum.tests new file mode 100644 index 0000000000..82fada633f --- /dev/null +++ b/release/src/router/busybox/testsuite/sha3sum.tests @@ -0,0 +1,3 @@ +#!/bin/sh + +. ./md5sum.tests sha3sum c29d77bc548fa2b20a04c861400a5360879c52156e2a54a3415b99a9a3123e1d5f36714a24eca8c1f05a8e2d8ba859c930d41141f64a255c6794436fc99c486a diff --git a/release/src/router/busybox/util-linux/Config.src b/release/src/router/busybox/util-linux/Config.src index 32a9c18b03..6c1b928daf 100644 --- a/release/src/router/busybox/util-linux/Config.src +++ b/release/src/router/busybox/util-linux/Config.src @@ -771,6 +771,13 @@ config FEATURE_VOLUMEID_XFS help TODO +config FEATURE_VOLUMEID_NILFS + bool "nilfs filesystem" + default y + depends on VOLUMEID + help + TODO + config FEATURE_VOLUMEID_NTFS bool "ntfs filesystem" default y @@ -834,6 +841,16 @@ config FEATURE_VOLUMEID_ROMFS help TODO +config FEATURE_VOLUMEID_SQUASHFS + bool "SquashFS filesystem" + default y + depends on VOLUMEID && FEATURE_BLKID_TYPE + help + Squashfs is a compressed read-only filesystem for Linux. Squashfs is + intended for general read-only filesystem use and in constrained block + device/memory systems (e.g. embedded systems) where low overhead is + needed. + config FEATURE_VOLUMEID_SYSV bool "sysv filesystem" default y diff --git a/release/src/router/busybox/util-linux/acpid.c b/release/src/router/busybox/util-linux/acpid.c index 1b22f3a01c..38421c2d7f 100644 --- a/release/src/router/busybox/util-linux/acpid.c +++ b/release/src/router/busybox/util-linux/acpid.c @@ -75,6 +75,7 @@ struct acpi_event { static const struct acpi_event f_evt_tab[] = { { "EV_KEY", 0x01, "KEY_POWER", 116, 1, "button/power PWRF 00000080" }, { "EV_KEY", 0x01, "KEY_POWER", 116, 1, "button/power PWRB 00000080" }, + { "EV_SW", 0x05, "SW_LID", 0x00, 1, "button/lid LID0 00000080" }, }; struct acpi_action { @@ -234,7 +235,7 @@ int acpid_main(int argc UNUSED_PARAM, char **argv) const char *opt_action = "/etc/acpid.conf"; const char *opt_map = "/etc/acpi.map"; #if ENABLE_FEATURE_PIDFILE - const char *opt_pidfile = "/var/run/acpid.pid"; + const char *opt_pidfile = CONFIG_PID_FILE_PATH "/acpid.pid"; #endif INIT_G(); diff --git a/release/src/router/busybox/util-linux/dmesg.c b/release/src/router/busybox/util-linux/dmesg.c index 6505da54bc..81ba1c9d14 100644 --- a/release/src/router/busybox/util-linux/dmesg.c +++ b/release/src/router/busybox/util-linux/dmesg.c @@ -59,16 +59,15 @@ int dmesg_main(int argc UNUSED_PARAM, char **argv) int last = '\n'; int in = 0; - /* Skip <#> at the start of lines */ + /* Skip <[0-9]+> at the start of lines */ while (1) { if (last == '\n' && buf[in] == '<') { - in += 3; - if (in >= len) - break; + while (buf[in++] != '>' && in < len) + ; + } else { + last = buf[in++]; + putchar(last); } - last = buf[in]; - putchar(last); - in++; if (in >= len) break; } diff --git a/release/src/router/busybox/util-linux/fbset.c b/release/src/router/busybox/util-linux/fbset.c index 196c2aa24b..e9aacce4f2 100644 --- a/release/src/router/busybox/util-linux/fbset.c +++ b/release/src/router/busybox/util-linux/fbset.c @@ -271,7 +271,7 @@ static int read_mode_db(struct fb_var_screeninfo *base, const char *fn, } p = token[1]; i = index_in_strings( - "geometry\0timings\0interlaced\0double\0vsync\0hsync\0csync\0extsync\0", + "geometry\0timings\0interlaced\0double\0vsync\0hsync\0csync\0extsync\0rgba\0", token[0]); switch (i) { case 0: @@ -342,6 +342,30 @@ static int read_mode_db(struct fb_var_screeninfo *base, const char *fn, ss(&base->sync, FB_SYNC_EXT, p, "false"); //bb_info_msg("EXTSYNC[%s]", p); break; + case 8: { + int red_offset, red_length; + int green_offset, green_length; + int blue_offset, blue_length; + int transp_offset, transp_length; + + sscanf(p, "%d/%d,%d/%d,%d/%d,%d/%d", + &red_offset, &red_length, + &green_offset, &green_length, + &blue_offset, &blue_length, + &transp_offset, &transp_length); + base->red.offset = red_offset; + base->red.length = red_length; + base->red.msb_right = 0; + base->green.offset = green_offset; + base->green.length = green_length; + base->green.msb_right = 0; + base->blue.offset = blue_offset; + base->blue.length = blue_length; + base->blue.msb_right = 0; + base->transp.offset = transp_offset; + base->transp.length = transp_length; + base->transp.msb_right = 0; + } } } return 0; diff --git a/release/src/router/busybox/util-linux/fdformat.c b/release/src/router/busybox/util-linux/fdformat.c index 2f0854a303..b3e918fb0c 100644 --- a/release/src/router/busybox/util-linux/fdformat.c +++ b/release/src/router/busybox/util-linux/fdformat.c @@ -116,7 +116,7 @@ int fdformat_main(int argc UNUSED_PARAM, char **argv) /* Check backwards so we don't need a counter */ while (--read_bytes >= 0) { if (data[read_bytes] != FD_FILL_BYTE) { - printf("bad data in cyl %d\nContinuing... ", cyl); + printf("bad data in cyl %d\nContinuing... ", cyl); } } } diff --git a/release/src/router/busybox/util-linux/fdisk.c b/release/src/router/busybox/util-linux/fdisk.c index 6eb797cd38..14f027ad3d 100644 --- a/release/src/router/busybox/util-linux/fdisk.c +++ b/release/src/router/busybox/util-linux/fdisk.c @@ -3023,7 +3023,7 @@ int fdisk_main(int argc UNUSED_PARAM, char **argv) printf("\nThe current boot file is: %s\n", sgi_get_bootfile()); if (read_maybe_empty("Please enter the name of the " - "new boot file: ") == '\n') + "new boot file: ") == '\n') printf("Boot file unchanged\n"); else sgi_set_bootfile(line_ptr); diff --git a/release/src/router/busybox/util-linux/fdisk_osf.c b/release/src/router/busybox/util-linux/fdisk_osf.c index 65e6bd7c4f..ff16389bd5 100644 --- a/release/src/router/busybox/util-linux/fdisk_osf.c +++ b/release/src/router/busybox/util-linux/fdisk_osf.c @@ -898,8 +898,7 @@ xbsd_initlabel(struct partition *p) pp->p_fstype = BSD_FS_UNUSED; #else d->d_npartitions = 3; - pp = &d->d_partitions[2]; /* Partition C should be - the whole disk */ + pp = &d->d_partitions[2]; /* Partition C should be the whole disk */ pp->p_offset = 0; pp->p_size = d->d_secperunit; pp->p_fstype = BSD_FS_UNUSED; @@ -935,7 +934,7 @@ xbsd_readlabel(struct partition *p) fdisk_fatal(unable_to_read); memmove(d, &disklabelbuffer[BSD_LABELSECTOR * SECTOR_SIZE + BSD_LABELOFFSET], - sizeof(struct xbsd_disklabel)); + sizeof(struct xbsd_disklabel)); if (d->d_magic != BSD_DISKMAGIC || d->d_magic2 != BSD_DISKMAGIC) return 0; diff --git a/release/src/router/busybox/util-linux/flock.c b/release/src/router/busybox/util-linux/flock.c index e9be4eee98..05a747f724 100644 --- a/release/src/router/busybox/util-linux/flock.c +++ b/release/src/router/busybox/util-linux/flock.c @@ -45,7 +45,7 @@ int flock_main(int argc UNUSED_PARAM, char **argv) if (argv[1]) { fd = open(argv[0], O_RDONLY|O_NOCTTY|O_CREAT, 0666); if (fd < 0 && errno == EISDIR) - fd = open(argv[0], O_RDONLY|O_NOCTTY); + fd = open(argv[0], O_RDONLY|O_NOCTTY); if (fd < 0) bb_perror_msg_and_die("can't open '%s'", argv[0]); //TODO? close_on_exec_on(fd); diff --git a/release/src/router/busybox/util-linux/fsck_minix.c b/release/src/router/busybox/util-linux/fsck_minix.c index 1508ecb033..c1d1b2cc3f 100644 --- a/release/src/router/busybox/util-linux/fsck_minix.c +++ b/release/src/router/busybox/util-linux/fsck_minix.c @@ -13,7 +13,7 @@ * 10.11.91 - updated, does checking, no repairs yet. * Sent out to the mailing-list for testing. * - * 14.11.91 - Testing seems to have gone well. Added some + * 14.11.91 - Testing seems to have gone well. Added some * correction-code, and changed some functions. * * 15.11.91 - More correction code. Hopefully it notices most @@ -22,11 +22,10 @@ * 16.11.91 - More corrections (thanks to Mika Jalava). Most * things seem to work now. Yeah, sure. * - * - * 19.04.92 - Had to start over again from this old version, as a + * 19.04.92 - Had to start over again from this old version, as a * kernel bug ate my enhanced fsck in february. * - * 28.02.93 - added support for different directory entry sizes.. + * 28.02.93 - added support for different directory entry sizes.. * * Sat Mar 6 18:59:42 1993, faith@cs.unc.edu: Output namelen with * superblock information @@ -35,31 +34,31 @@ * to that required by fsutil * * Mon Jan 3 11:06:52 1994 - Dr. Wettstein (greg%wind.uucp@plains.nodak.edu) - * Added support for file system valid flag. Also - * added program_version variable and output of - * program name and version number when program - * is executed. + * Added support for file system valid flag. Also + * added program_version variable and output of + * program name and version number when program + * is executed. * - * 30.10.94 - added support for v2 filesystem - * (Andreas Schwab, schwab@issan.informatik.uni-dortmund.de) + * 30.10.94 - added support for v2 filesystem + * (Andreas Schwab, schwab@issan.informatik.uni-dortmund.de) * - * 10.12.94 - added test to prevent checking of mounted fs adapted - * from Theodore Ts'o's (tytso@athena.mit.edu) e2fsck - * program. (Daniel Quinlan, quinlan@yggdrasil.com) + * 10.12.94 - added test to prevent checking of mounted fs adapted + * from Theodore Ts'o's (tytso@athena.mit.edu) e2fsck + * program. (Daniel Quinlan, quinlan@yggdrasil.com) * * 01.07.96 - Fixed the v2 fs stuff to use the right #defines and such - * for modern libcs (janl@math.uio.no, Nicolai Langfeldt) + * for modern libcs (janl@math.uio.no, Nicolai Langfeldt) * * 02.07.96 - Added C bit fiddling routines from rmk@ecs.soton.ac.uk * (Russell King). He made them for ARM. It would seem - * that the ARM is powerful enough to do this in C whereas + * that the ARM is powerful enough to do this in C whereas * i386 and m64k must use assembly to get it fast >:-) - * This should make minix fsck system-independent. - * (janl@math.uio.no, Nicolai Langfeldt) + * This should make minix fsck system-independent. + * (janl@math.uio.no, Nicolai Langfeldt) * * 04.11.96 - Added minor fixes from Andreas Schwab to avoid compiler * warnings. Added mc68k bitops from - * Joerg Dorchain . + * Joerg Dorchain . * * 06.11.96 - Added v2 code submitted by Joerg Dorchain, but written by * Andreas Schwab. @@ -1131,7 +1130,7 @@ static void check_counts(void) continue; } printf("Zone %d: %sin use, counted=%d\n", - i, zone_in_use(i) ? "" : "not ", zone_count[i]); + i, zone_in_use(i) ? "" : "not ", zone_count[i]); } } @@ -1183,7 +1182,7 @@ static void check_counts2(void) continue; } printf("Zone %d: %sin use, counted=%d\n", - i, zone_in_use(i) ? "" : "not ", zone_count[i]); + i, zone_in_use(i) ? "" : "not ", zone_count[i]); } } #endif @@ -1253,7 +1252,7 @@ int fsck_minix_main(int argc UNUSED_PARAM, char **argv) printf("Forcing filesystem check on %s\n", device_name); else if (OPT_repair) printf("Filesystem on %s is dirty, needs checking\n", - device_name); + device_name); read_tables(); @@ -1280,23 +1279,23 @@ int fsck_minix_main(int argc UNUSED_PARAM, char **argv) if (!inode_in_use(i)) free_cnt++; printf("\n%6u inodes used (%u%%)\n", (INODES - free_cnt), - 100 * (INODES - free_cnt) / INODES); + 100 * (INODES - free_cnt) / INODES); for (i = FIRSTZONE, free_cnt = 0; i < ZONES; i++) if (!zone_in_use(i)) free_cnt++; printf("%6u zones used (%u%%)\n\n" - "%6u regular files\n" - "%6u directories\n" - "%6u character device files\n" - "%6u block device files\n" - "%6u links\n" - "%6u symbolic links\n" - "------\n" - "%6u files\n", - (ZONES - free_cnt), 100 * (ZONES - free_cnt) / ZONES, - regular, directory, chardev, blockdev, - links - 2 * directory + 1, symlinks, - total - 2 * directory + 1); + "%6u regular files\n" + "%6u directories\n" + "%6u character device files\n" + "%6u block device files\n" + "%6u links\n" + "%6u symbolic links\n" + "------\n" + "%6u files\n", + (ZONES - free_cnt), 100 * (ZONES - free_cnt) / ZONES, + regular, directory, chardev, blockdev, + links - 2 * directory + 1, symlinks, + total - 2 * directory + 1); } if (changed) { write_tables(); diff --git a/release/src/router/busybox/util-linux/getopt.c b/release/src/router/busybox/util-linux/getopt.c index d662c813ae..1ae0c59dbf 100644 --- a/release/src/router/busybox/util-linux/getopt.c +++ b/release/src/router/busybox/util-linux/getopt.c @@ -372,7 +372,7 @@ int getopt_main(int argc, char **argv) if (!argv[1]) { if (compatible) { /* For some reason, the original getopt gave no error - when there were no arguments. */ + * when there were no arguments. */ printf(" --\n"); return 0; } diff --git a/release/src/router/busybox/util-linux/ipcrm.c b/release/src/router/busybox/util-linux/ipcrm.c index 274050cdf2..888f70ef89 100644 --- a/release/src/router/busybox/util-linux/ipcrm.c +++ b/release/src/router/busybox/util-linux/ipcrm.c @@ -160,7 +160,7 @@ int ipcrm_main(int argc, char **argv) /* convert key to id */ id = ((c == 'q') ? msgget(key, 0) : - (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0)); + (c == 'm') ? shmget(key, 0, 0) : semget(key, 0, 0)); if (id < 0) { const char *errmsg; @@ -189,8 +189,8 @@ int ipcrm_main(int argc, char **argv) } result = ((c == 'q') ? msgctl(id, IPC_RMID, NULL) : - (c == 'm') ? shmctl(id, IPC_RMID, NULL) : - semctl(id, 0, IPC_RMID, arg)); + (c == 'm') ? shmctl(id, IPC_RMID, NULL) : + semctl(id, 0, IPC_RMID, arg)); if (result) { const char *errmsg; diff --git a/release/src/router/busybox/util-linux/ipcs.c b/release/src/router/busybox/util-linux/ipcs.c index ee7df5e336..2668cafd46 100644 --- a/release/src/router/busybox/util-linux/ipcs.c +++ b/release/src/router/busybox/util-linux/ipcs.c @@ -152,54 +152,54 @@ static NOINLINE void do_shm(void) if ((shmctl(0, IPC_INFO, (struct shmid_ds *) (void *) &shminfo)) < 0) return; /* glibc 2.1.3 and all earlier libc's have ints as fields - of struct shminfo; glibc 2.1.91 has unsigned long; ach */ + * of struct shminfo; glibc 2.1.91 has unsigned long; ach */ printf("max number of segments = %lu\n" - "max seg size (kbytes) = %lu\n" - "max total shared memory (pages) = %lu\n" - "min seg size (bytes) = %lu\n", - (unsigned long) shminfo.shmmni, - (unsigned long) (shminfo.shmmax >> 10), - (unsigned long) shminfo.shmall, - (unsigned long) shminfo.shmmin); + "max seg size (kbytes) = %lu\n" + "max total shared memory (pages) = %lu\n" + "min seg size (bytes) = %lu\n", + (unsigned long) shminfo.shmmni, + (unsigned long) (shminfo.shmmax >> 10), + (unsigned long) shminfo.shmall, + (unsigned long) shminfo.shmmin); return; case STATUS: printf("------ Shared Memory %s --------\n", "Status"); - printf( "segments allocated %d\n" - "pages allocated %ld\n" - "pages resident %ld\n" - "pages swapped %ld\n" - "Swap performance: %ld attempts\t%ld successes\n", - shm_info.used_ids, - shm_info.shm_tot, - shm_info.shm_rss, - shm_info.shm_swp, - shm_info.swap_attempts, shm_info.swap_successes); + printf("segments allocated %d\n" + "pages allocated %ld\n" + "pages resident %ld\n" + "pages swapped %ld\n" + "Swap performance: %ld attempts\t%ld successes\n", + shm_info.used_ids, + shm_info.shm_tot, + shm_info.shm_rss, + shm_info.shm_swp, + shm_info.swap_attempts, shm_info.swap_successes); return; case CREATOR: printf("------ Shared Memory %s --------\n", "Segment Creators/Owners"); - printf( "%-10s %-10s %-10s %-10s %-10s %-10s\n", - "shmid", "perms", "cuid", "cgid", "uid", "gid"); + printf("%-10s %-10s %-10s %-10s %-10s %-10s\n", + "shmid", "perms", "cuid", "cgid", "uid", "gid"); break; case TIME: printf("------ Shared Memory %s --------\n", "Attach/Detach/Change Times"); - printf( "%-10s %-10s %-20s %-20s %-20s\n", - "shmid", "owner", "attached", "detached", "changed"); + printf("%-10s %-10s %-20s %-20s %-20s\n", + "shmid", "owner", "attached", "detached", "changed"); break; case PID: printf("------ Shared Memory %s --------\n", "Creator/Last-op"); - printf( "%-10s %-10s %-10s %-10s\n", - "shmid", "owner", "cpid", "lpid"); + printf("%-10s %-10s %-10s %-10s\n", + "shmid", "owner", "cpid", "lpid"); break; default: printf("------ Shared Memory %s --------\n", "Segments"); - printf( "%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n", - "key", "shmid", "owner", "perms", "bytes", "nattch", - "status"); + printf("%-10s %-10s %-10s %-10s %-10s %-10s %-12s\n", + "key", "shmid", "owner", "perms", "bytes", "nattch", + "status"); break; } @@ -220,11 +220,11 @@ static NOINLINE void do_shm(void) printf("%-10d %-10d", shmid, ipcp->uid); /* ctime uses static buffer: use separate calls */ printf(" %-20.16s", shmseg.shm_atime - ? ctime(&shmseg.shm_atime) + 4 : "Not set"); + ? ctime(&shmseg.shm_atime) + 4 : "Not set"); printf(" %-20.16s", shmseg.shm_dtime - ? ctime(&shmseg.shm_dtime) + 4 : "Not set"); + ? ctime(&shmseg.shm_dtime) + 4 : "Not set"); printf(" %-20.16s\n", shmseg.shm_ctime - ? ctime(&shmseg.shm_ctime) + 4 : "Not set"); + ? ctime(&shmseg.shm_ctime) + 4 : "Not set"); break; case PID: if (pw) @@ -241,17 +241,17 @@ static NOINLINE void do_shm(void) else printf("%-10d %-10d", shmid, ipcp->uid); printf(" %-10o %-10lu %-10ld %-6s %-6s\n", ipcp->mode & 0777, - /* - * earlier: int, Austin has size_t - */ - (unsigned long) shmseg.shm_segsz, - /* - * glibc-2.1.3 and earlier has unsigned short; - * Austin has shmatt_t - */ - (long) shmseg.shm_nattch, - ipcp->mode & SHM_DEST ? "dest" : " ", - ipcp->mode & SHM_LOCKED ? "locked" : " "); + /* + * earlier: int, Austin has size_t + */ + (unsigned long) shmseg.shm_segsz, + /* + * glibc-2.1.3 and earlier has unsigned short; + * Austin has shmatt_t + */ + (long) shmseg.shm_nattch, + ipcp->mode & SHM_DEST ? "dest" : " ", + ipcp->mode & SHM_LOCKED ? "locked" : " "); break; } } @@ -281,32 +281,32 @@ static NOINLINE void do_sem(void) if ((semctl(0, 0, IPC_INFO, arg)) < 0) return; printf("max number of arrays = %d\n" - "max semaphores per array = %d\n" - "max semaphores system wide = %d\n" - "max ops per semop call = %d\n" - "semaphore max value = %d\n", - seminfo.semmni, - seminfo.semmsl, - seminfo.semmns, seminfo.semopm, seminfo.semvmx); + "max semaphores per array = %d\n" + "max semaphores system wide = %d\n" + "max ops per semop call = %d\n" + "semaphore max value = %d\n", + seminfo.semmni, + seminfo.semmsl, + seminfo.semmns, seminfo.semopm, seminfo.semvmx); return; case STATUS: printf("------ Semaphore %s --------\n", "Status"); - printf( "used arrays = %d\n" - "allocated semaphores = %d\n", - seminfo.semusz, seminfo.semaem); + printf("used arrays = %d\n" + "allocated semaphores = %d\n", + seminfo.semusz, seminfo.semaem); return; case CREATOR: printf("------ Semaphore %s --------\n", "Arrays Creators/Owners"); - printf( "%-10s %-10s %-10s %-10s %-10s %-10s\n", - "semid", "perms", "cuid", "cgid", "uid", "gid"); + printf("%-10s %-10s %-10s %-10s %-10s %-10s\n", + "semid", "perms", "cuid", "cgid", "uid", "gid"); break; case TIME: printf("------ Shared Memory %s --------\n", "Operation/Change Times"); - printf( "%-8s %-10s %-26.24s %-26.24s\n", - "shmid", "owner", "last-op", "last-changed"); + printf("%-8s %-10s %-26.24s %-26.24s\n", + "shmid", "owner", "last-op", "last-changed"); break; case PID: @@ -314,8 +314,8 @@ static NOINLINE void do_sem(void) default: printf("------ Semaphore %s --------\n", "Arrays"); - printf( "%-10s %-10s %-10s %-10s %-10s\n", - "key", "semid", "owner", "perms", "nsems"); + printf("%-10s %-10s %-10s %-10s %-10s\n", + "key", "semid", "owner", "perms", "nsems"); break; } @@ -337,9 +337,9 @@ static NOINLINE void do_sem(void) printf("%-8d %-10d", semid, ipcp->uid); /* ctime uses static buffer: use separate calls */ printf(" %-26.24s", semary.sem_otime - ? ctime(&semary.sem_otime) : "Not set"); + ? ctime(&semary.sem_otime) : "Not set"); printf(" %-26.24s\n", semary.sem_ctime - ? ctime(&semary.sem_ctime) : "Not set"); + ? ctime(&semary.sem_ctime) : "Not set"); break; case PID: break; @@ -351,13 +351,13 @@ static NOINLINE void do_sem(void) else printf("%-10d %-9d", semid, ipcp->uid); printf(" %-10o %-10ld\n", ipcp->mode & 0777, - /* - * glibc-2.1.3 and earlier has unsigned short; - * glibc-2.1.91 has variation between - * unsigned short and unsigned long - * Austin prescribes unsigned short. - */ - (long) semary.sem_nsems); + /* + * glibc-2.1.3 and earlier has unsigned short; + * glibc-2.1.91 has variation between + * unsigned short and unsigned long + * Austin prescribes unsigned short. + */ + (long) semary.sem_nsems); break; } } @@ -383,42 +383,42 @@ static NOINLINE void do_msg(void) if ((msgctl(0, IPC_INFO, (struct msqid_ds *) (void *) &msginfo)) < 0) return; printf("------ Message%s --------\n", "s: Limits"); - printf( "max queues system wide = %d\n" - "max size of message (bytes) = %d\n" - "default max size of queue (bytes) = %d\n", - msginfo.msgmni, msginfo.msgmax, msginfo.msgmnb); + printf("max queues system wide = %d\n" + "max size of message (bytes) = %d\n" + "default max size of queue (bytes) = %d\n", + msginfo.msgmni, msginfo.msgmax, msginfo.msgmnb); return; case STATUS: printf("------ Message%s --------\n", "s: Status"); - printf( "allocated queues = %d\n" - "used headers = %d\n" - "used space = %d bytes\n", - msginfo.msgpool, msginfo.msgmap, msginfo.msgtql); + printf("allocated queues = %d\n" + "used headers = %d\n" + "used space = %d bytes\n", + msginfo.msgpool, msginfo.msgmap, msginfo.msgtql); return; case CREATOR: printf("------ Message%s --------\n", " Queues: Creators/Owners"); - printf( "%-10s %-10s %-10s %-10s %-10s %-10s\n", - "msqid", "perms", "cuid", "cgid", "uid", "gid"); + printf("%-10s %-10s %-10s %-10s %-10s %-10s\n", + "msqid", "perms", "cuid", "cgid", "uid", "gid"); break; case TIME: printf("------ Message%s --------\n", " Queues Send/Recv/Change Times"); - printf( "%-8s %-10s %-20s %-20s %-20s\n", - "msqid", "owner", "send", "recv", "change"); + printf("%-8s %-10s %-20s %-20s %-20s\n", + "msqid", "owner", "send", "recv", "change"); break; case PID: printf("------ Message%s --------\n", " Queues PIDs"); - printf( "%-10s %-10s %-10s %-10s\n", - "msqid", "owner", "lspid", "lrpid"); + printf("%-10s %-10s %-10s %-10s\n", + "msqid", "owner", "lspid", "lrpid"); break; default: printf("------ Message%s --------\n", " Queues"); - printf( "%-10s %-10s %-10s %-10s %-12s %-12s\n", - "key", "msqid", "owner", "perms", "used-bytes", "messages"); + printf("%-10s %-10s %-10s %-10s %-12s %-12s\n", + "key", "msqid", "owner", "perms", "used-bytes", "messages"); break; } @@ -438,11 +438,11 @@ static NOINLINE void do_msg(void) else printf("%-8d %-10d", msqid, ipcp->uid); printf(" %-20.16s", msgque.msg_stime - ? ctime(&msgque.msg_stime) + 4 : "Not set"); + ? ctime(&msgque.msg_stime) + 4 : "Not set"); printf(" %-20.16s", msgque.msg_rtime - ? ctime(&msgque.msg_rtime) + 4 : "Not set"); + ? ctime(&msgque.msg_rtime) + 4 : "Not set"); printf(" %-20.16s\n", msgque.msg_ctime - ? ctime(&msgque.msg_ctime) + 4 : "Not set"); + ? ctime(&msgque.msg_ctime) + 4 : "Not set"); break; case PID: if (pw) @@ -459,13 +459,13 @@ static NOINLINE void do_msg(void) else printf("%-10d %-10d", msqid, ipcp->uid); printf(" %-10o %-12ld %-12ld\n", ipcp->mode & 0777, - /* - * glibc-2.1.3 and earlier has unsigned short; - * glibc-2.1.91 has variation between - * unsigned short, unsigned long - * Austin has msgqnum_t - */ - (long) msgque.msg_cbytes, (long) msgque.msg_qnum); + /* + * glibc-2.1.3 and earlier has unsigned short; + * glibc-2.1.91 has variation between + * unsigned short, unsigned long + * Austin has msgqnum_t + */ + (long) msgque.msg_cbytes, (long) msgque.msg_qnum); break; } } @@ -483,18 +483,18 @@ static void print_shm(int shmid) } printf("\nShared memory Segment shmid=%d\n" - "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n" - "mode=%#o\taccess_perms=%#o\n" - "bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n", - shmid, - ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, - ipcp->mode, ipcp->mode & 0777, - (long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid, - (long) shmds.shm_nattch); + "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\n" + "mode=%#o\taccess_perms=%#o\n" + "bytes=%ld\tlpid=%d\tcpid=%d\tnattch=%ld\n", + shmid, + ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, + ipcp->mode, ipcp->mode & 0777, + (long) shmds.shm_segsz, shmds.shm_lpid, shmds.shm_cpid, + (long) shmds.shm_nattch); printf("att_time=%-26.24s\n", - shmds.shm_atime ? ctime(&shmds.shm_atime) : "Not set"); + shmds.shm_atime ? ctime(&shmds.shm_atime) : "Not set"); printf("det_time=%-26.24s\n", - shmds.shm_dtime ? ctime(&shmds.shm_dtime) : "Not set"); + shmds.shm_dtime ? ctime(&shmds.shm_dtime) : "Not set"); printf("change_time=%-26.24s\n\n", ctime(&shmds.shm_ctime)); } @@ -510,24 +510,24 @@ static void print_msg(int msqid) } printf("\nMessage Queue msqid=%d\n" - "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n" - "cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n", - msqid, ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode, - /* - * glibc-2.1.3 and earlier has unsigned short; - * glibc-2.1.91 has variation between - * unsigned short, unsigned long - * Austin has msgqnum_t (for msg_qbytes) - */ - (long) buf.msg_cbytes, (long) buf.msg_qbytes, - (long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid); + "uid=%d\tgid=%d\tcuid=%d\tcgid=%d\tmode=%#o\n" + "cbytes=%ld\tqbytes=%ld\tqnum=%ld\tlspid=%d\tlrpid=%d\n", + msqid, ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, ipcp->mode, + /* + * glibc-2.1.3 and earlier has unsigned short; + * glibc-2.1.91 has variation between + * unsigned short, unsigned long + * Austin has msgqnum_t (for msg_qbytes) + */ + (long) buf.msg_cbytes, (long) buf.msg_qbytes, + (long) buf.msg_qnum, buf.msg_lspid, buf.msg_lrpid); printf("send_time=%-26.24s\n", - buf.msg_stime ? ctime(&buf.msg_stime) : "Not set"); + buf.msg_stime ? ctime(&buf.msg_stime) : "Not set"); printf("rcv_time=%-26.24s\n", - buf.msg_rtime ? ctime(&buf.msg_rtime) : "Not set"); + buf.msg_rtime ? ctime(&buf.msg_rtime) : "Not set"); printf("change_time=%-26.24s\n\n", - buf.msg_ctime ? ctime(&buf.msg_ctime) : "Not set"); + buf.msg_ctime ? ctime(&buf.msg_ctime) : "Not set"); } static void print_sem(int semid) @@ -544,19 +544,19 @@ static void print_sem(int semid) } printf("\nSemaphore Array semid=%d\n" - "uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n" - "mode=%#o, access_perms=%#o\n" - "nsems = %ld\n" - "otime = %-26.24s\n", - semid, - ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, - ipcp->mode, ipcp->mode & 0777, - (long) semds.sem_nsems, - semds.sem_otime ? ctime(&semds.sem_otime) : "Not set"); + "uid=%d\t gid=%d\t cuid=%d\t cgid=%d\n" + "mode=%#o, access_perms=%#o\n" + "nsems = %ld\n" + "otime = %-26.24s\n", + semid, + ipcp->uid, ipcp->gid, ipcp->cuid, ipcp->cgid, + ipcp->mode, ipcp->mode & 0777, + (long) semds.sem_nsems, + semds.sem_otime ? ctime(&semds.sem_otime) : "Not set"); printf("ctime = %-26.24s\n" - "%-10s %-10s %-10s %-10s %-10s\n", - ctime(&semds.sem_ctime), - "semnum", "value", "ncount", "zcount", "pid"); + "%-10s %-10s %-10s %-10s %-10s\n", + ctime(&semds.sem_ctime), + "semnum", "value", "ncount", "zcount", "pid"); arg.val = 0; for (i = 0; i < semds.sem_nsems; i++) { diff --git a/release/src/router/busybox/util-linux/lspci.c b/release/src/router/busybox/util-linux/lspci.c index 5184858d18..514678afd3 100644 --- a/release/src/router/busybox/util-linux/lspci.c +++ b/release/src/router/busybox/util-linux/lspci.c @@ -74,11 +74,11 @@ static int FAST_FUNC fileAction( if (option_mask32 & OPT_m) { printf("%s \"Class %04x\" \"%04x\" \"%04x\" \"%04x\" \"%04x\"", - pci_slot_name, pci_class, pci_vid, pci_did, - pci_subsys_vid, pci_subsys_did); + pci_slot_name, pci_class, pci_vid, pci_did, + pci_subsys_vid, pci_subsys_did); } else { printf("%s Class %04x: %04x:%04x", - pci_slot_name, pci_class, pci_vid, pci_did); + pci_slot_name, pci_class, pci_vid, pci_did); } if ((option_mask32 & OPT_k) && driver) { diff --git a/release/src/router/busybox/util-linux/mdev.c b/release/src/router/busybox/util-linux/mdev.c index c4829a596c..3d4e135baa 100644 --- a/release/src/router/busybox/util-linux/mdev.c +++ b/release/src/router/busybox/util-linux/mdev.c @@ -80,7 +80,7 @@ //usage: IF_FEATURE_MDEV_CONF( //usage: "\n" //usage: "It uses /etc/mdev.conf with lines\n" -//usage: " [-]DEVNAME UID:GID PERM" +//usage: " [-][ENV=regex;]...DEVNAME UID:GID PERM" //usage: IF_FEATURE_MDEV_RENAME(" [>|=PATH]|[!]") //usage: IF_FEATURE_MDEV_EXEC(" [@|$|*PROG]") //usage: "\n" @@ -92,7 +92,9 @@ //usage: "\n" //usage: "If /dev/mdev.seq file exists, mdev will wait for its value\n" //usage: "to match $SEQNUM variable. This prevents plug/unplug races.\n" -//usage: "To activate this feature, create empty /dev/mdev.seq at boot." +//usage: "To activate this feature, create empty /dev/mdev.seq at boot.\n" +//usage: "\n" +//usage: "If /dev/mdev.log file exists, debug log will be appended to it." #include "libbb.h" #include "xregex.h" @@ -139,10 +141,126 @@ * This happens regardless of /sys/class/.../dev existence. */ +/* Kernel's hotplug environment constantly changes. + * Here are new cases I observed on 3.1.0: + * + * Case with $DEVNAME and $DEVICE, not just $DEVPATH: + * ACTION=add + * BUSNUM=001 + * DEVICE=/proc/bus/usb/001/003 + * DEVNAME=bus/usb/001/003 + * DEVNUM=003 + * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5 + * DEVTYPE=usb_device + * MAJOR=189 + * MINOR=2 + * PRODUCT=18d1/4e12/227 + * SUBSYSTEM=usb + * TYPE=0/0/0 + * + * Case with $DEVICE, but no $DEVNAME - apparenty, usb iface notification? + * "Please load me a module" thing? + * ACTION=add + * DEVICE=/proc/bus/usb/001/003 + * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0 + * DEVTYPE=usb_interface + * INTERFACE=8/6/80 + * MODALIAS=usb:v18D1p4E12d0227dc00dsc00dp00ic08isc06ip50 + * PRODUCT=18d1/4e12/227 + * SUBSYSTEM=usb + * TYPE=0/0/0 + * + * ACTION=add + * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5 + * DEVTYPE=scsi_host + * SUBSYSTEM=scsi + * + * ACTION=add + * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/scsi_host/host5 + * SUBSYSTEM=scsi_host + * + * ACTION=add + * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0 + * DEVTYPE=scsi_target + * SUBSYSTEM=scsi + * + * Case with strange $MODALIAS: + * ACTION=add + * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0 + * DEVTYPE=scsi_device + * MODALIAS=scsi:t-0x00 + * SUBSYSTEM=scsi + * + * ACTION=add + * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0/scsi_disk/5:0:0:0 + * SUBSYSTEM=scsi_disk + * + * ACTION=add + * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0/scsi_device/5:0:0:0 + * SUBSYSTEM=scsi_device + * + * Case with explicit $MAJOR/$MINOR (no need to read /sys/$DEVPATH/dev?): + * ACTION=add + * DEVNAME=bsg/5:0:0:0 + * DEVPATH=/devices/pci0000:00/0000:00:02.1/usb1/1-5/1-5:1.0/host5/target5:0:0/5:0:0:0/bsg/5:0:0:0 + * MAJOR=253 + * MINOR=1 + * SUBSYSTEM=bsg + * + * ACTION=add + * DEVPATH=/devices/virtual/bdi/8:16 + * SUBSYSTEM=bdi + * + * ACTION=add + * DEVNAME=sdb + * DEVPATH=/block/sdb + * DEVTYPE=disk + * MAJOR=8 + * MINOR=16 + * SUBSYSTEM=block + * + * Case with ACTION=change: + * ACTION=change + * DEVNAME=sdb + * DEVPATH=/block/sdb + * DEVTYPE=disk + * DISK_MEDIA_CHANGE=1 + * MAJOR=8 + * MINOR=16 + * SUBSYSTEM=block + */ + +#define DEBUG_LVL 2 + +#if DEBUG_LVL >= 1 +# define dbg1(...) do { if (G.verbose) bb_error_msg(__VA_ARGS__); } while(0) +#else +# define dbg1(...) ((void)0) +#endif +#if DEBUG_LVL >= 2 +# define dbg2(...) do { if (G.verbose >= 2) bb_error_msg(__VA_ARGS__); } while(0) +#else +# define dbg2(...) ((void)0) +#endif +#if DEBUG_LVL >= 3 +# define dbg3(...) do { if (G.verbose >= 3) bb_error_msg(__VA_ARGS__); } while(0) +#else +# define dbg3(...) ((void)0) +#endif + + +static const char keywords[] ALIGN1 = "add\0remove\0"; // "change\0" +enum { OP_add, OP_remove }; + +struct envmatch { + struct envmatch *next; + char *envname; + regex_t match; +}; + struct rule { bool keep_matching; bool regex_compiled; - bool regex_has_slash; mode_t mode; int maj, min0, min1; struct bb_uidgid_t ugid; @@ -150,11 +268,14 @@ struct rule { char *ren_mov; IF_FEATURE_MDEV_EXEC(char *r_cmd;) regex_t match; + struct envmatch *envmatch; }; struct globals { int root_major, root_minor; + smallint verbose; char *subsystem; + char *subsys_env; /* for putenv("SUBSYSTEM=subsystem") */ #if ENABLE_FEATURE_MDEV_CONF const char *filename; parser_t *parser; @@ -162,6 +283,7 @@ struct globals { unsigned rule_idx; #endif struct rule cur_rule; + char timestr[sizeof("60.123456")]; } FIX_ALIASING; #define G (*(struct globals*)&bb_common_bufsiz1) #define INIT_G() do { \ @@ -173,15 +295,8 @@ struct globals { /* Prevent infinite loops in /sys symlinks */ #define MAX_SYSFS_DEPTH 3 -/* We use additional 64+ bytes in make_device() */ -#define SCRATCH_SIZE 80 - -#if 0 -# define dbg(...) bb_error_msg(__VA_ARGS__) -#else -# define dbg(...) ((void)0) -#endif - +/* We use additional bytes in make_device() */ +#define SCRATCH_SIZE 128 #if ENABLE_FEATURE_MDEV_CONF @@ -194,14 +309,65 @@ static void make_default_cur_rule(void) static void clean_up_cur_rule(void) { + struct envmatch *e; + free(G.cur_rule.envvar); + free(G.cur_rule.ren_mov); if (G.cur_rule.regex_compiled) regfree(&G.cur_rule.match); - free(G.cur_rule.ren_mov); IF_FEATURE_MDEV_EXEC(free(G.cur_rule.r_cmd);) + e = G.cur_rule.envmatch; + while (e) { + free(e->envname); + regfree(&e->match); + e = e->next; + } make_default_cur_rule(); } +/* In later versions, endofname is in libbb */ +#define endofname mdev_endofname +static +const char* FAST_FUNC +endofname(const char *name) +{ +#define is_name(c) ((c) == '_' || isalpha((unsigned char)(c))) +#define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c))) + if (!is_name(*name)) + return name; + while (*++name) { + if (!is_in_name(*name)) + break; + } + return name; +} + +static char *parse_envmatch_pfx(char *val) +{ + struct envmatch **nextp = &G.cur_rule.envmatch; + + for (;;) { + struct envmatch *e; + char *semicolon; + char *eq = strchr(val, '='); + if (!eq /* || eq == val? */) + return val; + if (endofname(val) != eq) + return val; + semicolon = strchr(eq, ';'); + if (!semicolon) + return val; + /* ENVVAR=regex;... */ + *nextp = e = xzalloc(sizeof(*e)); + nextp = &e->next; + e->envname = xstrndup(val, eq - val); + *semicolon = '\0'; + xregcomp(&e->match, eq + 1, REG_EXTENDED); + *semicolon = ';'; + val = semicolon + 1; + } +} + static void parse_next_rule(void) { /* Note: on entry, G.cur_rule is set to default */ @@ -214,12 +380,13 @@ static void parse_next_rule(void) break; /* Fields: [-]regex uid:gid mode [alias] [cmd] */ - dbg("token1:'%s'", tokens[1]); + dbg3("token1:'%s'", tokens[1]); /* 1st field */ val = tokens[0]; G.cur_rule.keep_matching = ('-' == val[0]); val += G.cur_rule.keep_matching; /* swallow leading dash */ + val = parse_envmatch_pfx(val); if (val[0] == '@') { /* @major,minor[-minor2] */ /* (useful when name is ambiguous: @@ -234,8 +401,10 @@ static void parse_next_rule(void) if (sc == 2) G.cur_rule.min1 = G.cur_rule.min0; } else { + char *eq = strchr(val, '='); if (val[0] == '$') { - char *eq = strchr(++val, '='); + /* $ENVVAR=regex ... */ + val++; if (!eq) { bb_error_msg("bad $envvar=regex on line %d", G.parser->lineno); goto next_rule; @@ -245,7 +414,6 @@ static void parse_next_rule(void) } xregcomp(&G.cur_rule.match, val, REG_EXTENDED); G.cur_rule.regex_compiled = 1; - G.cur_rule.regex_has_slash = (strchr(val, '/') != NULL); } /* 2nd field: uid:gid - device ownership */ @@ -280,7 +448,7 @@ static void parse_next_rule(void) clean_up_cur_rule(); } /* while (config_read) */ - dbg("config_close(G.parser)"); + dbg3("config_close(G.parser)"); config_close(G.parser); G.parser = NULL; @@ -297,7 +465,7 @@ static const struct rule *next_rule(void) /* Open conf file if we didn't do it yet */ if (!G.parser && G.filename) { - dbg("config_open('%s')", G.filename); + dbg3("config_open('%s')", G.filename); G.parser = config_open2(G.filename, fopen_for_read); G.filename = NULL; } @@ -306,7 +474,7 @@ static const struct rule *next_rule(void) /* mdev -s */ /* Do we have rule parsed already? */ if (G.rule_vec[G.rule_idx]) { - dbg("< G.rule_vec[G.rule_idx:%d]=%p", G.rule_idx, G.rule_vec[G.rule_idx]); + dbg3("< G.rule_vec[G.rule_idx:%d]=%p", G.rule_idx, G.rule_vec[G.rule_idx]); return G.rule_vec[G.rule_idx++]; } make_default_cur_rule(); @@ -323,19 +491,46 @@ static const struct rule *next_rule(void) rule = memcpy(xmalloc(sizeof(G.cur_rule)), &G.cur_rule, sizeof(G.cur_rule)); G.rule_vec = xrealloc_vector(G.rule_vec, 4, G.rule_idx); G.rule_vec[G.rule_idx++] = rule; - dbg("> G.rule_vec[G.rule_idx:%d]=%p", G.rule_idx, G.rule_vec[G.rule_idx]); + dbg3("> G.rule_vec[G.rule_idx:%d]=%p", G.rule_idx, G.rule_vec[G.rule_idx]); } } return rule; } +static int env_matches(struct envmatch *e) +{ + while (e) { + int r; + char *val = getenv(e->envname); + if (!val) + return 0; + r = regexec(&e->match, val, /*size*/ 0, /*range[]*/ NULL, /*eflags*/ 0); + if (r != 0) /* no match */ + return 0; + e = e->next; + } + return 1; +} + #else # define next_rule() (&G.cur_rule) #endif +static void mkdir_recursive(char *name) +{ + /* if name has many levels ("dir1/dir2"), + * bb_make_directory() will create dir1 according to umask, + * not according to its "mode" parameter. + * Since we run with umask=0, need to temporarily switch it. + */ + umask(022); /* "dir1" (if any) will be 0755 too */ + bb_make_directory(name, 0755, FILEUTILS_RECUR); + umask(0); +} + /* Builds an alias path. * This function potentionally reallocates the alias parameter. * Only used for ENABLE_FEATURE_MDEV_RENAME @@ -349,7 +544,7 @@ static char *build_alias(char *alias, const char *device_name) dest = strrchr(alias, '/'); if (dest) { /* ">bar/[baz]" ? */ *dest = '\0'; /* mkdir bar */ - bb_make_directory(alias, 0755, FILEUTILS_RECUR); + mkdir_recursive(alias); *dest = '/'; if (dest[1] == '\0') { /* ">bar/" => ">bar/device_name" */ dest = alias; @@ -363,16 +558,17 @@ static char *build_alias(char *alias, const char *device_name) /* mknod in /dev based on a path like "/sys/block/hda/hda1" * NB1: path parameter needs to have SCRATCH_SIZE scratch bytes - * after NUL, but we promise to not mangle (IOW: to restore if needed) + * after NUL, but we promise to not mangle (IOW: to restore NUL if needed) * path string. * NB2: "mdev -s" may call us many times, do not leak memory/fds! + * + * device_name = $DEVNAME (may be NULL) + * path = /sys/$DEVPATH */ -static void make_device(char *path, int delete) +static void make_device(char *device_name, char *path, int operation) { - char *device_name, *subsystem_slash_devname; int major, minor, type, len; - - dbg("%s('%s', delete:%d)", __func__, path, delete); + char *path_end = path + strlen(path); /* Try to read major/minor string. Note that the kernel puts \n after * the data, so we don't need to worry about null terminating the string @@ -380,51 +576,60 @@ static void make_device(char *path, int delete) * We also depend on path having writeable space after it. */ major = -1; - if (!delete) { - char *dev_maj_min = path + strlen(path); - - strcpy(dev_maj_min, "/dev"); - len = open_read_close(path, dev_maj_min + 1, 64); - *dev_maj_min = '\0'; + if (operation == OP_add) { + strcpy(path_end, "/dev"); + len = open_read_close(path, path_end + 1, SCRATCH_SIZE - 1); + *path_end = '\0'; if (len < 1) { if (!ENABLE_FEATURE_MDEV_EXEC) return; /* no "dev" file, but we can still run scripts * based on device name */ - } else if (sscanf(++dev_maj_min, "%u:%u", &major, &minor) != 2) { + } else if (sscanf(path_end + 1, "%u:%u", &major, &minor) == 2) { + dbg1("dev %u,%u", major, minor); + } else { major = -1; } } /* else: for delete, -1 still deletes the node, but < -1 suppresses that */ - /* Determine device name, type, major and minor */ - device_name = (char*) bb_basename(path); - /* http://kernel.org/doc/pending/hotplug.txt says that only + /* Determine device name */ + if (!device_name) { + /* + * There was no $DEVNAME envvar (for example, mdev -s never has). + * But it is very useful: it contains the *path*, not only basename, + * Thankfully, uevent file has it. + * Example of .../sound/card0/controlC0/uevent file on Linux-3.7.7: + * MAJOR=116 + * MINOR=7 + * DEVNAME=snd/controlC0 + */ + strcpy(path_end, "/uevent"); + len = open_read_close(path, path_end + 1, SCRATCH_SIZE - 1); + if (len < 0) + len = 0; + *path_end = '\0'; + path_end[1 + len] = '\0'; + device_name = strstr(path_end + 1, "\nDEVNAME="); + if (device_name) { + device_name += sizeof("\nDEVNAME=")-1; + strchrnul(device_name, '\n')[0] = '\0'; + } else { + /* Fall back to just basename */ + device_name = (char*) bb_basename(path); + } + } + /* Determine device type */ + /* + * http://kernel.org/doc/pending/hotplug.txt says that only * "/sys/block/..." is for block devices. "/sys/bus" etc is not. * But since 2.6.25 block devices are also in /sys/class/block. - * We use strstr("/block/") to forestall future surprises. */ + * We use strstr("/block/") to forestall future surprises. + */ type = S_IFCHR; if (strstr(path, "/block/") || (G.subsystem && strncmp(G.subsystem, "block", 5) == 0)) type = S_IFBLK; - /* Make path point to "subsystem/device_name" */ - subsystem_slash_devname = NULL; - /* Check for coldplug invocations first */ - if (strncmp(path, "/sys/block/", 11) == 0) /* legacy case */ - path += sizeof("/sys/") - 1; - else if (strncmp(path, "/sys/class/", 11) == 0) - path += sizeof("/sys/class/") - 1; - else { - /* Example of a hotplug invocation: - * SUBSYSTEM="block" - * DEVPATH="/sys" + "/devices/virtual/mtd/mtd3/mtdblock3" - * ("/sys" is added by mdev_main) - * - path does not contain subsystem - */ - subsystem_slash_devname = concat_path_file(G.subsystem, device_name); - path = subsystem_slash_devname; - } - #if ENABLE_FEATURE_MDEV_CONF G.rule_idx = 0; /* restart from the beginning (think mdev -s) */ #endif @@ -434,14 +639,16 @@ static void make_device(char *path, int delete) char *command; char *alias; char aliaslink = aliaslink; /* for compiler */ - const char *node_name; + char *node_name; const struct rule *rule; - str_to_match = ""; + str_to_match = device_name; rule = next_rule(); #if ENABLE_FEATURE_MDEV_CONF + if (!env_matches(rule->envmatch)) + continue; if (rule->maj >= 0) { /* @maj,min rule */ if (major != rule->maj) continue; @@ -452,17 +659,15 @@ static void make_device(char *path, int delete) } if (rule->envvar) { /* $envvar=regex rule */ str_to_match = getenv(rule->envvar); - dbg("getenv('%s'):'%s'", rule->envvar, str_to_match); + dbg3("getenv('%s'):'%s'", rule->envvar, str_to_match); if (!str_to_match) continue; - } else { - /* regex to match [subsystem/]device_name */ - str_to_match = (rule->regex_has_slash ? path : device_name); } + /* else: str_to_match = device_name */ if (rule->regex_compiled) { int regex_match = regexec(&rule->match, str_to_match, ARRAY_SIZE(off), off, 0); - dbg("regex_match for '%s':%d", str_to_match, regex_match); + dbg3("regex_match for '%s':%d", str_to_match, regex_match); //bb_error_msg("matches:"); //for (int i = 0; i < ARRAY_SIZE(off); i++) { // if (off[i].rm_so < 0) continue; @@ -481,9 +686,8 @@ static void make_device(char *path, int delete) } /* else: it's final implicit "match-all" rule */ rule_matches: + dbg2("rule matched, line %d", G.parser ? G.parser->lineno : -1); #endif - dbg("rule matched"); - /* Build alias name */ alias = NULL; if (ENABLE_FEATURE_MDEV_RENAME && rule->ren_mov) { @@ -526,51 +730,64 @@ static void make_device(char *path, int delete) } } } - dbg("alias:'%s'", alias); + dbg3("alias:'%s'", alias); command = NULL; IF_FEATURE_MDEV_EXEC(command = rule->r_cmd;) if (command) { - const char *s = "$@*"; - const char *s2 = strchr(s, command[0]); - /* Are we running this command now? - * Run $cmd on delete, @cmd on create, *cmd on both + * Run @cmd on create, $cmd on delete, *cmd on any */ - if (s2 - s != delete) { - /* We are here if: '*', - * or: '@' and delete = 0, - * or: '$' and delete = 1 - */ + if ((command[0] == '@' && operation == OP_add) + || (command[0] == '$' && operation == OP_remove) + || (command[0] == '*') + ) { command++; } else { command = NULL; } } - dbg("command:'%s'", command); + dbg3("command:'%s'", command); /* "Execute" the line we found */ node_name = device_name; if (ENABLE_FEATURE_MDEV_RENAME && alias) { node_name = alias = build_alias(alias, device_name); - dbg("alias2:'%s'", alias); + dbg3("alias2:'%s'", alias); } - if (!delete && major >= 0) { - dbg("mknod('%s',%o,(%d,%d))", node_name, rule->mode | type, major, minor); + if (operation == OP_add && major >= 0) { + char *slash = strrchr(node_name, '/'); + if (slash) { + *slash = '\0'; + mkdir_recursive(node_name); + *slash = '/'; + } + if (ENABLE_FEATURE_MDEV_CONF) { + dbg1("mknod %s (%d,%d) %o" + " %u:%u", + node_name, major, minor, rule->mode | type, + rule->ugid.uid, rule->ugid.gid + ); + } else { + dbg1("mknod %s (%d,%d) %o", + node_name, major, minor, rule->mode | type + ); + } if (mknod(node_name, rule->mode | type, makedev(major, minor)) && errno != EEXIST) bb_perror_msg("can't create '%s'", node_name); - if (major == G.root_major && minor == G.root_minor) - symlink(node_name, "root"); if (ENABLE_FEATURE_MDEV_CONF) { chmod(node_name, rule->mode); chown(node_name, rule->ugid.uid, rule->ugid.gid); } + if (major == G.root_major && minor == G.root_minor) + symlink(node_name, "root"); if (ENABLE_FEATURE_MDEV_RENAME && alias) { if (aliaslink == '>') { //TODO: on devtmpfs, device_name already exists and symlink() fails. //End result is that instead of symlink, we have two nodes. //What should be done? + dbg1("symlink: %s", device_name); symlink(node_name, device_name); } } @@ -579,20 +796,21 @@ static void make_device(char *path, int delete) if (ENABLE_FEATURE_MDEV_EXEC && command) { /* setenv will leak memory, use putenv/unsetenv/free */ char *s = xasprintf("%s=%s", "MDEV", node_name); - char *s1 = xasprintf("%s=%s", "SUBSYSTEM", G.subsystem); putenv(s); - putenv(s1); + dbg1("running: %s", command); if (system(command) == -1) bb_perror_msg("can't run '%s'", command); - bb_unsetenv_and_free(s1); bb_unsetenv_and_free(s); } - if (delete && major >= -1) { + if (operation == OP_remove && major >= -1) { if (ENABLE_FEATURE_MDEV_RENAME && alias) { - if (aliaslink == '>') + if (aliaslink == '>') { + dbg1("unlink: %s", device_name); unlink(device_name); + } } + dbg1("unlink: %s", node_name); unlink(node_name); } @@ -605,8 +823,6 @@ static void make_device(char *path, int delete) if (!ENABLE_FEATURE_MDEV_CONF || !rule->keep_matching) break; } /* for (;;) */ - - free(subsystem_slash_devname); } /* File callback for /sys/ traversal */ @@ -624,7 +840,7 @@ static int FAST_FUNC fileAction(const char *fileName, strcpy(scratch, fileName); scratch[len] = '\0'; - make_device(scratch, /*delete:*/ 0); + make_device(/*DEVNAME:*/ NULL, scratch, OP_add); return TRUE; } @@ -639,9 +855,16 @@ static int FAST_FUNC dirAction(const char *fileName UNUSED_PARAM, * under /sys/class/ */ if (1 == depth) { free(G.subsystem); + if (G.subsys_env) { + bb_unsetenv_and_free(G.subsys_env); + G.subsys_env = NULL; + } G.subsystem = strrchr(fileName, '/'); - if (G.subsystem) + if (G.subsystem) { G.subsystem = xstrdup(G.subsystem + 1); + G.subsys_env = xasprintf("%s=%s", "SUBSYSTEM", G.subsystem); + putenv(G.subsys_env); + } } return (depth >= MAX_SYSFS_DEPTH ? SKIP : TRUE); @@ -696,7 +919,7 @@ static void load_firmware(const char *firmware, const char *sysfs_path) } /* Tell kernel result by "echo [0|-1] > /sys/$DEVPATH/loading" - * Note: we emit -1 if firmware file wasn't found. + * Note: we emit -1 also if firmware file wasn't found. * There are cases when otherwise kernel would wait for minutes * before timing out. */ @@ -706,12 +929,107 @@ static void load_firmware(const char *firmware, const char *sysfs_path) full_write(loading_fd, "-1", 2); out: + xchdir("/dev"); if (ENABLE_FEATURE_CLEAN_UP) { close(firmware_fd); close(loading_fd); } } +static char *curtime(void) +{ + struct timeval tv; + gettimeofday(&tv, NULL); + sprintf(G.timestr, "%u.%06u", (unsigned)tv.tv_sec % 60, (unsigned)tv.tv_usec); + return G.timestr; +} + +static void open_mdev_log(const char *seq, unsigned my_pid) +{ + int logfd = open("mdev.log", O_WRONLY | O_APPEND); + if (logfd >= 0) { + xmove_fd(logfd, STDERR_FILENO); + G.verbose = 2; + applet_name = xasprintf("%s[%s]", applet_name, seq ? seq : utoa(my_pid)); + } +} + +/* If it exists, does /dev/mdev.seq match $SEQNUM? + * If it does not match, earlier mdev is running + * in parallel, and we need to wait. + * Active mdev pokes us with SIGCHLD to check the new file. + */ +static int +wait_for_seqfile(const char *seq) +{ + /* We time out after 2 sec */ + static const struct timespec ts = { 0, 32*1000*1000 }; + int timeout = 2000 / 32; + int seq_fd = -1; + int do_once = 1; + sigset_t set_CHLD; + + sigemptyset(&set_CHLD); + sigaddset(&set_CHLD, SIGCHLD); + sigprocmask(SIG_BLOCK, &set_CHLD, NULL); + + for (;;) { + int seqlen; + char seqbuf[sizeof(int)*3 + 2]; + + if (seq_fd < 0) { + seq_fd = open("mdev.seq", O_RDWR); + if (seq_fd < 0) + break; + } + seqlen = pread(seq_fd, seqbuf, sizeof(seqbuf) - 1, 0); + if (seqlen < 0) { + close(seq_fd); + seq_fd = -1; + break; + } + seqbuf[seqlen] = '\0'; + if (seqbuf[0] == '\n') { + /* seed file: write out seq ASAP */ + xwrite_str(seq_fd, seq); + xlseek(seq_fd, 0, SEEK_SET); + dbg2("first seq written"); + break; + } + if (strcmp(seq, seqbuf) == 0) { + /* correct idx */ + break; + } + if (do_once) { + dbg2("%s waiting for '%s'", curtime(), seqbuf); + do_once = 0; + } + if (sigtimedwait(&set_CHLD, NULL, &ts) >= 0) { + dbg3("woken up"); + continue; /* don't decrement timeout! */ + } + if (--timeout == 0) { + dbg1("%s waiting for '%s'", "timed out", seqbuf); + break; + } + } + sigprocmask(SIG_UNBLOCK, &set_CHLD, NULL); + return seq_fd; +} + +static void signal_mdevs(unsigned my_pid) +{ + procps_status_t* p = NULL; + while ((p = procps_scan(p, PSSCAN_ARGV0)) != NULL) { + if (p->pid != my_pid + && p->argv0 + && strcmp(bb_basename(p->argv0), "mdev") == 0 + ) { + kill(p->pid, SIGCHLD); + } + } +} + int mdev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int mdev_main(int argc UNUSED_PARAM, char **argv) { @@ -733,8 +1051,8 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) xchdir("/dev"); if (argv[1] && strcmp(argv[1], "-s") == 0) { - /* Scan: - * mdev -s + /* + * Scan: mdev -s */ struct stat st; @@ -746,6 +1064,8 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) G.root_major = major(st.st_dev); G.root_minor = minor(st.st_dev); + putenv((char*)"ACTION=add"); + /* ACTION_FOLLOWLINKS is needed since in newer kernels * /sys/block/loop* (for example) are symlinks to dirs, * not real directories. @@ -769,66 +1089,60 @@ int mdev_main(int argc UNUSED_PARAM, char **argv) char *fw; char *seq; char *action; - char *env_path; - static const char keywords[] ALIGN1 = "remove\0add\0"; - enum { OP_remove = 0, OP_add }; + char *env_devname; + char *env_devpath; + unsigned my_pid; + int seq_fd; smalluint op; /* Hotplug: * env ACTION=... DEVPATH=... SUBSYSTEM=... [SEQNUM=...] mdev - * ACTION can be "add" or "remove" + * ACTION can be "add", "remove", "change" * DEVPATH is like "/block/sda" or "/class/input/mice" */ action = getenv("ACTION"); - env_path = getenv("DEVPATH"); + op = index_in_strings(keywords, action); + env_devname = getenv("DEVNAME"); /* can be NULL */ + env_devpath = getenv("DEVPATH"); G.subsystem = getenv("SUBSYSTEM"); - if (!action || !env_path /*|| !G.subsystem*/) + if (!action || !env_devpath /*|| !G.subsystem*/) bb_show_usage(); fw = getenv("FIRMWARE"); - op = index_in_strings(keywords, action); - /* If it exists, does /dev/mdev.seq match $SEQNUM? - * If it does not match, earlier mdev is running - * in parallel, and we need to wait */ seq = getenv("SEQNUM"); - if (seq) { - int timeout = 2000 / 32; /* 2000 msec */ - do { - int seqlen; - char seqbuf[sizeof(int)*3 + 2]; - - seqlen = open_read_close("mdev.seq", seqbuf, sizeof(seqbuf) - 1); - if (seqlen < 0) { - seq = NULL; - break; - } - seqbuf[seqlen] = '\0'; - if (seqbuf[0] == '\n' /* seed file? */ - || strcmp(seq, seqbuf) == 0 /* correct idx? */ - ) { - break; - } - usleep(32*1000); - } while (--timeout); - } - snprintf(temp, PATH_MAX, "/sys%s", env_path); + my_pid = getpid(); + open_mdev_log(seq, my_pid); + + seq_fd = seq ? wait_for_seqfile(seq) : -1; + + dbg1("%s " + "ACTION:%s SUBSYSTEM:%s DEVNAME:%s DEVPATH:%s" + "%s%s", + curtime(), + action, G.subsystem, env_devname, env_devpath, + fw ? " FW:" : "", fw ? fw : "" + ); + + snprintf(temp, PATH_MAX, "/sys%s", env_devpath); if (op == OP_remove) { /* Ignoring "remove firmware". It was reported * to happen and to cause erroneous deletion * of device nodes. */ if (!fw) - make_device(temp, /*delete:*/ 1); + make_device(env_devname, temp, op); } - else if (op == OP_add) { - make_device(temp, /*delete:*/ 0); + else { + make_device(env_devname, temp, op); if (ENABLE_FEATURE_MDEV_LOAD_FIRMWARE) { - if (fw) + if (op == OP_add && fw) load_firmware(fw, temp); } } - if (seq) { - xopen_xwrite_close("mdev.seq", utoa(xatou(seq) + 1)); + dbg1("%s exiting", curtime()); + if (seq_fd >= 0) { + xwrite_str(seq_fd, utoa(xatou(seq) + 1)); + signal_mdevs(my_pid); } } diff --git a/release/src/router/busybox/util-linux/mount.c b/release/src/router/busybox/util-linux/mount.c index 13f43d4b16..a2de9fd4df 100644 --- a/release/src/router/busybox/util-linux/mount.c +++ b/release/src/router/busybox/util-linux/mount.c @@ -36,6 +36,10 @@ //usage: IF_FEATURE_MTAB_SUPPORT( //usage: "\n -n Don't update /etc/mtab" //usage: ) +//usage: IF_FEATURE_MOUNT_VERBOSE( +//usage: "\n -v Verbose" +//usage: ) +////usage: "\n -s Sloppy (ignored)" //usage: "\n -r Read-only mount" //usage: "\n -w Read-write mount (default)" //usage: "\n -t FSTYPE[,...] Filesystem type(s)" @@ -113,6 +117,12 @@ #ifndef MS_RELATIME # define MS_RELATIME (1 << 21) #endif +#ifndef MS_STRICTATIME +# define MS_STRICTATIME (1 << 24) +#endif + +/* Any ~MS_FOO value has this bit set: */ +#define BB_MS_INVERTED_VALUE (1u << 31) #include "libbb.h" #if ENABLE_FEATURE_MOUNT_LABEL @@ -218,6 +228,7 @@ static const int32_t mount_options[] = { IF_DESKTOP(/* "user" */ MOUNT_USERS,) IF_DESKTOP(/* "users" */ MOUNT_USERS,) /* "_netdev" */ 0, + IF_DESKTOP(/* "comment=" */ 0,) /* systemd uses this in fstab */ ) IF_FEATURE_MOUNT_FLAGS( @@ -239,6 +250,7 @@ static const int32_t mount_options[] = { /* "nomand" */ ~MS_MANDLOCK, /* "relatime" */ MS_RELATIME, /* "norelatime" */ ~MS_RELATIME, + /* "strictatime" */ MS_STRICTATIME, /* "loud" */ ~MS_SILENT, /* "rbind" */ MS_BIND|MS_RECURSIVE, @@ -275,6 +287,7 @@ static const char mount_option_str[] = IF_DESKTOP("user\0") IF_DESKTOP("users\0") "_netdev\0" + IF_DESKTOP("comment=\0") /* systemd uses this in fstab */ ) IF_FEATURE_MOUNT_FLAGS( // vfs flags @@ -295,6 +308,7 @@ static const char mount_option_str[] = "nomand\0" "relatime\0" "norelatime\0" + "strictatime\0" "loud\0" "rbind\0" @@ -450,9 +464,9 @@ static void append_mount_options(char **oldopts, const char *newopts) // Use the mount_options list to parse options into flags. // Also update list of unrecognized options if unrecognized != NULL -static long parse_mount_options(char *options, char **unrecognized) +static unsigned long parse_mount_options(char *options, char **unrecognized) { - long flags = MS_SILENT; + unsigned long flags = MS_SILENT; // Loop through options for (;;) { @@ -465,15 +479,22 @@ static long parse_mount_options(char *options, char **unrecognized) // FIXME: use hasmntopt() // Find this option in mount_options for (i = 0; i < ARRAY_SIZE(mount_options); i++) { - if (strcasecmp(option_str, options) == 0) { - long fl = mount_options[i]; - if (fl < 0) + unsigned opt_len = strlen(option_str); + + if (strncasecmp(option_str, options, opt_len) == 0 + && (options[opt_len] == '\0' + /* or is it "comment=" thingy in fstab? */ + IF_FEATURE_MOUNT_FSTAB(IF_DESKTOP( || option_str[opt_len-1] == '=' )) + ) + ) { + unsigned long fl = mount_options[i]; + if (fl & BB_MS_INVERTED_VALUE) flags &= fl; else flags |= fl; goto found; } - option_str += strlen(option_str) + 1; + option_str += opt_len + 1; } // We did not recognize this option. // If "unrecognized" is not NULL, append option there. @@ -548,7 +569,7 @@ void delete_block_backed_filesystems(void); // Perform actual mount of specific filesystem at specific location. // NB: mp->xxx fields may be trashed on exit -static int mount_it_now(struct mntent *mp, long vfsflags, char *filteropts) +static int mount_it_now(struct mntent *mp, unsigned long vfsflags, char *filteropts) { int rc = 0; @@ -913,7 +934,7 @@ static bool_t xdr_fhandle(XDR *xdrs, fhandle objp) static bool_t xdr_fhstatus(XDR *xdrs, fhstatus *objp) { if (!xdr_u_int(xdrs, &objp->fhs_status)) - return FALSE; + return FALSE; if (objp->fhs_status == 0) return xdr_fhandle(xdrs, objp->fhstatus_u.fhs_fhandle); return TRUE; @@ -927,8 +948,8 @@ static bool_t xdr_dirpath(XDR *xdrs, dirpath *objp) static bool_t xdr_fhandle3(XDR *xdrs, fhandle3 *objp) { return xdr_bytes(xdrs, (char **)&objp->fhandle3_val, - (unsigned int *) &objp->fhandle3_len, - FHSIZE3); + (unsigned int *) &objp->fhandle3_len, + FHSIZE3); } static bool_t xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp) @@ -936,10 +957,10 @@ static bool_t xdr_mountres3_ok(XDR *xdrs, mountres3_ok *objp) if (!xdr_fhandle3(xdrs, &objp->fhandle)) return FALSE; return xdr_array(xdrs, &(objp->auth_flavours.auth_flavours_val), - &(objp->auth_flavours.auth_flavours_len), - ~0, - sizeof(int), - (xdrproc_t) xdr_int); + &(objp->auth_flavours.auth_flavours_len), + ~0, + sizeof(int), + (xdrproc_t) xdr_int); } static bool_t xdr_mountstat3(XDR *xdrs, mountstat3 *objp) @@ -1080,7 +1101,7 @@ static void error_msg_rpc(const char *msg) } /* NB: mp->xxx fields may be trashed on exit */ -static NOINLINE int nfsmount(struct mntent *mp, long vfsflags, char *filteropts) +static NOINLINE int nfsmount(struct mntent *mp, unsigned long vfsflags, char *filteropts) { CLIENT *mclient; char *hostname; @@ -1508,19 +1529,19 @@ static NOINLINE int nfsmount(struct mntent *mp, long vfsflags, char *filteropts) switch (pm_mnt.pm_prot) { case IPPROTO_UDP: mclient = clntudp_create(&mount_server_addr, - pm_mnt.pm_prog, - pm_mnt.pm_vers, - retry_timeout, - &msock); + pm_mnt.pm_prog, + pm_mnt.pm_vers, + retry_timeout, + &msock); if (mclient) break; mount_server_addr.sin_port = htons(pm_mnt.pm_port); msock = RPC_ANYSOCK; case IPPROTO_TCP: mclient = clnttcp_create(&mount_server_addr, - pm_mnt.pm_prog, - pm_mnt.pm_vers, - &msock, 0, 0); + pm_mnt.pm_prog, + pm_mnt.pm_vers, + &msock, 0, 0); break; default: mclient = NULL; @@ -1541,18 +1562,18 @@ static NOINLINE int nfsmount(struct mntent *mp, long vfsflags, char *filteropts) if (pm_mnt.pm_vers == 3) clnt_stat = clnt_call(mclient, MOUNTPROC3_MNT, - (xdrproc_t) xdr_dirpath, - (caddr_t) &pathname, - (xdrproc_t) xdr_mountres3, - (caddr_t) &status, - total_timeout); + (xdrproc_t) xdr_dirpath, + (caddr_t) &pathname, + (xdrproc_t) xdr_mountres3, + (caddr_t) &status, + total_timeout); else clnt_stat = clnt_call(mclient, MOUNTPROC_MNT, - (xdrproc_t) xdr_dirpath, - (caddr_t) &pathname, - (xdrproc_t) xdr_fhstatus, - (caddr_t) &status, - total_timeout); + (xdrproc_t) xdr_dirpath, + (caddr_t) &pathname, + (xdrproc_t) xdr_fhstatus, + (caddr_t) &status, + total_timeout); if (clnt_stat == RPC_SUCCESS) goto prepare_kernel_data; /* we're done */ @@ -1711,7 +1732,7 @@ static NOINLINE int nfsmount(struct mntent *mp, long vfsflags, char *filteropts) * For older kernels, you must build busybox with ENABLE_FEATURE_MOUNT_NFS. * (However, note that then you lose any chances that NFS over IPv6 would work). */ -static int nfsmount(struct mntent *mp, long vfsflags, char *filteropts) +static int nfsmount(struct mntent *mp, unsigned long vfsflags, char *filteropts) { len_and_sockaddr *lsa; char *opts; @@ -1754,7 +1775,7 @@ static int nfsmount(struct mntent *mp, long vfsflags, char *filteropts) static int singlemount(struct mntent *mp, int ignore_busy) { int rc = -1; - long vfsflags; + unsigned long vfsflags; char *loopFile = NULL, *filteropts = NULL; llist_t *fl = NULL; struct stat st; @@ -1804,17 +1825,44 @@ static int singlemount(struct mntent *mp, int ignore_busy) ) { int len; char c; + char *hostname, *share; + char *dotted, *ip; len_and_sockaddr *lsa; - char *hostname, *dotted, *ip; + + // Parse mp->mnt_fsname of the form "//hostname/share[/dir1/dir2]" hostname = mp->mnt_fsname + 2; len = strcspn(hostname, "/\\"); - if (len == 0 || hostname[len] == '\0') + share = hostname + len + 1; + if (len == 0 // 3rd char is a [back]slash (IOW: empty hostname) + || share[-1] == '\0' // no [back]slash after hostname + || share[0] == '\0' // empty share name + ) { goto report_error; - c = hostname[len]; - hostname[len] = '\0'; + } + c = share[-1]; + share[-1] = '\0'; + len = strcspn(share, "/\\"); + + // "unc=\\hostname\share" option is mandatory + // after CIFS option parsing was rewritten in Linux 3.4. + // Must use backslashes. + // If /dir1/dir2 is present, also add "prefixpath=dir1/dir2" + { + char *unc = xasprintf( + share[len] != '\0' /* "/dir1/dir2" exists? */ + ? "unc=\\\\%s\\%.*s,prefixpath=%s" + : "unc=\\\\%s\\%.*s", + hostname, + len, share, + share + len + 1 /* "dir1/dir2" */ + ); + parse_mount_options(unc, &filteropts); + if (ENABLE_FEATURE_CLEAN_UP) free(unc); + } + lsa = host2sockaddr(hostname, 0); - hostname[len] = c; + share[-1] = c; if (!lsa) goto report_error; @@ -1826,8 +1874,6 @@ static int singlemount(struct mntent *mp, int ignore_busy) parse_mount_options(ip, &filteropts); if (ENABLE_FEATURE_CLEAN_UP) free(ip); - // "-o mand" is required [why?] - vfsflags |= MS_MANDLOCK; mp->mnt_type = (char*)"cifs"; rc = mount_it_now(mp, vfsflags, filteropts); @@ -1855,7 +1901,7 @@ static int singlemount(struct mntent *mp, int ignore_busy) if (ENABLE_FEATURE_MOUNT_LOOP && S_ISREG(st.st_mode)) { loopFile = bb_simplify_path(mp->mnt_fsname); mp->mnt_fsname = NULL; // will receive malloced loop dev name - if (set_loop(&mp->mnt_fsname, loopFile, 0, /*ro:*/ 0) < 0) { + if (set_loop(&mp->mnt_fsname, loopFile, 0, /*ro:*/ (vfsflags & MS_RDONLY)) < 0) { if (errno == EPERM || errno == EACCES) bb_error_msg(bb_msg_perm_denied_are_you_root); else @@ -1993,6 +2039,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv) FILE *fstab; int i, j; int rc = EXIT_SUCCESS; + unsigned long cmdopt_flags; unsigned opt; struct mntent mtpair[2], *mtcur = mtpair; IF_NOT_DESKTOP(const int nonroot = 0;) @@ -2067,16 +2114,16 @@ int mount_main(int argc UNUSED_PARAM, char **argv) // Past this point, we are handling either "mount -a [opts]" // or "mount [opts] single_param" - i = parse_mount_options(cmdopts, NULL); // FIXME: should be "long", not "int" - if (nonroot && (i & ~MS_SILENT)) // Non-root users cannot specify flags + cmdopt_flags = parse_mount_options(cmdopts, NULL); + if (nonroot && (cmdopt_flags & ~MS_SILENT)) // Non-root users cannot specify flags bb_error_msg_and_die(bb_msg_you_must_be_root); // If we have a shared subtree flag, don't worry about fstab or mtab. if (ENABLE_FEATURE_MOUNT_FLAGS - && (i & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) + && (cmdopt_flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) ) { // verbose_mount(source, target, type, flags, data) - rc = verbose_mount("", argv[0], "", i, ""); + rc = verbose_mount("", argv[0], "", cmdopt_flags, ""); if (rc) bb_simple_perror_msg_and_die(argv[0]); return rc; @@ -2084,7 +2131,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv) // Open either fstab or mtab fstabname = "/etc/fstab"; - if (i & MS_REMOUNT) { + if (cmdopt_flags & MS_REMOUNT) { // WARNING. I am not sure this matches util-linux's // behavior. It's possible util-linux does not // take -o opts from mtab (takes only mount source). @@ -2183,7 +2230,7 @@ int mount_main(int argc UNUSED_PARAM, char **argv) // End of fstab/mtab is reached. // Were we looking for something specific? if (argv[0]) { // yes - long l; + unsigned long l; // If we didn't find anything, complain if (!mtcur->mnt_fsname) diff --git a/release/src/router/busybox/util-linux/rdate.c b/release/src/router/busybox/util-linux/rdate.c index 1f36d8f37b..6e35cd5190 100644 --- a/release/src/router/busybox/util-linux/rdate.c +++ b/release/src/router/busybox/util-linux/rdate.c @@ -1,7 +1,7 @@ /* vi: set sw=4 ts=4: */ /* * The Rdate command will ask a time server for the RFC 868 time - * and optionally set the system time. + * and optionally set the system time. * * by Sterling Huxley * @@ -11,9 +11,9 @@ //usage:#define rdate_trivial_usage //usage: "[-sp] HOST" //usage:#define rdate_full_usage "\n\n" -//usage: "Get and possibly set the system date and time from a remote HOST\n" -//usage: "\n -s Set the system date and time (default)" -//usage: "\n -p Print the date and time" +//usage: "Get and possibly set the system date/time from a remote HOST\n" +//usage: "\n -s Set the system date/time (default)" +//usage: "\n -p Print the date/time" #include "libbb.h" @@ -35,15 +35,16 @@ static time_t askremotedate(const char *host) fd = create_and_connect_stream_or_die(host, bb_lookup_port("time", "tcp", 37)); - if (safe_read(fd, (void *)&nett, 4) != 4) /* read time from server */ + if (safe_read(fd, &nett, 4) != 4) /* read time from server */ bb_error_msg_and_die("%s did not send the complete time", host); - close(fd); + if (ENABLE_FEATURE_CLEAN_UP) + close(fd); - /* convert from network byte order to local byte order. + /* Convert from network byte order to local byte order. * RFC 868 time is the number of seconds * since 00:00 (midnight) 1 January 1900 GMT * the RFC 868 time 2,208,988,800 corresponds to 00:00 1 Jan 1970 GMT - * Subtract the RFC 868 time to get Linux epoch + * Subtract the RFC 868 time to get Linux epoch. */ return ntohl(nett) - RFC_868_BIAS; @@ -53,14 +54,14 @@ int rdate_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int rdate_main(int argc UNUSED_PARAM, char **argv) { time_t remote_time; - unsigned long flags; + unsigned flags; opt_complementary = "-1"; flags = getopt32(argv, "sp"); remote_time = askremotedate(argv[optind]); - if ((flags & 2) == 0) { + if (!(flags & 2)) { /* no -p (-s may be present) */ time_t current_time; time(¤t_time); @@ -71,7 +72,7 @@ int rdate_main(int argc UNUSED_PARAM, char **argv) bb_perror_msg_and_die("can't set time of day"); } - if ((flags & 1) == 0) + if (flags != 1) /* not lone -s */ printf("%s", ctime(&remote_time)); return EXIT_SUCCESS; diff --git a/release/src/router/busybox/util-linux/readprofile.c b/release/src/router/busybox/util-linux/readprofile.c index 4ed8011377..974fe89c48 100644 --- a/release/src/router/busybox/util-linux/readprofile.c +++ b/release/src/router/busybox/util-linux/readprofile.c @@ -163,7 +163,7 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv) while (fgets(mapline, S_LEN, map)) { if (sscanf(mapline, "%llx %s %s", &fn_add, mode, fn_name) != 3) bb_error_msg_and_die("%s(%i): wrong map line", - mapFile, maplineno); + mapFile, maplineno); if (!strcmp(fn_name, "_stext")) /* only elf works like this */ { add0 = fn_add; @@ -198,7 +198,7 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv) if (indx >= len / sizeof(*buf)) bb_error_msg_and_die("profile address out of range. " - "Wrong map file?"); + "Wrong map file?"); while (indx < (next_add-add0)/step) { if (optBins && (buf[indx] || optAll)) { @@ -220,10 +220,10 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv) ) { if (optVerbose) printf("%016llx %-40s %6i %8.4f\n", fn_add, - fn_name, this, this/(double)fn_len); + fn_name, this, this/(double)fn_len); else printf("%6i %-40s %8.4f\n", - this, fn_name, this/(double)fn_len); + this, fn_name, this/(double)fn_len); if (optSub) { unsigned long long scan; @@ -233,8 +233,8 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv) addr = (scan - 1)*step + add0; printf("\t%#llx\t%s+%#llx\t%u\n", - addr, fn_name, addr - fn_add, - buf[scan]); + addr, fn_name, addr - fn_add, + buf[scan]); } } } @@ -251,10 +251,10 @@ int readprofile_main(int argc UNUSED_PARAM, char **argv) /* trailer */ if (optVerbose) printf("%016x %-40s %6i %8.4f\n", - 0, "total", total, total/(double)(fn_add-add0)); + 0, "total", total, total/(double)(fn_add-add0)); else printf("%6i %-40s %8.4f\n", - total, "total", total/(double)(fn_add-add0)); + total, "total", total/(double)(fn_add-add0)); fclose(map); free(buf); diff --git a/release/src/router/busybox/util-linux/volume_id/Kbuild.src b/release/src/router/busybox/util-linux/volume_id/Kbuild.src index 430d2a75d5..ff19fabc4d 100644 --- a/release/src/router/busybox/util-linux/volume_id/Kbuild.src +++ b/release/src/router/busybox/util-linux/volume_id/Kbuild.src @@ -31,6 +31,7 @@ lib-$(CONFIG_FEATURE_VOLUMEID_LINUXSWAP) += linux_swap.o ### lib-$(CONFIG_FEATURE_VOLUMEID_LVM) += lvm.o ### lib-$(CONFIG_FEATURE_VOLUMEID_MAC) += mac.o ### lib-$(CONFIG_FEATURE_VOLUMEID_MSDOS) += msdos.o +lib-$(CONFIG_FEATURE_VOLUMEID_NILFS) += nilfs.o lib-$(CONFIG_FEATURE_VOLUMEID_NTFS) += ntfs.o lib-$(CONFIG_FEATURE_VOLUMEID_EXFAT) += exfat.o lib-$(CONFIG_FEATURE_VOLUMEID_REISERFS) += reiserfs.o diff --git a/release/src/router/busybox/util-linux/volume_id/btrfs.c b/release/src/router/busybox/util-linux/volume_id/btrfs.c index 777b809236..ee71d2e003 100644 --- a/release/src/router/busybox/util-linux/volume_id/btrfs.c +++ b/release/src/router/busybox/util-linux/volume_id/btrfs.c @@ -102,6 +102,7 @@ int FAST_FUNC volume_id_probe_btrfs(struct volume_id *id /*,uint64_t off*/) // N.B.: btrfs natively supports 256 (>VOLUME_ID_LABEL_SIZE) size labels volume_id_set_label_string(id, sb->label, VOLUME_ID_LABEL_SIZE); volume_id_set_uuid(id, sb->fsid, UUID_DCE); + IF_FEATURE_BLKID_TYPE(id->type = "btrfs";) return 0; } diff --git a/release/src/router/busybox/util-linux/volume_id/exfat.c b/release/src/router/busybox/util-linux/volume_id/exfat.c index 49249102c1..a38a8916d8 100644 --- a/release/src/router/busybox/util-linux/volume_id/exfat.c +++ b/release/src/router/busybox/util-linux/volume_id/exfat.c @@ -16,7 +16,6 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * From Busybox 1.21.1 to Tomato RAF */ #include "volume_id_internal.h" diff --git a/release/src/router/busybox/util-linux/volume_id/ext.c b/release/src/router/busybox/util-linux/volume_id/ext.c dissimilarity index 63% index aa23d1ebf1..97451067fd 100644 --- a/release/src/router/busybox/util-linux/volume_id/ext.c +++ b/release/src/router/busybox/util-linux/volume_id/ext.c @@ -1,120 +1,60 @@ -/* - * volume_id - reads filesystem label and uuid - * - * Copyright (C) 2004 Kay Sievers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "volume_id_internal.h" - -struct ext2_super_block { - uint32_t inodes_count; - uint32_t blocks_count; - uint32_t r_blocks_count; - uint32_t free_blocks_count; - uint32_t free_inodes_count; - uint32_t first_data_block; - uint32_t log_block_size; - uint32_t dummy3[7]; - uint8_t magic[2]; - uint16_t state; - uint32_t dummy5[8]; - uint32_t feature_compat; - uint32_t feature_incompat; - uint32_t feature_ro_compat; - uint8_t uuid[16]; - uint8_t volume_name[16]; -} PACKED; - -#define EXT_SUPERBLOCK_OFFSET 0x400 - -/* for s_flags */ -#define EXT2_FLAGS_TEST_FILESYS 0x0004 - -/* for s_feature_compat */ -#define EXT3_FEATURE_COMPAT_HAS_JOURNAL 0x0004 - -/* for s_feature_ro_compat */ -#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER 0x0001 -#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE 0x0002 -#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR 0x0004 -#define EXT4_FEATURE_RO_COMPAT_HUGE_FILE 0x0008 -#define EXT4_FEATURE_RO_COMPAT_GDT_CSUM 0x0010 -#define EXT4_FEATURE_RO_COMPAT_DIR_NLINK 0x0020 -#define EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE 0x0040 - -/* for s_feature_incompat */ -#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002 -#define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 -#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 -#define EXT2_FEATURE_INCOMPAT_META_BG 0x0010 -#define EXT4_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ -#define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 -#define EXT4_FEATURE_INCOMPAT_MMP 0x0100 -#define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 - -#define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ - EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ - EXT2_FEATURE_RO_COMPAT_BTREE_DIR) -#define EXT2_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ - EXT2_FEATURE_INCOMPAT_META_BG) -#define EXT2_FEATURE_INCOMPAT_UNSUPPORTED ~EXT2_FEATURE_INCOMPAT_SUPP -#define EXT2_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT2_FEATURE_RO_COMPAT_SUPP - -#define EXT3_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ - EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ - EXT2_FEATURE_RO_COMPAT_BTREE_DIR) -#define EXT3_FEATURE_INCOMPAT_SUPP (EXT2_FEATURE_INCOMPAT_FILETYPE| \ - EXT3_FEATURE_INCOMPAT_RECOVER| \ - EXT2_FEATURE_INCOMPAT_META_BG) -#define EXT3_FEATURE_INCOMPAT_UNSUPPORTED ~EXT3_FEATURE_INCOMPAT_SUPP -#define EXT3_FEATURE_RO_COMPAT_UNSUPPORTED ~EXT3_FEATURE_RO_COMPAT_SUPP - -int FAST_FUNC volume_id_probe_ext(struct volume_id *id /*,uint64_t off*/) -{ -#define off ((uint64_t)0) - struct ext2_super_block *es; - - dbg("ext: probing at offset 0x%llx", (unsigned long long) off); - - es = volume_id_get_buffer(id, off + EXT_SUPERBLOCK_OFFSET, 0x200); - if (es == NULL) - return -1; - - if (es->magic[0] != 0123 || es->magic[1] != 0357) { - dbg("ext: no magic found"); - return -1; - } - -// volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -// volume_id_set_label_raw(id, es->volume_name, 16); - volume_id_set_label_string(id, es->volume_name, 16); - volume_id_set_uuid(id, es->uuid, UUID_DCE); - dbg("ext: label '%s' uuid '%s'", id->label, id->uuid); - -#if ENABLE_FEATURE_BLKID_TYPE - if ((es->feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_HUGE_FILE | EXT4_FEATURE_RO_COMPAT_DIR_NLINK)) - || (es->feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_EXTENTS | EXT4_FEATURE_INCOMPAT_64BIT)) - ) { - id->type = "ext4"; - } - else if (es->feature_compat & cpu_to_le32(EXT3_FEATURE_COMPAT_HAS_JOURNAL)) - id->type = "ext3"; - else - id->type = "ext2"; -#endif - return 0; -} +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "volume_id_internal.h" +#include "bb_e2fs_defs.h" + +#define EXT_SUPERBLOCK_OFFSET 0x400 + +int FAST_FUNC volume_id_probe_ext(struct volume_id *id /*,uint64_t off*/) +{ +#define off ((uint64_t)0) + struct ext2_super_block *es; + + dbg("ext: probing at offset 0x%llx", (unsigned long long) off); + + es = volume_id_get_buffer(id, off + EXT_SUPERBLOCK_OFFSET, 0x200); + if (es == NULL) + return -1; + + if (es->s_magic != cpu_to_le16(EXT2_SUPER_MAGIC)) { + dbg("ext: no magic found"); + return -1; + } + +// volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); +// volume_id_set_label_raw(id, es->volume_name, 16); + volume_id_set_label_string(id, (void*)es->s_volume_name, 16); + volume_id_set_uuid(id, es->s_uuid, UUID_DCE); + dbg("ext: label '%s' uuid '%s'", id->label, id->uuid); + +#if ENABLE_FEATURE_BLKID_TYPE + if ((es->s_feature_ro_compat & cpu_to_le32(EXT4_FEATURE_RO_COMPAT_HUGE_FILE | EXT4_FEATURE_RO_COMPAT_DIR_NLINK)) + || (es->s_feature_incompat & cpu_to_le32(EXT4_FEATURE_INCOMPAT_EXTENTS | EXT4_FEATURE_INCOMPAT_64BIT)) + ) { + id->type = "ext4"; + } + else if (es->s_feature_compat & cpu_to_le32(EXT3_FEATURE_COMPAT_HAS_JOURNAL)) + id->type = "ext3"; + else + id->type = "ext2"; +#endif + return 0; +} diff --git a/release/src/router/busybox/util-linux/volume_id/get_devname.c b/release/src/router/busybox/util-linux/volume_id/get_devname.c index 3390e7ec43..9c626026cb 100644 --- a/release/src/router/busybox/util-linux/volume_id/get_devname.c +++ b/release/src/router/busybox/util-linux/volume_id/get_devname.c @@ -49,7 +49,11 @@ get_label_uuid(int fd, char **label, char **uuid, const char **type) if (volume_id_probe_all(vid, /*0,*/ size) != 0) goto ret; - if (vid->label[0] != '\0' || vid->uuid[0] != '\0') { + if (vid->label[0] != '\0' || vid->uuid[0] != '\0' +#if ENABLE_FEATURE_BLKID_TYPE + || vid->type != NULL +#endif + ) { *label = xstrndup(vid->label, sizeof(vid->label)); *uuid = xstrndup(vid->uuid, sizeof(vid->uuid)); #if ENABLE_FEATURE_BLKID_TYPE diff --git a/release/src/router/busybox/util-linux/volume_id/hfs.c b/release/src/router/busybox/util-linux/volume_id/hfs.c index f3f19dba71..3d9704d128 100644 --- a/release/src/router/busybox/util-linux/volume_id/hfs.c +++ b/release/src/router/busybox/util-linux/volume_id/hfs.c @@ -131,6 +131,27 @@ struct hfsplus_vol_header { #define HFS_NODE_LEAF 0xff #define HFSPLUS_POR_CNID 1 +static void FAST_FUNC hfs_set_uuid(struct volume_id *id, const uint8_t *hfs_id) +{ +#define hfs_id_len 8 + md5_ctx_t md5c; + uint8_t uuid[16]; + unsigned i; + + for (i = 0; i < hfs_id_len; i++) + if (hfs_id[i] != 0) + goto do_md5; + return; + do_md5: + md5_begin(&md5c); + md5_hash(&md5c, "\263\342\17\71\362\222\21\326\227\244\0\60\145\103\354\254", 16); + md5_hash(&md5c, hfs_id, hfs_id_len); + md5_end(&md5c, uuid); + uuid[6] = 0x30 | (uuid[6] & 0x0f); + uuid[8] = 0x80 | (uuid[8] & 0x3f); + volume_id_set_uuid(id, uuid, UUID_DCE); +} + int FAST_FUNC volume_id_probe_hfs_hfsplus(struct volume_id *id /*,uint64_t off*/) { uint64_t off = 0; @@ -193,7 +214,7 @@ int FAST_FUNC volume_id_probe_hfs_hfsplus(struct volume_id *id /*,uint64_t off*/ volume_id_set_label_string(id, hfs->label, hfs->label_len) ; } - volume_id_set_uuid(id, hfs->finder_info.id, UUID_HFS); + hfs_set_uuid(id, hfs->finder_info.id); // volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); IF_FEATURE_BLKID_TYPE(id->type = "hfs";) @@ -207,7 +228,7 @@ int FAST_FUNC volume_id_probe_hfs_hfsplus(struct volume_id *id /*,uint64_t off*/ return -1; hfsplus: - volume_id_set_uuid(id, hfsplus->finder_info.id, UUID_HFS); + hfs_set_uuid(id, hfsplus->finder_info.id); blocksize = be32_to_cpu(hfsplus->blocksize); dbg("blocksize %u", blocksize); @@ -286,7 +307,7 @@ int FAST_FUNC volume_id_probe_hfs_hfsplus(struct volume_id *id /*,uint64_t off*/ found: // volume_id_set_usage(id, VOLUME_ID_FILESYSTEM); -// id->type = "hfsplus"; + IF_FEATURE_BLKID_TYPE(id->type = "hfsplus";) return 0; } diff --git a/release/src/router/busybox/util-linux/volume_id/linux_raid.c b/release/src/router/busybox/util-linux/volume_id/linux_raid.c index 761e54f9f3..209eaabe97 100644 --- a/release/src/router/busybox/util-linux/volume_id/linux_raid.c +++ b/release/src/router/busybox/util-linux/volume_id/linux_raid.c @@ -69,9 +69,9 @@ int FAST_FUNC volume_id_probe_linux_raid(struct volume_id *id /*,uint64_t off*/, volume_id_set_uuid(id, uuid, UUID_DCE); // snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u.%u", -// le32_to_cpu(mdp->major_version), -// le32_to_cpu(mdp->minor_version), -// le32_to_cpu(mdp->patch_version)); +// le32_to_cpu(mdp->major_version), +// le32_to_cpu(mdp->minor_version), +// le32_to_cpu(mdp->patch_version)); dbg("found raid signature"); // volume_id_set_usage(id, VOLUME_ID_RAID); diff --git a/release/src/router/busybox/util-linux/volume_id/nilfs.c b/release/src/router/busybox/util-linux/volume_id/nilfs.c new file mode 100644 index 0000000000..b88a9e4358 --- /dev/null +++ b/release/src/router/busybox/util-linux/volume_id/nilfs.c @@ -0,0 +1,96 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2004 Kay Sievers + * Copyright (C) 2012 S-G Bergh + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "volume_id_internal.h" + +#define NILFS_UUID_SIZE 16 +#define NILFS_LABEL_SIZE 80 +#define NILFS_SB1_OFFSET 0x400 +#define NILFS_SB2_OFFSET 0x1000 +#define NILFS_MAGIC 0x3434 + +struct nilfs2_super_block { +/* 0x00 */ uint32_t s_rev_level; // Major revision level. +/* 0x04 */ uint16_t s_minor_rev_level; // Minor revision level. +/* 0x06 */ uint16_t s_magic; // Magic signature. +/* 0x08 */ uint16_t s_bytes; +/* 0x0A */ uint16_t s_flags; +/* 0x0C */ uint32_t s_crc_seed; +/* 0x10 */ uint32_t s_sum; +/* 0x14 */ uint32_t s_log_block_size; +/* 0x18 */ uint64_t s_nsegments; +/* 0x20 */ uint64_t s_dev_size; // Block device size in bytes. +/* 0x28 */ uint64_t s_first_data_block; +/* 0x30 */ uint32_t s_blocks_per_segment; +/* 0x34 */ uint32_t s_r_segments_percentage; +/* 0x38 */ uint64_t s_last_cno; +/* 0x40 */ uint64_t s_last_pseg; +/* 0x48 */ uint64_t s_last_seq; +/* 0x50 */ uint64_t s_free_blocks_count; +/* 0x58 */ uint64_t s_ctime; +/* 0x60 */ uint64_t s_mtime; +/* 0x68 */ uint64_t s_wtime; +/* 0x70 */ uint16_t s_mnt_count; +/* 0x72 */ uint16_t s_max_mnt_count; +/* 0x74 */ uint16_t s_state; +/* 0x76 */ uint16_t s_errors; +/* 0x78 */ uint64_t s_lastcheck; +/* 0x80 */ uint32_t s_checkinterval; +/* 0x84 */ uint32_t s_creator_os; +/* 0x88 */ uint16_t s_def_resuid; +/* 0x8A */ uint16_t s_def_resgid; +/* 0x8C */ uint32_t s_first_ino; +/* 0x90 */ uint16_t s_inode_size; +/* 0x92 */ uint16_t s_dat_entry_size; +/* 0x94 */ uint16_t s_checkpoint_size; +/* 0x96 */ uint16_t s_segment_usage_size; +/* 0x98 */ uint8_t s_uuid[NILFS_UUID_SIZE]; // 128-bit UUID for volume. +/* 0xA8 */ uint8_t s_volume_name[NILFS_LABEL_SIZE]; // Volume label. +/* 0xF8 */ // ... +} PACKED; + +int FAST_FUNC volume_id_probe_nilfs(struct volume_id *id /*,uint64_t off*/) +{ + struct nilfs2_super_block *sb; + + // Primary super block + dbg("nilfs: probing at offset 0x%x", NILFS_SB1_OFFSET); + + sb = volume_id_get_buffer(id, NILFS_SB1_OFFSET, sizeof(*sb)); + + if (sb == NULL) + return -1; + + if (sb->s_magic != NILFS_MAGIC) + return -1; + + // The secondary superblock is not always used, so ignore it for now. + // When used it is at 4K from the end of the partition (sb->s_dev_size - NILFS_SB2_OFFSET). + + volume_id_set_label_string(id, sb->s_volume_name, NILFS_LABEL_SIZE < VOLUME_ID_LABEL_SIZE ? + NILFS_LABEL_SIZE : VOLUME_ID_LABEL_SIZE); + volume_id_set_uuid(id, sb->s_uuid, UUID_DCE); + + if (sb->s_rev_level == 2) + IF_FEATURE_BLKID_TYPE(id->type = "nilfs2"); + + return 0; +} diff --git a/release/src/router/busybox/util-linux/volume_id/ntfs.c b/release/src/router/busybox/util-linux/volume_id/ntfs.c index 547f141c9c..0444e546b2 100644 --- a/release/src/router/busybox/util-linux/volume_id/ntfs.c +++ b/release/src/router/busybox/util-linux/volume_id/ntfs.c @@ -132,7 +132,7 @@ int FAST_FUNC volume_id_probe_ntfs(struct volume_id *id /*,uint64_t off*/) dbg("mft record size %i", mft_record_size); buf = volume_id_get_buffer(id, off + mft_off + (MFT_RECORD_VOLUME * mft_record_size), - mft_record_size); + mft_record_size); if (buf == NULL) goto found; @@ -150,7 +150,7 @@ int FAST_FUNC volume_id_probe_ntfs(struct volume_id *id /*,uint64_t off*/) attr = (struct file_attribute*) &buf[attr_off]; attr_type = le32_to_cpu(attr->type); - attr_len = le16_to_cpu(attr->len); + attr_len = le32_to_cpu(attr->len); val_off = le16_to_cpu(attr->value_offset); val_len = le32_to_cpu(attr->value_len); attr_off += attr_len; @@ -165,7 +165,7 @@ int FAST_FUNC volume_id_probe_ntfs(struct volume_id *id /*,uint64_t off*/) break; dbg("found attribute type 0x%x, len %i, at offset %i", - attr_type, attr_len, attr_off); + attr_type, attr_len, attr_off); // if (attr_type == MFT_RECORD_ATTR_VOLUME_INFO) { // struct volume_info *info; diff --git a/release/src/router/busybox/util-linux/volume_id/squashfs.c b/release/src/router/busybox/util-linux/volume_id/squashfs.c new file mode 100644 index 0000000000..c5b4f9cedb --- /dev/null +++ b/release/src/router/busybox/util-linux/volume_id/squashfs.c @@ -0,0 +1,49 @@ +/* + * volume_id - reads filesystem label and uuid + * + * Copyright (C) 2012 S-G Bergh + * + * Licensed under GPLv2, see file LICENSE in this source tree. + */ + +//kbuild:lib-$(CONFIG_FEATURE_VOLUMEID_SQUASHFS) += squashfs.o + +#include "volume_id_internal.h" + +struct squashfs_superblock { + uint32_t magic; +/* + uint32_t dummy[6]; + uint16_t major; + uint16_t minor; +*/ +} PACKED; + +int FAST_FUNC volume_id_probe_squashfs(struct volume_id *id /*,uint64_t off*/) +{ +#define off ((uint64_t)0) + struct squashfs_superblock *sb; + + dbg("SquashFS: probing at offset 0x%llx", (unsigned long long) off); + sb = volume_id_get_buffer(id, off, 0x200); + if (!sb) + return -1; + + // Old SquashFS (pre 4.0) can be both big and little endian, so test for both. + // Likewise, it is commonly used in firwmare with some non-standard signatures. +#define pack(a,b,c,d) ( (uint32_t)((a * 256 + b) * 256 + c) * 256 + d ) +#define SIG1 pack('s','q','s','h') +#define SIG2 pack('h','s','q','s') +#define SIG3 pack('s','h','s','q') +#define SIG4 pack('q','s','h','s') + if (sb->magic == SIG1 + || sb->magic == SIG2 + || sb->magic == SIG3 + || sb->magic == SIG4 + ) { + IF_FEATURE_BLKID_TYPE(id->type = "squashfs";) + return 0; + } + + return -1; +} diff --git a/release/src/router/busybox/util-linux/volume_id/udf.c b/release/src/router/busybox/util-linux/volume_id/udf.c index cd63c8d8a7..d3747fb8ec 100644 --- a/release/src/router/busybox/util-linux/volume_id/udf.c +++ b/release/src/router/busybox/util-linux/volume_id/udf.c @@ -109,7 +109,7 @@ nsr: return -1; dbg("vsd: %c%c%c%c%c", - vsd->id[0], vsd->id[1], vsd->id[2], vsd->id[3], vsd->id[4]); + vsd->id[0], vsd->id[1], vsd->id[2], vsd->id[3], vsd->id[4]); if (vsd->id[0] == '\0') return -1; diff --git a/release/src/router/busybox/util-linux/volume_id/unused_msdos.c b/release/src/router/busybox/util-linux/volume_id/unused_msdos.c index 65fb885017..2e8cb196a8 100644 --- a/release/src/router/busybox/util-linux/volume_id/unused_msdos.c +++ b/release/src/router/busybox/util-linux/volume_id/unused_msdos.c @@ -109,7 +109,7 @@ int FAST_FUNC volume_id_probe_msdos_part_table(struct volume_id *id, uint64_t of extended = off + poff; } else { dbg("found 0x%x data partition at 0x%llx, len 0x%llx", - part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen); + part[i].sys_ind, (unsigned long long) poff, (unsigned long long) plen); // if (is_raid(part[i].sys_ind)) // volume_id_set_usage_part(p, VOLUME_ID_RAID); diff --git a/release/src/router/busybox/util-linux/volume_id/unused_silicon_raid.c b/release/src/router/busybox/util-linux/volume_id/unused_silicon_raid.c index d1c439ecfe..878b88197b 100644 --- a/release/src/router/busybox/util-linux/volume_id/unused_silicon_raid.c +++ b/release/src/router/busybox/util-linux/volume_id/unused_silicon_raid.c @@ -62,7 +62,7 @@ int FAST_FUNC volume_id_probe_silicon_medley_raid(struct volume_id *id, uint64_t // volume_id_set_usage(id, VOLUME_ID_RAID); // snprintf(id->type_version, sizeof(id->type_version)-1, "%u.%u", -// le16_to_cpu(sil->major_ver), le16_to_cpu(sil->minor_ver)); +// le16_to_cpu(sil->major_ver), le16_to_cpu(sil->minor_ver)); // id->type = "silicon_medley_raid_member"; return 0; diff --git a/release/src/router/busybox/util-linux/volume_id/util.c b/release/src/router/busybox/util-linux/volume_id/util.c index 5bb897cfca..1a68436ca2 100644 --- a/release/src/router/busybox/util-linux/volume_id/util.c +++ b/release/src/router/busybox/util-linux/volume_id/util.c @@ -32,25 +32,29 @@ void volume_id_set_unicode16(char *str, size_t len, const uint8_t *buf, enum end c = (buf[i+1] << 8) | buf[i]; else c = (buf[i] << 8) | buf[i+1]; - if (c == 0) { - str[j] = '\0'; + if (c == 0) break; - } else if (c < 0x80) { - if (j+1 >= len) - break; - str[j++] = (uint8_t) c; - } else if (c < 0x800) { - if (j+2 >= len) - break; - str[j++] = (uint8_t) (0xc0 | (c >> 6)); - str[j++] = (uint8_t) (0x80 | (c & 0x3f)); + if (j+1 >= len) + break; + if (c < 0x80) { + /* 0xxxxxxx */ } else { - if (j+3 >= len) + uint8_t topbits = 0xc0; + if (j+2 >= len) break; - str[j++] = (uint8_t) (0xe0 | (c >> 12)); - str[j++] = (uint8_t) (0x80 | ((c >> 6) & 0x3f)); - str[j++] = (uint8_t) (0x80 | (c & 0x3f)); + if (c < 0x800) { + /* 110yyyxx 10xxxxxx */ + } else { + if (j+3 >= len) + break; + /* 1110yyyy 10yyyyxx 10xxxxxx */ + str[j++] = (uint8_t) (0xe0 | (c >> 12)); + topbits = 0x80; + } + str[j++] = (uint8_t) (topbits | ((c >> 6) & 0x3f)); + c = 0x80 | (c & 0x3f); } + str[j++] = (uint8_t) c; } str[j] = '\0'; } @@ -131,30 +135,14 @@ void volume_id_set_label_string(struct volume_id *id, const uint8_t *buf, size_t void volume_id_set_label_unicode16(struct volume_id *id, const uint8_t *buf, enum endian endianess, size_t count) { - volume_id_set_unicode16(id->label, sizeof(id->label), buf, endianess, count); + volume_id_set_unicode16(id->label, sizeof(id->label), buf, endianess, count); } void volume_id_set_uuid(struct volume_id *id, const uint8_t *buf, enum uuid_format format) { unsigned i; - unsigned count = 0; + unsigned count = (format == UUID_DCE_STRING ? VOLUME_ID_UUID_SIZE : 4 << format); - switch (format) { - case UUID_DOS: - count = 4; - break; - case UUID_NTFS: - case UUID_HFS: - count = 8; - break; - case UUID_DCE: - count = 16; - break; - case UUID_DCE_STRING: - /* 36 is ok, id->uuid has one extra byte for NUL */ - count = VOLUME_ID_UUID_SIZE; - break; - } // memcpy(id->uuid_raw, buf, count); // id->uuid_raw_len = count; @@ -175,11 +163,6 @@ set: buf[7], buf[6], buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]); break; - case UUID_HFS: - sprintf(id->uuid, "%02X%02X%02X%02X%02X%02X%02X%02X", - buf[0], buf[1], buf[2], buf[3], - buf[4], buf[5], buf[6], buf[7]); - break; case UUID_DCE: sprintf(id->uuid, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x", diff --git a/release/src/router/busybox/util-linux/volume_id/volume_id.c b/release/src/router/busybox/util-linux/volume_id/volume_id.c index 7c936a81db..f0fc84c05b 100644 --- a/release/src/router/busybox/util-linux/volume_id/volume_id.c +++ b/release/src/router/busybox/util-linux/volume_id/volume_id.c @@ -99,6 +99,9 @@ static const probe_fptr fs1[] = { #if ENABLE_FEATURE_VOLUMEID_MAC volume_id_probe_mac_partition_map, #endif +#if ENABLE_FEATURE_VOLUMEID_SQUASHFS + volume_id_probe_squashfs, +#endif #if ENABLE_FEATURE_VOLUMEID_XFS volume_id_probe_xfs, #endif @@ -133,6 +136,9 @@ static const probe_fptr fs2[] = { #if ENABLE_FEATURE_VOLUMEID_UFS volume_id_probe_ufs, #endif +#if ENABLE_FEATURE_VOLUMEID_NILFS + volume_id_probe_nilfs, +#endif #if ENABLE_FEATURE_VOLUMEID_NTFS volume_id_probe_ntfs, #endif diff --git a/release/src/router/busybox/util-linux/volume_id/volume_id_internal.h b/release/src/router/busybox/util-linux/volume_id/volume_id_internal.h index b38b3ea333..3f02bd50d7 100644 --- a/release/src/router/busybox/util-linux/volume_id/volume_id_internal.h +++ b/release/src/router/busybox/util-linux/volume_id/volume_id_internal.h @@ -136,12 +136,15 @@ void FAST_FUNC free_volume_id(struct volume_id *id); #define cpu_to_be32(x) (x) #endif +/* volume_id_set_uuid(id,buf,fmt) assumes size of uuid buf + * by shifting: 4 << fmt, except for fmt == UUID_DCE_STRING. + * The constants below should match sizes. + */ enum uuid_format { - UUID_DCE_STRING, - UUID_DCE, - UUID_DOS, - UUID_NTFS, - UUID_HFS, + UUID_DOS = 0, /* 4 bytes */ + UUID_NTFS = 1, /* 8 bytes */ + UUID_DCE = 2, /* 16 bytes */ + UUID_DCE_STRING = 3, /* 36 bytes (VOLUME_ID_UUID_SIZE) */ }; enum endian { @@ -212,6 +215,8 @@ int FAST_FUNC volume_id_probe_luks(struct volume_id *id /*,uint64_t off*/); //int FAST_FUNC volume_id_probe_msdos_part_table(struct volume_id *id /*,uint64_t off*/); +int FAST_FUNC volume_id_probe_nilfs(struct volume_id *id /*,uint64_t off*/); + int FAST_FUNC volume_id_probe_ntfs(struct volume_id *id /*,uint64_t off*/); int FAST_FUNC volume_id_probe_exfat(struct volume_id *id /*,uint64_t off*/); @@ -222,6 +227,8 @@ int FAST_FUNC volume_id_probe_reiserfs(struct volume_id *id /*,uint64_t off*/); int FAST_FUNC volume_id_probe_romfs(struct volume_id *id /*,uint64_t off*/); +int FAST_FUNC volume_id_probe_squashfs(struct volume_id *id /*,uint64_t off*/); + int FAST_FUNC volume_id_probe_sysv(struct volume_id *id /*,uint64_t off*/); int FAST_FUNC volume_id_probe_udf(struct volume_id *id /*,uint64_t off*/); -- 2.11.4.GIT