瀏覽代碼

update busybox to 2.23.0

add upstream patches.
Fix the busybox disable mechanism. When you choose less or
lsusb full blown version, be sure busybox applet is disabled.
Waldemar Brodkorb 9 年之前
父節點
當前提交
86098e08d8

+ 12 - 12
package/busybox/Makefile

@@ -4,9 +4,9 @@
 include $(ADK_TOPDIR)/rules.mk
 
 PKG_NAME:=		busybox
-PKG_VERSION:=		1.22.1
-PKG_RELEASE:=		2
-PKG_HASH:=		ae0b029d0a9e4dd71a077a790840e496dd838998e4571b87b60fed7462b6678b
+PKG_VERSION:=		1.23.0
+PKG_RELEASE:=		1
+PKG_HASH:=		483ab594dd962ddbb332fd24e36ffdd6e36ac2182fbff055c56e1ca49fda09e4
 PKG_DESCR:=		core utilities for embedded systems
 PKG_SECTION:=		base/apps
 PKG_BUILDDEP:=		bzip2-host
@@ -32,20 +32,20 @@ BB_MAKE_FLAGS:=		V=1 \
 
 do-configure:
 	# get all symbols from top level config
-	grep BUSYBOX_ $(ADK_TOPDIR)/.config|sed -e 's/BUSYBOX_/CONFIG_/' > \
+	grep "^BUSYBOX_\|# BUSYBOX" $(ADK_TOPDIR)/.config|grep -v BUSYBOX_DISABLE|sed -e 's/BUSYBOX_/CONFIG_/' > \
 		${WRKBUILD}/.config
-	# remove all disabled symbols
-	for i in $$(grep "BUSYBOX_DISABLE" $(ADK_TOPDIR)/.config);do \
-		test -s "$$i" || continue; \
-		grep -v $${i#BUSYBOX_DISABLE} ${WRKBUILD}/.config > \
-		${WRKBUILD}/.config.tmp; \
-		cp ${WRKBUILD}/.config.tmp ${WRKBUILD}/.config; \
+	cp ${WRKBUILD}/.config ${WRKBUILD}/.config.step1
+	# convert all disabled symbols
+	for i in $$(grep ^BUSYBOX_DISABLE $(ADK_TOPDIR)/.config);do \
+		echo "$$i"; \
+		sym=$${i#BUSYBOX_DISABLE_}; \
+		symbol=$$(echo $$sym|sed -e "s#=y##"); \
+		printf "# CONFIG_$${symbol} is not set\n" >> ${WRKBUILD}/.config; \
 	done
 ifeq ($(ADK_TARGET_UCLINUX),y)
-	echo 'BUSYBOX_NOMMU=y' >> ${WRKBUILD}/.config
+	echo 'CONFIG_NOMMU=y' >> ${WRKBUILD}/.config
 endif
 	$(SED) 's;@IDIR@;${WRKINST};' ${WRKBUILD}/.config
-	yes '' | PATH='$(HOST_PATH)' $(MAKE) ${BB_MAKE_FLAGS} -C ${WRKBUILD} oldconfig $(MAKE_TRACE)
 
 do-build:
 	PATH='$(HOST_PATH)' $(MAKE) ${BB_MAKE_FLAGS} -C ${WRKBUILD} busybox

+ 46 - 0
package/busybox/config/Config.in

@@ -47,6 +47,14 @@ config BUSYBOX_USE_PORTABLE_CODE
 	  compiler other than gcc.
 	  If you do use gcc, this option may needlessly increase code size.
 
+config BUSYBOX_INSTALL_NO_USR
+        bool "Don't use /usr"
+        default n
+        help
+          Disable use of /usr. busybox --install and "make install"
+          will install applets only to /bin and /sbin,
+          never to /usr/bin or /usr/sbin.
+
 config BUSYBOX_PLATFORM_LINUX
 	bool "Enable Linux-specific applets and features"
 	default y
@@ -248,6 +256,26 @@ config BUSYBOX_UNICODE_PRESERVE_BROKEN
 	  at shell prompt will list file named 0xff (single char name
 	  with char value 255), not file named '?'.
 
+config BUSYBOX_PAM
+	bool "Support for PAM (Pluggable Authentication Modules)"
+	default n
+	help
+	  Use PAM in some busybox applets (currently login and httpd) instead
+	  of direct access to password database.
+
+config BUSYBOX_FEATURE_USE_SENDFILE
+	bool "Use sendfile system call"
+	default y
+	select PLATFORM_LINUX
+	help
+	  When enabled, busybox will use the kernel sendfile() function
+	  instead of read/write loops to copy data between file descriptors
+	  (for example, cp command does this a lot).
+	  If sendfile() doesn't work, copying code falls back to read/write
+	  loop. sendfile() was originally implemented for faster I/O
+	  from files to sockets, but since Linux 2.6.33 it was extended
+	  to work for many more file types.
+
 config BUSYBOX_LONG_OPTS
 	bool "Support for --long-options"
 	default y
@@ -304,6 +332,16 @@ config BUSYBOX_FEATURE_PIDFILE
 	  This option makes some applets (e.g. crond, syslogd, inetd) write
 	  a pidfile in /var/run. Some applications rely on them.
 
+config BUSYBOX_PID_FILE_PATH
+        string "Path to directory for pidfile"
+        default "/var/run"
+        depends on BUSYBOX_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 BUSYBOX_FEATURE_SUID
 	bool "Support for SUID/SGID handling"
 	default y
@@ -653,6 +691,14 @@ config BUSYBOX_DEBUG_PESSIMIZE
 	  in a much bigger executable that more closely matches the source
 	  code.
 
+config BUSYBOX_UNIT_TEST
+	bool "Build unit tests"
+	default n
+	help
+	  Say Y here if you want to build unit tests (both the framework and
+	  test cases) as a Busybox applet. This results in bigger code, so you
+	  probably don't want this option in production builds.
+
 config BUSYBOX_WERROR
 	bool "Abort compilation on any warning"
 	default n

+ 32 - 0
package/busybox/config/coreutils/Config.in

@@ -79,6 +79,13 @@ config BUSYBOX_GROUPS
 	default y
 	help
 	  Print the group names associated with current user id.
+
+config BUSYBOX_SHUF
+	bool "shuf"
+	default n
+	help
+	  Generate random permutations
+
 config BUSYBOX_TEST
 	bool "test"
 	default y
@@ -93,6 +100,7 @@ config BUSYBOX_FEATURE_TEST_64
 	depends on BUSYBOX_TEST || BUSYBOX_ASH_BUILTIN_TEST || BUSYBOX_HUSH
 	help
 	  Enable 64-bit support in test.
+
 config BUSYBOX_TOUCH
 	bool "touch"
 	default y
@@ -100,6 +108,14 @@ config BUSYBOX_TOUCH
 	  touch is used to create or change the access and/or
 	  modification timestamp of specified files.
 
+config BUSYBOX_FEATURE_TOUCH_NODEREF
+	bool "Add support for -h"
+	default y
+	depends on BUSYBOX_TOUCH
+	help
+	  Enable touch to have the -h option.
+	  This requires libc support for lutimes() function.
+
 config BUSYBOX_FEATURE_TOUCH_SUSV3
 	bool "Add support for SUSV3 features (-d -t -r)"
 	default y
@@ -132,6 +148,12 @@ config BUSYBOX_FEATURE_TR_EQUIV
 	  useful for cases when no other way of expressing a character
 	  is possible.
 
+config BUSYBOX_UNLINK
+	bool "unlink"
+	default y
+	help
+	  unlink deletes a file by calling unlink()
+
 config BUSYBOX_BASE64
 	bool "base64"
 	default y
@@ -883,6 +905,16 @@ config BUSYBOX_YES
 	  yes is used to repeatedly output a specific string, or
 	  the default string `y'.
 
+comment "Common options"
+
+config BUSYBOX_FEATURE_VERBOSE
+	bool "Support verbose options (usually -v) for various applets"
+	default y
+	help
+	  Enable cp -v, rm -v and similar messages.
+	  Also enables long option (--verbose) if it exists.
+	  Without this option, -v is accepted but ignored.
+
 comment "Common options for cp and mv"
 	depends on BUSYBOX_CP || BUSYBOX_MV
 

+ 44 - 0
package/busybox/config/editors/Config.in

@@ -129,6 +129,39 @@ config BUSYBOX_FEATURE_VI_ASK_TERMINAL
 
 	  This is not clean but helps a lot on serial lines and such.
 
+config BUSYBOX_FEATURE_VI_UNDO
+	bool "Support undo command 'u'"
+	default y
+	depends on BUSYBOX_VI
+	help
+	  Support the 'u' command to undo insertion, deletion, and replacement
+	  of text.
+
+config BUSYBOX_FEATURE_VI_UNDO_QUEUE
+	bool "Enable undo operation queuing"
+	default y
+	depends on BUSYBOX_FEATURE_VI_UNDO
+	help
+	  The vi undo functions can use an intermediate queue to greatly lower
+	  malloc() calls and overhead. When the maximum size of this queue is
+	  reached, the contents of the queue are committed to the undo stack.
+	  This increases the size of the undo code and allows some undo
+	  operations (especially un-typing/backspacing) to be far more useful.
+
+config BUSYBOX_FEATURE_VI_UNDO_QUEUE_MAX
+	int "Maximum undo character queue size"
+	default 256
+	range 32 65536
+	depends on BUSYBOX_FEATURE_VI_UNDO_QUEUE
+	help
+	  This option sets the number of bytes used at runtime for the queue.
+	  Smaller values will create more undo objects and reduce the amount
+	  of typed or backspaced characters that are grouped into one undo
+	  operation; larger values increase the potential size of each undo
+	  and will generally malloc() larger objects and less frequently.
+	  Unless you want more (or less) frequent "undo points" while typing,
+	  you should probably leave this unchanged.
+
 config BUSYBOX_AWK
 	bool "awk"
 	default y
@@ -144,6 +177,17 @@ config BUSYBOX_FEATURE_AWK_LIBM
 	  Enable math functions of the Awk programming language.
 	  NOTE: This will require libm to be present for linking.
 
+config BUSYBOX_FEATURE_AWK_GNU_EXTENSIONS
+	bool "Enable a few GNU extensions"
+	default y
+	depends on BUSYBOX_AWK
+	help
+	  Enable a few features from gawk:
+	  * command line option -e AWK_PROGRAM
+	  * simultaneous use of -f and -e on the command line.
+	    This enables the use of awk library files.
+	    Ex: awk -f mylib.awk -e '{print myfunction($1);}' ...
+
 config BUSYBOX_CMP
 	bool "cmp"
 	default y

+ 18 - 0
package/busybox/config/findutils/Config.in

@@ -99,6 +99,16 @@ config BUSYBOX_FEATURE_FIND_EXEC
 	  Support the 'find -exec' option for executing commands based upon
 	  the files matched.
 
+config BUSYBOX_FEATURE_FIND_EXEC_PLUS
+	bool "Enable -exec ... {} +"
+	default y
+	depends on BUSYBOX_FEATURE_FIND_EXEC
+	help
+	  Support the 'find -exec ... {} +' option for executing commands
+	  for all matched files at once.
+	  Without this option, -exec + is a synonym for -exec ;
+	  (IOW: it works correctly, but without expected speedup)
+
 config BUSYBOX_FEATURE_FIND_USER
 	bool "Enable -user: username/uid matching"
 	default y
@@ -221,6 +231,7 @@ config BUSYBOX_FEATURE_GREP_CONTEXT
 	  Print the specified number of leading (-B) and/or trailing (-A)
 	  context surrounding our matching lines.
 	  Print the specified number of context lines (-C).
+
 config BUSYBOX_XARGS
 	bool "xargs"
 	default y
@@ -260,4 +271,11 @@ config BUSYBOX_FEATURE_XARGS_SUPPORT_ZERO_TERM
 	  instead of whitespace, and the quotes and backslash
 	  are not special.
 
+config BUSYBOX_FEATURE_XARGS_SUPPORT_REPL_STR
+	bool "Enable -I STR: string to replace"
+	default y
+	depends on BUSYBOX_XARGS
+	help
+	  Support -I STR and -i[STR] options.
+
 endmenu

+ 7 - 0
package/busybox/config/loginutils/Config.in

@@ -129,6 +129,13 @@ config BUSYBOX_FEATURE_CHECK_NAMES
 	  For compatibility with Samba machine accounts "$" is also supported
 	  at the end of the user or group name.
 
+config BUSYBOX_LAST_ID
+	int "Last valid uid or gid for adduser and addgroup"
+	depends on BUSYBOX_ADDUSER || BUSYBOX_ADDGROUP
+	default 60000
+	help
+	  Last valid uid or gid for adduser and addgroup
+
 config BUSYBOX_FIRST_SYSTEM_ID
 	int "First valid system uid or gid for adduser and addgroup"
 	depends on BUSYBOX_ADDUSER || BUSYBOX_ADDGROUP

+ 8 - 0
package/busybox/config/networking/Config.in

@@ -767,6 +767,14 @@ config BUSYBOX_FEATURE_NTPD_SERVER
 	  Make ntpd usable as a NTP server. If you disable this option
 	  ntpd will be usable only as a NTP client.
 
+config BUSYBOX_FEATURE_NTPD_CONF
+	bool "Make ntpd understand /etc/ntp.conf"
+	default n
+	depends on BUSYBOX_NTPD
+	help
+	  Make ntpd look in /etc/ntp.conf for peers. Only "server address"
+	  is supported.
+
 config BUSYBOX_PSCAN
 	bool "pscan"
 	default n

+ 11 - 0
package/busybox/config/networking/udhcp/Config.in

@@ -89,6 +89,17 @@ config BUSYBOX_FEATURE_UDHCPC_ARPING
 	  will DHCPDECLINE the offer if the address is in use,
 	  and restart the discover process.
 
+config BUSYBOX_FEATURE_UDHCPC_SANITIZEOPT
+	bool "Do not pass malformed host and domain names"
+	default y
+	depends on BUSYBOX_UDHCPC
+	help
+	  If selected, udhcpc will check some options (such as option 12 -
+	  hostname) and if they don't look like valid hostnames
+	  (for example, if they start with dash or contain spaces),
+	  they will be replaced with string "bad" when exporting
+	  to the environment.
+
 config BUSYBOX_FEATURE_UDHCP_PORT
 	bool "Enable '-P port' option for udhcpd and udhcpc"
 	default n

+ 45 - 9
package/busybox/config/util-linux/Config.in

@@ -12,6 +12,20 @@ config BUSYBOX_BLOCKDEV
 	help
 	  Performs some ioctls with block devices.
 
+config BUSYBOX_FATATTR
+	bool "fatattr"
+	default n
+	select PLATFORM_LINUX
+	help
+	  fatattr lists or changes the file attributes on a fat file system.
+
+config BUSYBOX_FSTRIM
+	bool "fstrim"
+	default n
+	select PLATFORM_LINUX
+	help
+	  Discard unused blocks on a mounted filesystem.
+
 config BUSYBOX_MDEV
 	bool "mdev"
 	default y
@@ -153,7 +167,6 @@ config BUSYBOX_FEATURE_DMESG_PRETTY
 config BUSYBOX_FBSET
 	bool "fbset"
 	depends on !BUSYBOX_DISABLE_FBSET
-	default y if ADK_TARGET_WITH_VGA
 	default n
 	select BUSYBOX_PLATFORM_LINUX
 	help
@@ -317,6 +330,13 @@ config BUSYBOX_FSCK_MINIX
 	  check for and attempt to repair any corruption that occurs to a minix
 	  filesystem.
 
+config BUSYBOX_MKFS_EXT2
+	bool "mkfs_ext2"
+	default n
+	select PLATFORM_LINUX
+	help
+	  Utility to create EXT2 filesystems.
+
 config BUSYBOX_MKFS_MINIX
 	bool "mkfs_minix"
 	default n
@@ -345,7 +365,6 @@ config BUSYBOX_MKFS_REISER
 
 config BUSYBOX_MKFS_VFAT
 	bool "mkfs_vfat"
-	default y if ADK_TARGET_WITH_MMC
 	default n
 	select BUSYBOX_PLATFORM_LINUX
 	help
@@ -427,7 +446,7 @@ config BUSYBOX_FEATURE_HWCLOCK_ADJTIME_FHS
 
 config BUSYBOX_IPCRM
 	bool "ipcrm"
-	default y
+	default n
 	help
 	  The ipcrm utility allows the removal of System V interprocess
 	  communication (IPC) objects and the associated data structures
@@ -435,7 +454,7 @@ config BUSYBOX_IPCRM
 
 config BUSYBOX_IPCS
 	bool "ipcs"
-	default y
+	default n
 	select BUSYBOX_PLATFORM_LINUX
 	help
 	  The ipcs utility is used to provide information on the currently
@@ -453,8 +472,6 @@ config BUSYBOX_LOSETUP
 config BUSYBOX_LSPCI
 	bool "lspci"
 	depends on !BUSYBOX_DISABLE_LSPCI
-	default y if ADK_TARGET_WITH_PCI
-	default y if ADK_TARGET_WITH_MINIPCI
 	default n
 	#select PLATFORM_LINUX
 	help
@@ -466,7 +483,6 @@ config BUSYBOX_LSPCI
 config BUSYBOX_LSUSB
 	bool "lsusb"
 	depends on !BUSYBOX_DISABLE_LSUSB
-	default y if ADK_TARGET_WITH_USB
 	default n
 	#select PLATFORM_LINUX
 	help
@@ -477,7 +493,7 @@ config BUSYBOX_LSUSB
 
 config BUSYBOX_MKSWAP
 	bool "mkswap"
-	default y
+	default n
 	help
 	  The mkswap utility is used to configure a file or disk partition as
 	  Linux swap space. This allows Linux to use the entire file or
@@ -609,6 +625,7 @@ config BUSYBOX_PIVOT_ROOT
 
 config BUSYBOX_RDATE
 	bool "rdate"
+	depends on !BUSYBOX_DISABLE_RDATE
 	default n
 	help
 	  The rdate utility allows you to synchronize the date and time of your
@@ -661,7 +678,7 @@ config BUSYBOX_SETARCH
 
 config BUSYBOX_SWAPONOFF
 	bool "swaponoff"
-	default y
+	default n
 	select BUSYBOX_PLATFORM_LINUX
 	help
 	  This option enables both the 'swapon' and the 'swapoff' utilities.
@@ -671,6 +688,15 @@ config BUSYBOX_SWAPONOFF
 	  space. If you are not using any swap space, you can leave this
 	  option disabled.
 
+config BUSYBOX_FEATURE_SWAPON_DISCARD
+	bool "Support discard option -d"
+	default n
+	depends on BUSYBOX_SWAPONOFF
+	help
+	  Enable support for discarding swap area blocks at swapon and/or as
+	  the kernel frees them. This option enables both the -d option on
+	  'swapon' and the 'discard' option for swap entries in /etc/fstab.
+
 config BUSYBOX_FEATURE_SWAPON_PRI
 	bool "Support priority option -p"
 	default y
@@ -800,6 +826,16 @@ config BUSYBOX_FEATURE_VOLUMEID_REISERFS
 	help
 	  TODO
 
+config BUSYBOX_FEATURE_VOLUMEID_F2FS
+	bool "f2fs filesystem"
+	default y
+	depends on BUSYBOX_VOLUMEID
+	help
+	  F2FS (aka Flash-Friendly File System) is a log-structured file system,
+	  which is adapted to newer forms of storage. F2FS also remedies some
+	  known issues of the older log structured file systems, such as high
+	  cleaning overhead.
+
 config BUSYBOX_FEATURE_VOLUMEID_FAT
 	bool "fat filesystem"
 	default y

文件差異過大導致無法顯示
+ 353 - 597
package/busybox/patches/001-ipkg.patch


+ 34 - 0
package/busybox/patches/004-busybox-1.23.0-ash.patch

@@ -0,0 +1,34 @@
+--- busybox-1.23.0/shell/ash.c
++++ busybox-1.23.0-ash/shell/ash.c
+@@ -6746,6 +6746,14 @@ varvalue(char *name, int varflags, int f
+ 		len = strlen(p);
+ 		if (!(subtype == VSPLUS || subtype == VSLENGTH))
+ 			memtodest(p, len, syntax, quotes);
++#if ENABLE_UNICODE_SUPPORT
++		if (subtype == VSLENGTH && len > 0) {
++			reinit_unicode_for_ash();
++			if (unicode_status == UNICODE_ON) {
++				len = unicode_strlen(p);
++			}
++		}
++#endif
+ 		return len;
+ 	}
+ 
+@@ -6829,15 +6837,7 @@ evalvar(char *p, int flags, struct strli
+ 		varunset(p, var, 0, 0);
+ 
+ 	if (subtype == VSLENGTH) {
+-		ssize_t n = varlen;
+-		if (n > 0) {
+-			reinit_unicode_for_ash();
+-			if (unicode_status == UNICODE_ON) {
+-				const char *val = lookupvar(var);
+-				n = unicode_strlen(val);
+-			}
+-		}
+-		cvtnum(n > 0 ? n : 0);
++		cvtnum(varlen > 0 ? varlen : 0);
+ 		goto record;
+ 	}
+ 

+ 0 - 1135
package/busybox/patches/004-ping.patch

@@ -1,1135 +0,0 @@
-diff -Nur busybox-1.22.1.orig/networking/ping.c busybox-1.22.1/networking/ping.c
---- busybox-1.22.1.orig/networking/ping.c	2014-01-20 03:38:10.000000000 +0100
-+++ busybox-1.22.1/networking/ping.c	2014-05-24 14:31:09.000000000 +0200
-@@ -152,6 +152,7 @@
- 	pingsock = 0,
- };
- 
-+static int using_dgram;
- static void
- #if ENABLE_PING6
- create_icmp_socket(len_and_sockaddr *lsa)
-@@ -184,6 +185,7 @@
- 		if (sock < 0)
- #endif
- 		bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
-+		using_dgram = 1;
- 	}
- 
- 	xmove_fd(sock, pingsock);
-@@ -234,10 +236,12 @@
- 				bb_perror_msg("recvfrom");
- 			continue;
- 		}
--		if (c >= 76) {			/* ip + icmp */
--			struct iphdr *iphdr = (struct iphdr *) G.packet;
-+		if (c >= 76 || using_dgram && (c == 64)) {			/* ip + icmp */
-+			if(!using_dgram) {
-+				struct iphdr *iphdr = (struct iphdr *) G.packet;
- 
--			pkt = (struct icmp *) (G.packet + (iphdr->ihl << 2));	/* skip ip hdr */
-+				pkt = (struct icmp *) (G.packet + (iphdr->ihl << 2));	/* skip ip hdr */
-+			} else pkt = (struct icmp *) G.packet;
- 			if (pkt->icmp_type == ICMP_ECHOREPLY)
- 				break;
- 		}
-@@ -628,19 +632,21 @@
- }
- static void unpack4(char *buf, int sz, struct sockaddr_in *from)
- {
--	struct icmp *icmppkt;
- 	struct iphdr *iphdr;
-+	struct icmp *icmppkt;
- 	int hlen;
- 
- 	/* discard if too short */
- 	if (sz < (datalen + ICMP_MINLEN))
- 		return;
-+	if(!using_dgram) {
-+		/* check IP header */
-+		iphdr = (struct iphdr *) buf;
-+		hlen = iphdr->ihl << 2;
-+		sz -= hlen;
-+		icmppkt = (struct icmp *) (buf + hlen);
-+	} else icmppkt = (struct icmp *) buf;
- 
--	/* check IP header */
--	iphdr = (struct iphdr *) buf;
--	hlen = iphdr->ihl << 2;
--	sz -= hlen;
--	icmppkt = (struct icmp *) (buf + hlen);
- 	if (icmppkt->icmp_id != myid)
- 		return;				/* not our ping */
- 
-@@ -652,7 +658,7 @@
- 			tp = (uint32_t *) icmppkt->icmp_data;
- 		unpack_tail(sz, tp,
- 			inet_ntoa(*(struct in_addr *) &from->sin_addr.s_addr),
--			recv_seq, iphdr->ttl);
-+			recv_seq, using_dgram ? 42 : iphdr->ttl);
- 	} else if (icmppkt->icmp_type != ICMP_ECHO) {
- 		bb_error_msg("warning: got ICMP %d (%s)",
- 				icmppkt->icmp_type,
-@@ -696,11 +702,31 @@
- 	int sockopt;
- 
- 	pingaddr.sin = lsa->u.sin;
--	if (source_lsa) {
-+	if (source_lsa && !using_dgram) {
- 		if (setsockopt(pingsock, IPPROTO_IP, IP_MULTICAST_IF,
- 				&source_lsa->u.sa, source_lsa->len))
- 			bb_error_msg_and_die("can't set multicast source interface");
- 		xbind(pingsock, &source_lsa->u.sa, source_lsa->len);
-+	} else if(using_dgram) {
-+		struct sockaddr_in sa;
-+		socklen_t sl;
-+
-+		sa.sin_family = AF_INET;
-+		sa.sin_port = 0;
-+		sa.sin_addr.s_addr = source_lsa ?
-+			source_lsa->u.sin.sin_addr.s_addr : 0;
-+		sl = sizeof(sa);
-+
-+		if (bind(pingsock, (struct sockaddr *) &sa, sl) == -1) {
-+			perror("bind");
-+			exit(2);
-+		}
-+
-+		if (getsockname(pingsock, (struct sockaddr *) &sa, &sl) == -1) {
-+			perror("getsockname");
-+			exit(2);
-+		}
-+		myid = sa.sin_port;
- 	}
- 
- 	/* enable broadcast pings */
-@@ -717,6 +743,15 @@
- 		setsockopt(pingsock, IPPROTO_IP, IP_MULTICAST_TTL, &opt_ttl, sizeof(opt_ttl));
- 	}
- 
-+	if(using_dgram) {
-+		int hold = 65536;
-+		if (setsockopt(pingsock, SOL_IP, IP_RECVTTL, (char *)&hold, sizeof(hold)))
-+			perror("WARNING: setsockopt(IP_RECVTTL)");
-+		if (setsockopt(pingsock, SOL_IP, IP_RETOPTS, (char *)&hold, sizeof(hold)))
-+			perror("WARNING: setsockopt(IP_RETOPTS)");
-+
-+	}
-+
- 	signal(SIGINT, print_stats_and_exit);
- 
- 	/* start the ping's going ... */
-@@ -751,10 +786,33 @@
- 	char control_buf[CMSG_SPACE(36)];
- 
- 	pingaddr.sin6 = lsa->u.sin6;
--	if (source_lsa)
-+	if (source_lsa && !using_dgram)
- 		xbind(pingsock, &source_lsa->u.sa, source_lsa->len);
-+	else if(using_dgram) {
-+                struct sockaddr_in6 sa = {0};
-+                socklen_t sl;
-+
-+                sa.sin6_family = AF_INET6;
-+                sa.sin6_port = 0;
-+		if(source_lsa) {
-+			memcpy(&sa.sin6_addr, &source_lsa->u.sin6.sin6_addr, sizeof(struct in6_addr));
-+		}
-+                sl = sizeof(sa);
-+
-+                if (bind(pingsock, (struct sockaddr *) &sa, sl) == -1) {
-+                        perror("bind");
-+                        exit(2);
-+                }
-+
-+                if (getsockname(pingsock, (struct sockaddr *) &sa, &sl) == -1) {
-+                        perror("getsockname");
-+                        exit(2);
-+                }
-+                myid = sa.sin6_port;
-+	}
- 
- #ifdef ICMP6_FILTER
-+	if(!using_dgram)
- 	{
- 		struct icmp6_filter filt;
- 		if (!(option_mask32 & OPT_VERBOSE)) {
-@@ -880,7 +938,7 @@
- 			str_I = NULL; /* don't try to bind to device later */
- 		}
- 	}
--	myid = (uint16_t) getpid();
-+	if(!using_dgram) myid = (uint16_t) getpid();
- 	hostname = argv[optind];
- #if ENABLE_PING6
- 	{
-diff -Nur busybox-1.22.1.orig/networking/ping.c.orig busybox-1.22.1/networking/ping.c.orig
---- busybox-1.22.1.orig/networking/ping.c.orig	1970-01-01 01:00:00.000000000 +0100
-+++ busybox-1.22.1/networking/ping.c.orig	2014-01-20 03:38:10.000000000 +0100
-@@ -0,0 +1,966 @@
-+/* vi: set sw=4 ts=4: */
-+/*
-+ * Mini ping implementation for busybox
-+ *
-+ * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
-+ *
-+ * Adapted from the ping in netkit-base 0.10:
-+ * Copyright (c) 1989 The Regents of the University of California.
-+ * All rights reserved.
-+ *
-+ * This code is derived from software contributed to Berkeley by
-+ * Mike Muuss.
-+ *
-+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
-+ */
-+/* from ping6.c:
-+ * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
-+ *
-+ * This version of ping is adapted from the ping in netkit-base 0.10,
-+ * which is:
-+ *
-+ * Original copyright notice is retained at the end of this file.
-+ *
-+ * This version is an adaptation of ping.c from busybox.
-+ * The code was modified by Bart Visscher <magick@linux-fan.com>
-+ */
-+
-+#include <net/if.h>
-+#include <netinet/ip_icmp.h>
-+#include "libbb.h"
-+
-+#ifdef __BIONIC__
-+/* should be in netinet/ip_icmp.h */
-+# define ICMP_DEST_UNREACH    3  /* Destination Unreachable  */
-+# define ICMP_SOURCE_QUENCH   4  /* Source Quench    */
-+# define ICMP_REDIRECT        5  /* Redirect (change route)  */
-+# define ICMP_ECHO            8  /* Echo Request      */
-+# define ICMP_TIME_EXCEEDED  11  /* Time Exceeded    */
-+# define ICMP_PARAMETERPROB  12  /* Parameter Problem    */
-+# define ICMP_TIMESTAMP      13  /* Timestamp Request    */
-+# define ICMP_TIMESTAMPREPLY 14  /* Timestamp Reply    */
-+# define ICMP_INFO_REQUEST   15  /* Information Request    */
-+# define ICMP_INFO_REPLY     16  /* Information Reply    */
-+# define ICMP_ADDRESS        17  /* Address Mask Request    */
-+# define ICMP_ADDRESSREPLY   18  /* Address Mask Reply    */
-+#endif
-+
-+//config:config PING
-+//config:	bool "ping"
-+//config:	default y
-+//config:	select PLATFORM_LINUX
-+//config:	help
-+//config:	  ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to
-+//config:	  elicit an ICMP ECHO_RESPONSE from a host or gateway.
-+//config:
-+//config:config PING6
-+//config:	bool "ping6"
-+//config:	default y
-+//config:	depends on FEATURE_IPV6 && PING
-+//config:	help
-+//config:	  This will give you a ping that can talk IPv6.
-+//config:
-+//config:config FEATURE_FANCY_PING
-+//config:	bool "Enable fancy ping output"
-+//config:	default y
-+//config:	depends on PING
-+//config:	help
-+//config:	  Make the output from the ping applet include statistics, and at the
-+//config:	  same time provide full support for ICMP packets.
-+
-+/* Needs socket(AF_INET, SOCK_RAW, IPPROTO_ICMP), therefore BB_SUID_MAYBE: */
-+//applet:IF_PING(APPLET(ping, BB_DIR_BIN, BB_SUID_MAYBE))
-+//applet:IF_PING6(APPLET(ping6, BB_DIR_BIN, BB_SUID_MAYBE))
-+
-+//kbuild:lib-$(CONFIG_PING)  += ping.o
-+//kbuild:lib-$(CONFIG_PING6) += ping.o
-+
-+//usage:#if !ENABLE_FEATURE_FANCY_PING
-+//usage:# define ping_trivial_usage
-+//usage:       "HOST"
-+//usage:# define ping_full_usage "\n\n"
-+//usage:       "Send ICMP ECHO_REQUEST packets to network hosts"
-+//usage:# define ping6_trivial_usage
-+//usage:       "HOST"
-+//usage:# define ping6_full_usage "\n\n"
-+//usage:       "Send ICMP ECHO_REQUEST packets to network hosts"
-+//usage:#else
-+//usage:# define ping_trivial_usage
-+//usage:       "[OPTIONS] HOST"
-+//usage:# define ping_full_usage "\n\n"
-+//usage:       "Send ICMP ECHO_REQUEST packets to network hosts\n"
-+//usage:	IF_PING6(
-+//usage:     "\n	-4,-6		Force IP or IPv6 name resolution"
-+//usage:	)
-+//usage:     "\n	-c CNT		Send only CNT pings"
-+//usage:     "\n	-s SIZE		Send SIZE data bytes in packets (default:56)"
-+//usage:     "\n	-t TTL		Set TTL"
-+//usage:     "\n	-I IFACE/IP	Use interface or IP address as source"
-+//usage:     "\n	-W SEC		Seconds to wait for the first response (default:10)"
-+//usage:     "\n			(after all -c CNT packets are sent)"
-+//usage:     "\n	-w SEC		Seconds until ping exits (default:infinite)"
-+//usage:     "\n			(can exit earlier with -c CNT)"
-+//usage:     "\n	-q		Quiet, only displays output at start"
-+//usage:     "\n			and when finished"
-+//usage:
-+//usage:# define ping6_trivial_usage
-+//usage:       "[OPTIONS] HOST"
-+//usage:# define ping6_full_usage "\n\n"
-+//usage:       "Send ICMP ECHO_REQUEST packets to network hosts\n"
-+//usage:     "\n	-c CNT		Send only CNT pings"
-+//usage:     "\n	-s SIZE		Send SIZE data bytes in packets (default:56)"
-+//usage:     "\n	-I IFACE/IP	Use interface or IP address as source"
-+//usage:     "\n	-q		Quiet, only displays output at start"
-+//usage:     "\n			and when finished"
-+//usage:
-+//usage:#endif
-+//usage:
-+//usage:#define ping_example_usage
-+//usage:       "$ ping localhost\n"
-+//usage:       "PING slag (127.0.0.1): 56 data bytes\n"
-+//usage:       "64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=20.1 ms\n"
-+//usage:       "\n"
-+//usage:       "--- debian ping statistics ---\n"
-+//usage:       "1 packets transmitted, 1 packets received, 0% packet loss\n"
-+//usage:       "round-trip min/avg/max = 20.1/20.1/20.1 ms\n"
-+//usage:#define ping6_example_usage
-+//usage:       "$ ping6 ip6-localhost\n"
-+//usage:       "PING ip6-localhost (::1): 56 data bytes\n"
-+//usage:       "64 bytes from ::1: icmp6_seq=0 ttl=64 time=20.1 ms\n"
-+//usage:       "\n"
-+//usage:       "--- ip6-localhost ping statistics ---\n"
-+//usage:       "1 packets transmitted, 1 packets received, 0% packet loss\n"
-+//usage:       "round-trip min/avg/max = 20.1/20.1/20.1 ms\n"
-+
-+#if ENABLE_PING6
-+# include <netinet/icmp6.h>
-+/* I see RENUMBERED constants in bits/in.h - !!?
-+ * What a fuck is going on with libc? Is it a glibc joke? */
-+# ifdef IPV6_2292HOPLIMIT
-+#  undef IPV6_HOPLIMIT
-+#  define IPV6_HOPLIMIT IPV6_2292HOPLIMIT
-+# endif
-+#endif
-+
-+enum {
-+	DEFDATALEN = 56,
-+	MAXIPLEN = 60,
-+	MAXICMPLEN = 76,
-+	MAX_DUP_CHK = (8 * 128),
-+	MAXWAIT = 10,
-+	PINGINTERVAL = 1, /* 1 second */
-+	pingsock = 0,
-+};
-+
-+static void
-+#if ENABLE_PING6
-+create_icmp_socket(len_and_sockaddr *lsa)
-+#else
-+create_icmp_socket(void)
-+#define create_icmp_socket(lsa) create_icmp_socket()
-+#endif
-+{
-+	int sock;
-+#if ENABLE_PING6
-+	if (lsa->u.sa.sa_family == AF_INET6)
-+		sock = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
-+	else
-+#endif
-+		sock = socket(AF_INET, SOCK_RAW, 1); /* 1 == ICMP */
-+	if (sock < 0) {
-+		if (errno != EPERM)
-+			bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);
-+#if defined(__linux__) || defined(__APPLE__)
-+		/* We don't have root privileges.  Try SOCK_DGRAM instead.
-+		 * Linux needs net.ipv4.ping_group_range for this to work.
-+		 * MacOSX allows ICMP_ECHO, ICMP_TSTAMP or ICMP_MASKREQ
-+		 */
-+#if ENABLE_PING6
-+		if (lsa->u.sa.sa_family == AF_INET6)
-+			sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_ICMPV6);
-+		else
-+#endif
-+			sock = socket(AF_INET, SOCK_DGRAM, 1); /* 1 == ICMP */
-+		if (sock < 0)
-+#endif
-+		bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);
-+	}
-+
-+	xmove_fd(sock, pingsock);
-+}
-+
-+#if !ENABLE_FEATURE_FANCY_PING
-+
-+/* Simple version */
-+
-+struct globals {
-+	char *hostname;
-+	char packet[DEFDATALEN + MAXIPLEN + MAXICMPLEN];
-+} FIX_ALIASING;
-+#define G (*(struct globals*)&bb_common_bufsiz1)
-+#define INIT_G() do { } while (0)
-+
-+static void noresp(int ign UNUSED_PARAM)
-+{
-+	printf("No response from %s\n", G.hostname);
-+	exit(EXIT_FAILURE);
-+}
-+
-+static void ping4(len_and_sockaddr *lsa)
-+{
-+	struct icmp *pkt;
-+	int c;
-+
-+	pkt = (struct icmp *) G.packet;
-+	/*memset(pkt, 0, sizeof(G.packet)); already is */
-+	pkt->icmp_type = ICMP_ECHO;
-+	pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, sizeof(G.packet));
-+
-+	xsendto(pingsock, G.packet, DEFDATALEN + ICMP_MINLEN, &lsa->u.sa, lsa->len);
-+
-+	/* listen for replies */
-+	while (1) {
-+#if 0
-+		struct sockaddr_in from;
-+		socklen_t fromlen = sizeof(from);
-+
-+		c = recvfrom(pingsock, G.packet, sizeof(G.packet), 0,
-+				(struct sockaddr *) &from, &fromlen);
-+#else
-+		c = recv(pingsock, G.packet, sizeof(G.packet), 0);
-+#endif
-+		if (c < 0) {
-+			if (errno != EINTR)
-+				bb_perror_msg("recvfrom");
-+			continue;
-+		}
-+		if (c >= 76) {			/* ip + icmp */
-+			struct iphdr *iphdr = (struct iphdr *) G.packet;
-+
-+			pkt = (struct icmp *) (G.packet + (iphdr->ihl << 2));	/* skip ip hdr */
-+			if (pkt->icmp_type == ICMP_ECHOREPLY)
-+				break;
-+		}
-+	}
-+	if (ENABLE_FEATURE_CLEAN_UP)
-+		close(pingsock);
-+}
-+
-+#if ENABLE_PING6
-+static void ping6(len_and_sockaddr *lsa)
-+{
-+	struct icmp6_hdr *pkt;
-+	int c;
-+	int sockopt;
-+
-+	pkt = (struct icmp6_hdr *) G.packet;
-+	/*memset(pkt, 0, sizeof(G.packet)); already is */
-+	pkt->icmp6_type = ICMP6_ECHO_REQUEST;
-+
-+	sockopt = offsetof(struct icmp6_hdr, icmp6_cksum);
-+	setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, &sockopt, sizeof(sockopt));
-+
-+	xsendto(pingsock, G.packet, DEFDATALEN + sizeof(struct icmp6_hdr), &lsa->u.sa, lsa->len);
-+
-+	/* listen for replies */
-+	while (1) {
-+#if 0
-+		struct sockaddr_in6 from;
-+		socklen_t fromlen = sizeof(from);
-+
-+		c = recvfrom(pingsock, G.packet, sizeof(G.packet), 0,
-+				(struct sockaddr *) &from, &fromlen);
-+#else
-+		c = recv(pingsock, G.packet, sizeof(G.packet), 0);
-+#endif
-+		if (c < 0) {
-+			if (errno != EINTR)
-+				bb_perror_msg("recvfrom");
-+			continue;
-+		}
-+		if (c >= ICMP_MINLEN) {	/* icmp6_hdr */
-+			if (pkt->icmp6_type == ICMP6_ECHO_REPLY)
-+				break;
-+		}
-+	}
-+	if (ENABLE_FEATURE_CLEAN_UP)
-+		close(pingsock);
-+}
-+#endif
-+
-+#if !ENABLE_PING6
-+# define common_ping_main(af, argv) common_ping_main(argv)
-+#endif
-+static int common_ping_main(sa_family_t af, char **argv)
-+{
-+	len_and_sockaddr *lsa;
-+
-+	INIT_G();
-+
-+#if ENABLE_PING6
-+	while ((++argv)[0] && argv[0][0] == '-') {
-+		if (argv[0][1] == '4') {
-+			af = AF_INET;
-+			continue;
-+		}
-+		if (argv[0][1] == '6') {
-+			af = AF_INET6;
-+			continue;
-+		}
-+		bb_show_usage();
-+	}
-+#else
-+	argv++;
-+#endif
-+
-+	G.hostname = *argv;
-+	if (!G.hostname)
-+		bb_show_usage();
-+
-+#if ENABLE_PING6
-+	lsa = xhost_and_af2sockaddr(G.hostname, 0, af);
-+#else
-+	lsa = xhost_and_af2sockaddr(G.hostname, 0, AF_INET);
-+#endif
-+	/* Set timer _after_ DNS resolution */
-+	signal(SIGALRM, noresp);
-+	alarm(5); /* give the host 5000ms to respond */
-+
-+	create_icmp_socket(lsa);
-+#if ENABLE_PING6
-+	if (lsa->u.sa.sa_family == AF_INET6)
-+		ping6(lsa);
-+	else
-+#endif
-+		ping4(lsa);
-+	printf("%s is alive!\n", G.hostname);
-+	return EXIT_SUCCESS;
-+}
-+
-+
-+#else /* FEATURE_FANCY_PING */
-+
-+
-+/* Full(er) version */
-+
-+#define OPT_STRING ("qvc:s:t:w:W:I:n4" IF_PING6("6"))
-+enum {
-+	OPT_QUIET = 1 << 0,
-+	OPT_VERBOSE = 1 << 1,
-+	OPT_c = 1 << 2,
-+	OPT_s = 1 << 3,
-+	OPT_t = 1 << 4,
-+	OPT_w = 1 << 5,
-+	OPT_W = 1 << 6,
-+	OPT_I = 1 << 7,
-+	/*OPT_n = 1 << 8, - ignored */
-+	OPT_IPV4 = 1 << 9,
-+	OPT_IPV6 = (1 << 10) * ENABLE_PING6,
-+};
-+
-+
-+struct globals {
-+	int if_index;
-+	char *str_I;
-+	len_and_sockaddr *source_lsa;
-+	unsigned datalen;
-+	unsigned pingcount; /* must be int-sized */
-+	unsigned opt_ttl;
-+	unsigned long ntransmitted, nreceived, nrepeats;
-+	uint16_t myid;
-+	unsigned tmin, tmax; /* in us */
-+	unsigned long long tsum; /* in us, sum of all times */
-+	unsigned deadline;
-+	unsigned timeout;
-+	unsigned total_secs;
-+	unsigned sizeof_rcv_packet;
-+	char *rcv_packet; /* [datalen + MAXIPLEN + MAXICMPLEN] */
-+	void *snd_packet; /* [datalen + ipv4/ipv6_const] */
-+	const char *hostname;
-+	const char *dotted;
-+	union {
-+		struct sockaddr sa;
-+		struct sockaddr_in sin;
-+#if ENABLE_PING6
-+		struct sockaddr_in6 sin6;
-+#endif
-+	} pingaddr;
-+	unsigned char rcvd_tbl[MAX_DUP_CHK / 8];
-+} FIX_ALIASING;
-+#define G (*(struct globals*)&bb_common_bufsiz1)
-+#define if_index     (G.if_index    )
-+#define source_lsa   (G.source_lsa  )
-+#define str_I        (G.str_I       )
-+#define datalen      (G.datalen     )
-+#define pingcount    (G.pingcount   )
-+#define opt_ttl      (G.opt_ttl     )
-+#define myid         (G.myid        )
-+#define tmin         (G.tmin        )
-+#define tmax         (G.tmax        )
-+#define tsum         (G.tsum        )
-+#define deadline     (G.deadline    )
-+#define timeout      (G.timeout     )
-+#define total_secs   (G.total_secs  )
-+#define hostname     (G.hostname    )
-+#define dotted       (G.dotted      )
-+#define pingaddr     (G.pingaddr    )
-+#define rcvd_tbl     (G.rcvd_tbl    )
-+void BUG_ping_globals_too_big(void);
-+#define INIT_G() do { \
-+	if (sizeof(G) > COMMON_BUFSIZE) \
-+		BUG_ping_globals_too_big(); \
-+	datalen = DEFDATALEN; \
-+	timeout = MAXWAIT; \
-+	tmin = UINT_MAX; \
-+} while (0)
-+
-+
-+#define BYTE(bit)	rcvd_tbl[(bit)>>3]
-+#define MASK(bit)	(1 << ((bit) & 7))
-+#define SET(bit)	(BYTE(bit) |= MASK(bit))
-+#define CLR(bit)	(BYTE(bit) &= (~MASK(bit)))
-+#define TST(bit)	(BYTE(bit) & MASK(bit))
-+
-+static void print_stats_and_exit(int junk) NORETURN;
-+static void print_stats_and_exit(int junk UNUSED_PARAM)
-+{
-+	unsigned long ul;
-+	unsigned long nrecv;
-+
-+	signal(SIGINT, SIG_IGN);
-+
-+	nrecv = G.nreceived;
-+	printf("\n--- %s ping statistics ---\n"
-+		"%lu packets transmitted, "
-+		"%lu packets received, ",
-+		hostname, G.ntransmitted, nrecv
-+	);
-+	if (G.nrepeats)
-+		printf("%lu duplicates, ", G.nrepeats);
-+	ul = G.ntransmitted;
-+	if (ul != 0)
-+		ul = (ul - nrecv) * 100 / ul;
-+	printf("%lu%% packet loss\n", ul);
-+	if (tmin != UINT_MAX) {
-+		unsigned tavg = tsum / (nrecv + G.nrepeats);
-+		printf("round-trip min/avg/max = %u.%03u/%u.%03u/%u.%03u ms\n",
-+			tmin / 1000, tmin % 1000,
-+			tavg / 1000, tavg % 1000,
-+			tmax / 1000, tmax % 1000);
-+	}
-+	/* if condition is true, exit with 1 -- 'failure' */
-+	exit(nrecv == 0 || (deadline && nrecv < pingcount));
-+}
-+
-+static void sendping_tail(void (*sp)(int), int size_pkt)
-+{
-+	int sz;
-+
-+	CLR((uint16_t)G.ntransmitted % MAX_DUP_CHK);
-+	G.ntransmitted++;
-+
-+	size_pkt += datalen;
-+
-+	/* sizeof(pingaddr) can be larger than real sa size, but I think
-+	 * it doesn't matter */
-+	sz = xsendto(pingsock, G.snd_packet, size_pkt, &pingaddr.sa, sizeof(pingaddr));
-+	if (sz != size_pkt)
-+		bb_error_msg_and_die(bb_msg_write_error);
-+
-+	if (pingcount == 0 || deadline || G.ntransmitted < pingcount) {
-+		/* Didn't send all pings yet - schedule next in 1s */
-+		signal(SIGALRM, sp);
-+		if (deadline) {
-+			total_secs += PINGINTERVAL;
-+			if (total_secs >= deadline)
-+				signal(SIGALRM, print_stats_and_exit);
-+		}
-+		alarm(PINGINTERVAL);
-+	} else { /* -c NN, and all NN are sent (and no deadline) */
-+		/* Wait for the last ping to come back.
-+		 * -W timeout: wait for a response in seconds.
-+		 * Affects only timeout in absense of any responses,
-+		 * otherwise ping waits for two RTTs. */
-+		unsigned expire = timeout;
-+
-+		if (G.nreceived) {
-+			/* approx. 2*tmax, in seconds (2 RTT) */
-+			expire = tmax / (512*1024);
-+			if (expire == 0)
-+				expire = 1;
-+		}
-+		signal(SIGALRM, print_stats_and_exit);
-+		alarm(expire);
-+	}
-+}
-+
-+static void sendping4(int junk UNUSED_PARAM)
-+{
-+	struct icmp *pkt = G.snd_packet;
-+
-+	//memset(pkt, 0, datalen + ICMP_MINLEN + 4); - G.snd_packet was xzalloced
-+	pkt->icmp_type = ICMP_ECHO;
-+	/*pkt->icmp_code = 0;*/
-+	pkt->icmp_cksum = 0; /* cksum is calculated with this field set to 0 */
-+	pkt->icmp_seq = htons(G.ntransmitted); /* don't ++ here, it can be a macro */
-+	pkt->icmp_id = myid;
-+
-+	/* If datalen < 4, we store timestamp _past_ the packet,
-+	 * but it's ok - we allocated 4 extra bytes in xzalloc() just in case.
-+	 */
-+	/*if (datalen >= 4)*/
-+		/* No hton: we'll read it back on the same machine */
-+		*(uint32_t*)&pkt->icmp_dun = monotonic_us();
-+
-+	pkt->icmp_cksum = inet_cksum((uint16_t *) pkt, datalen + ICMP_MINLEN);
-+
-+	sendping_tail(sendping4, ICMP_MINLEN);
-+}
-+#if ENABLE_PING6
-+static void sendping6(int junk UNUSED_PARAM)
-+{
-+	struct icmp6_hdr *pkt = G.snd_packet;
-+
-+	//memset(pkt, 0, datalen + sizeof(struct icmp6_hdr) + 4);
-+	pkt->icmp6_type = ICMP6_ECHO_REQUEST;
-+	/*pkt->icmp6_code = 0;*/
-+	/*pkt->icmp6_cksum = 0;*/
-+	pkt->icmp6_seq = htons(G.ntransmitted); /* don't ++ here, it can be a macro */
-+	pkt->icmp6_id = myid;
-+
-+	/*if (datalen >= 4)*/
-+		*(bb__aliased_uint32_t*)(&pkt->icmp6_data8[4]) = monotonic_us();
-+
-+	//TODO? pkt->icmp_cksum = inet_cksum(...);
-+
-+	sendping_tail(sendping6, sizeof(struct icmp6_hdr));
-+}
-+#endif
-+
-+static const char *icmp_type_name(int id)
-+{
-+	switch (id) {
-+	case ICMP_ECHOREPLY:      return "Echo Reply";
-+	case ICMP_DEST_UNREACH:   return "Destination Unreachable";
-+	case ICMP_SOURCE_QUENCH:  return "Source Quench";
-+	case ICMP_REDIRECT:       return "Redirect (change route)";
-+	case ICMP_ECHO:           return "Echo Request";
-+	case ICMP_TIME_EXCEEDED:  return "Time Exceeded";
-+	case ICMP_PARAMETERPROB:  return "Parameter Problem";
-+	case ICMP_TIMESTAMP:      return "Timestamp Request";
-+	case ICMP_TIMESTAMPREPLY: return "Timestamp Reply";
-+	case ICMP_INFO_REQUEST:   return "Information Request";
-+	case ICMP_INFO_REPLY:     return "Information Reply";
-+	case ICMP_ADDRESS:        return "Address Mask Request";
-+	case ICMP_ADDRESSREPLY:   return "Address Mask Reply";
-+	default:                  return "unknown ICMP type";
-+	}
-+}
-+#if ENABLE_PING6
-+/* RFC3542 changed some definitions from RFC2292 for no good reason, whee!
-+ * the newer 3542 uses a MLD_ prefix where as 2292 uses ICMP6_ prefix */
-+#ifndef MLD_LISTENER_QUERY
-+# define MLD_LISTENER_QUERY ICMP6_MEMBERSHIP_QUERY
-+#endif
-+#ifndef MLD_LISTENER_REPORT
-+# define MLD_LISTENER_REPORT ICMP6_MEMBERSHIP_REPORT
-+#endif
-+#ifndef MLD_LISTENER_REDUCTION
-+# define MLD_LISTENER_REDUCTION ICMP6_MEMBERSHIP_REDUCTION
-+#endif
-+static const char *icmp6_type_name(int id)
-+{
-+	switch (id) {
-+	case ICMP6_DST_UNREACH:      return "Destination Unreachable";
-+	case ICMP6_PACKET_TOO_BIG:   return "Packet too big";
-+	case ICMP6_TIME_EXCEEDED:    return "Time Exceeded";
-+	case ICMP6_PARAM_PROB:       return "Parameter Problem";
-+	case ICMP6_ECHO_REPLY:       return "Echo Reply";
-+	case ICMP6_ECHO_REQUEST:     return "Echo Request";
-+	case MLD_LISTENER_QUERY:     return "Listener Query";
-+	case MLD_LISTENER_REPORT:    return "Listener Report";
-+	case MLD_LISTENER_REDUCTION: return "Listener Reduction";
-+	default:                     return "unknown ICMP type";
-+	}
-+}
-+#endif
-+
-+static void unpack_tail(int sz, uint32_t *tp,
-+		const char *from_str,
-+		uint16_t recv_seq, int ttl)
-+{
-+	unsigned char *b, m;
-+	const char *dupmsg = " (DUP!)";
-+	unsigned triptime = triptime; /* for gcc */
-+
-+	if (tp) {
-+		/* (int32_t) cast is for hypothetical 64-bit unsigned */
-+		/* (doesn't hurt 32-bit real-world anyway) */
-+		triptime = (int32_t) ((uint32_t)monotonic_us() - *tp);
-+		tsum += triptime;
-+		if (triptime < tmin)
-+			tmin = triptime;
-+		if (triptime > tmax)
-+			tmax = triptime;
-+	}
-+
-+	b = &BYTE(recv_seq % MAX_DUP_CHK);
-+	m = MASK(recv_seq % MAX_DUP_CHK);
-+	/*if TST(recv_seq % MAX_DUP_CHK):*/
-+	if (*b & m) {
-+		++G.nrepeats;
-+	} else {
-+		/*SET(recv_seq % MAX_DUP_CHK):*/
-+		*b |= m;
-+		++G.nreceived;
-+		dupmsg += 7;
-+	}
-+
-+	if (option_mask32 & OPT_QUIET)
-+		return;
-+
-+	printf("%d bytes from %s: seq=%u ttl=%d", sz,
-+		from_str, recv_seq, ttl);
-+	if (tp)
-+		printf(" time=%u.%03u ms", triptime / 1000, triptime % 1000);
-+	puts(dupmsg);
-+	fflush_all();
-+}
-+static void unpack4(char *buf, int sz, struct sockaddr_in *from)
-+{
-+	struct icmp *icmppkt;
-+	struct iphdr *iphdr;
-+	int hlen;
-+
-+	/* discard if too short */
-+	if (sz < (datalen + ICMP_MINLEN))
-+		return;
-+
-+	/* check IP header */
-+	iphdr = (struct iphdr *) buf;
-+	hlen = iphdr->ihl << 2;
-+	sz -= hlen;
-+	icmppkt = (struct icmp *) (buf + hlen);
-+	if (icmppkt->icmp_id != myid)
-+		return;				/* not our ping */
-+
-+	if (icmppkt->icmp_type == ICMP_ECHOREPLY) {
-+		uint16_t recv_seq = ntohs(icmppkt->icmp_seq);
-+		uint32_t *tp = NULL;
-+
-+		if (sz >= ICMP_MINLEN + sizeof(uint32_t))
-+			tp = (uint32_t *) icmppkt->icmp_data;
-+		unpack_tail(sz, tp,
-+			inet_ntoa(*(struct in_addr *) &from->sin_addr.s_addr),
-+			recv_seq, iphdr->ttl);
-+	} else if (icmppkt->icmp_type != ICMP_ECHO) {
-+		bb_error_msg("warning: got ICMP %d (%s)",
-+				icmppkt->icmp_type,
-+				icmp_type_name(icmppkt->icmp_type));
-+	}
-+}
-+#if ENABLE_PING6
-+static void unpack6(char *packet, int sz, struct sockaddr_in6 *from, int hoplimit)
-+{
-+	struct icmp6_hdr *icmppkt;
-+	char buf[INET6_ADDRSTRLEN];
-+
-+	/* discard if too short */
-+	if (sz < (datalen + sizeof(struct icmp6_hdr)))
-+		return;
-+
-+	icmppkt = (struct icmp6_hdr *) packet;
-+	if (icmppkt->icmp6_id != myid)
-+		return;				/* not our ping */
-+
-+	if (icmppkt->icmp6_type == ICMP6_ECHO_REPLY) {
-+		uint16_t recv_seq = ntohs(icmppkt->icmp6_seq);
-+		uint32_t *tp = NULL;
-+
-+		if (sz >= sizeof(struct icmp6_hdr) + sizeof(uint32_t))
-+			tp = (uint32_t *) &icmppkt->icmp6_data8[4];
-+		unpack_tail(sz, tp,
-+			inet_ntop(AF_INET6, &from->sin6_addr,
-+					buf, sizeof(buf)),
-+			recv_seq, hoplimit);
-+	} else if (icmppkt->icmp6_type != ICMP6_ECHO_REQUEST) {
-+		bb_error_msg("warning: got ICMP %d (%s)",
-+				icmppkt->icmp6_type,
-+				icmp6_type_name(icmppkt->icmp6_type));
-+	}
-+}
-+#endif
-+
-+static void ping4(len_and_sockaddr *lsa)
-+{
-+	int sockopt;
-+
-+	pingaddr.sin = lsa->u.sin;
-+	if (source_lsa) {
-+		if (setsockopt(pingsock, IPPROTO_IP, IP_MULTICAST_IF,
-+				&source_lsa->u.sa, source_lsa->len))
-+			bb_error_msg_and_die("can't set multicast source interface");
-+		xbind(pingsock, &source_lsa->u.sa, source_lsa->len);
-+	}
-+
-+	/* enable broadcast pings */
-+	setsockopt_broadcast(pingsock);
-+
-+	/* set recv buf (needed if we can get lots of responses: flood ping,
-+	 * broadcast ping etc) */
-+	sockopt = (datalen * 2) + 7 * 1024; /* giving it a bit of extra room */
-+	setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt));
-+
-+	if (opt_ttl != 0) {
-+		setsockopt(pingsock, IPPROTO_IP, IP_TTL, &opt_ttl, sizeof(opt_ttl));
-+		/* above doesnt affect packets sent to bcast IP, so... */
-+		setsockopt(pingsock, IPPROTO_IP, IP_MULTICAST_TTL, &opt_ttl, sizeof(opt_ttl));
-+	}
-+
-+	signal(SIGINT, print_stats_and_exit);
-+
-+	/* start the ping's going ... */
-+	sendping4(0);
-+
-+	/* listen for replies */
-+	while (1) {
-+		struct sockaddr_in from;
-+		socklen_t fromlen = (socklen_t) sizeof(from);
-+		int c;
-+
-+		c = recvfrom(pingsock, G.rcv_packet, G.sizeof_rcv_packet, 0,
-+				(struct sockaddr *) &from, &fromlen);
-+		if (c < 0) {
-+			if (errno != EINTR)
-+				bb_perror_msg("recvfrom");
-+			continue;
-+		}
-+		unpack4(G.rcv_packet, c, &from);
-+		if (pingcount && G.nreceived >= pingcount)
-+			break;
-+	}
-+}
-+#if ENABLE_PING6
-+extern int BUG_bad_offsetof_icmp6_cksum(void);
-+static void ping6(len_and_sockaddr *lsa)
-+{
-+	int sockopt;
-+	struct msghdr msg;
-+	struct sockaddr_in6 from;
-+	struct iovec iov;
-+	char control_buf[CMSG_SPACE(36)];
-+
-+	pingaddr.sin6 = lsa->u.sin6;
-+	if (source_lsa)
-+		xbind(pingsock, &source_lsa->u.sa, source_lsa->len);
-+
-+#ifdef ICMP6_FILTER
-+	{
-+		struct icmp6_filter filt;
-+		if (!(option_mask32 & OPT_VERBOSE)) {
-+			ICMP6_FILTER_SETBLOCKALL(&filt);
-+			ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filt);
-+		} else {
-+			ICMP6_FILTER_SETPASSALL(&filt);
-+		}
-+		if (setsockopt(pingsock, IPPROTO_ICMPV6, ICMP6_FILTER, &filt,
-+					sizeof(filt)) < 0)
-+			bb_error_msg_and_die("setsockopt(ICMP6_FILTER)");
-+	}
-+#endif /*ICMP6_FILTER*/
-+
-+	/* enable broadcast pings */
-+	setsockopt_broadcast(pingsock);
-+
-+	/* set recv buf (needed if we can get lots of responses: flood ping,
-+	 * broadcast ping etc) */
-+	sockopt = (datalen * 2) + 7 * 1024; /* giving it a bit of extra room */
-+	setsockopt(pingsock, SOL_SOCKET, SO_RCVBUF, &sockopt, sizeof(sockopt));
-+
-+	sockopt = offsetof(struct icmp6_hdr, icmp6_cksum);
-+	if (offsetof(struct icmp6_hdr, icmp6_cksum) != 2)
-+		BUG_bad_offsetof_icmp6_cksum();
-+	setsockopt(pingsock, SOL_RAW, IPV6_CHECKSUM, &sockopt, sizeof(sockopt));
-+
-+	/* request ttl info to be returned in ancillary data */
-+	setsockopt(pingsock, SOL_IPV6, IPV6_HOPLIMIT, &const_int_1, sizeof(const_int_1));
-+
-+	if (if_index)
-+		pingaddr.sin6.sin6_scope_id = if_index;
-+
-+	signal(SIGINT, print_stats_and_exit);
-+
-+	/* start the ping's going ... */
-+	sendping6(0);
-+
-+	/* listen for replies */
-+	msg.msg_name = &from;
-+	msg.msg_namelen = sizeof(from);
-+	msg.msg_iov = &iov;
-+	msg.msg_iovlen = 1;
-+	msg.msg_control = control_buf;
-+	iov.iov_base = G.rcv_packet;
-+	iov.iov_len = G.sizeof_rcv_packet;
-+	while (1) {
-+		int c;
-+		struct cmsghdr *mp;
-+		int hoplimit = -1;
-+		msg.msg_controllen = sizeof(control_buf);
-+
-+		c = recvmsg(pingsock, &msg, 0);
-+		if (c < 0) {
-+			if (errno != EINTR)
-+				bb_perror_msg("recvfrom");
-+			continue;
-+		}
-+		for (mp = CMSG_FIRSTHDR(&msg); mp; mp = CMSG_NXTHDR(&msg, mp)) {
-+			if (mp->cmsg_level == SOL_IPV6
-+			 && mp->cmsg_type == IPV6_HOPLIMIT
-+			 /* don't check len - we trust the kernel: */
-+			 /* && mp->cmsg_len >= CMSG_LEN(sizeof(int)) */
-+			) {
-+				/*hoplimit = *(int*)CMSG_DATA(mp); - unaligned access */
-+				move_from_unaligned_int(hoplimit, CMSG_DATA(mp));
-+			}
-+		}
-+		unpack6(G.rcv_packet, c, &from, hoplimit);
-+		if (pingcount && G.nreceived >= pingcount)
-+			break;
-+	}
-+}
-+#endif
-+
-+static void ping(len_and_sockaddr *lsa)
-+{
-+	printf("PING %s (%s)", hostname, dotted);
-+	if (source_lsa) {
-+		printf(" from %s",
-+			xmalloc_sockaddr2dotted_noport(&source_lsa->u.sa));
-+	}
-+	printf(": %d data bytes\n", datalen);
-+
-+	create_icmp_socket(lsa);
-+	/* untested whether "-I addr" really works for IPv6: */
-+	if (str_I)
-+		setsockopt_bindtodevice(pingsock, str_I);
-+
-+	G.sizeof_rcv_packet = datalen + MAXIPLEN + MAXICMPLEN;
-+	G.rcv_packet = xzalloc(G.sizeof_rcv_packet);
-+#if ENABLE_PING6
-+	if (lsa->u.sa.sa_family == AF_INET6) {
-+		/* +4 reserves a place for timestamp, which may end up sitting
-+		 * _after_ packet. Saves one if() - see sendping4/6() */
-+		G.snd_packet = xzalloc(datalen + sizeof(struct icmp6_hdr) + 4);
-+		ping6(lsa);
-+	} else
-+#endif
-+	{
-+		G.snd_packet = xzalloc(datalen + ICMP_MINLEN + 4);
-+		ping4(lsa);
-+	}
-+}
-+
-+static int common_ping_main(int opt, char **argv)
-+{
-+	len_and_sockaddr *lsa;
-+	char *str_s;
-+
-+	INIT_G();
-+
-+	/* exactly one argument needed; -v and -q don't mix; -c NUM, -t NUM, -w NUM, -W NUM */
-+	opt_complementary = "=1:q--v:v--q:c+:t+:w+:W+";
-+	opt |= getopt32(argv, OPT_STRING, &pingcount, &str_s, &opt_ttl, &deadline, &timeout, &str_I);
-+	if (opt & OPT_s)
-+		datalen = xatou16(str_s); // -s
-+	if (opt & OPT_I) { // -I
-+		if_index = if_nametoindex(str_I);
-+		if (!if_index) {
-+			/* TODO: I'm not sure it takes IPv6 unless in [XX:XX..] format */
-+			source_lsa = xdotted2sockaddr(str_I, 0);
-+			str_I = NULL; /* don't try to bind to device later */
-+		}
-+	}
-+	myid = (uint16_t) getpid();
-+	hostname = argv[optind];
-+#if ENABLE_PING6
-+	{
-+		sa_family_t af = AF_UNSPEC;
-+		if (opt & OPT_IPV4)
-+			af = AF_INET;
-+		if (opt & OPT_IPV6)
-+			af = AF_INET6;
-+		lsa = xhost_and_af2sockaddr(hostname, 0, af);
-+	}
-+#else
-+	lsa = xhost_and_af2sockaddr(hostname, 0, AF_INET);
-+#endif
-+
-+	if (source_lsa && source_lsa->u.sa.sa_family != lsa->u.sa.sa_family)
-+		/* leaking it here... */
-+		source_lsa = NULL;
-+
-+	dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa);
-+	ping(lsa);
-+	print_stats_and_exit(EXIT_SUCCESS);
-+	/*return EXIT_SUCCESS;*/
-+}
-+#endif /* FEATURE_FANCY_PING */
-+
-+
-+int ping_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
-+int ping_main(int argc UNUSED_PARAM, char **argv)
-+{
-+#if !ENABLE_FEATURE_FANCY_PING
-+	return common_ping_main(AF_UNSPEC, argv);
-+#else
-+	return common_ping_main(0, argv);
-+#endif
-+}
-+
-+#if ENABLE_PING6
-+int ping6_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
-+int ping6_main(int argc UNUSED_PARAM, char **argv)
-+{
-+# if !ENABLE_FEATURE_FANCY_PING
-+	return common_ping_main(AF_INET6, argv);
-+# else
-+	return common_ping_main(OPT_IPV6, argv);
-+# endif
-+}
-+#endif
-+
-+/* from ping6.c:
-+ * Copyright (c) 1989 The Regents of the University of California.
-+ * All rights reserved.
-+ *
-+ * This code is derived from software contributed to Berkeley by
-+ * Mike Muuss.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions
-+ * are met:
-+ * 1. Redistributions of source code must retain the above copyright
-+ *    notice, this list of conditions and the following disclaimer.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ *
-+ * 3. <BSD Advertising Clause omitted per the July 22, 1999 licensing change
-+ *		ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change>
-+ *
-+ * 4. Neither the name of the University nor the names of its contributors
-+ *    may be used to endorse or promote products derived from this software
-+ *    without specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-+ * SUCH DAMAGE.
-+ */

+ 114 - 0
package/busybox/patches/005-busybox-1.23.0-modprobe.patch

@@ -0,0 +1,114 @@
+--- busybox-1.23.0/modutils/depmod.c
++++ busybox-1.23.0-modprobe/modutils/depmod.c
+@@ -51,7 +51,11 @@ static int FAST_FUNC parse_module(const
+ 
+ 	info->dnext = info->dprev = info;
+ 	info->name = xstrdup(fname + 2); /* skip "./" */
+-	info->modname = xstrdup(filename2modname(fname, modname));
++	info->modname = xstrdup(
++		filename2modname(
++			bb_get_last_path_component_nostrip(fname),
++			modname
++	));
+ 	for (ptr = image; ptr < image + len - 10; ptr++) {
+ 		if (strncmp(ptr, "depends=", 8) == 0) {
+ 			char *u;
+@@ -242,17 +246,18 @@ int depmod_main(int argc UNUSED_PARAM, c
+ 	if (!(option_mask32 & OPT_n))
+ 		xfreopen_write("modules.alias", stdout);
+ 	for (m = modules; m != NULL; m = m->next) {
++		char modname[MODULE_NAME_LEN];
+ 		const char *fname = bb_basename(m->name);
+-		int fnlen = strchrnul(fname, '.') - fname;
++		filename2modname(fname, modname);
+ 		while (m->aliases) {
+ 			/* Last word can well be m->modname instead,
+ 			 * but depmod from module-init-tools 3.4
+ 			 * uses module basename, i.e., no s/-/_/g.
+ 			 * (pathname and .ko.* are still stripped)
+ 			 * Mimicking that... */
+-			printf("alias %s %.*s\n",
++			printf("alias %s %s\n",
+ 				(char*)llist_pop(&m->aliases),
+-				fnlen, fname);
++				modname);
+ 		}
+ 	}
+ #endif
+@@ -260,12 +265,13 @@ int depmod_main(int argc UNUSED_PARAM, c
+ 	if (!(option_mask32 & OPT_n))
+ 		xfreopen_write("modules.symbols", stdout);
+ 	for (m = modules; m != NULL; m = m->next) {
++		char modname[MODULE_NAME_LEN];
+ 		const char *fname = bb_basename(m->name);
+-		int fnlen = strchrnul(fname, '.') - fname;
++		filename2modname(fname, modname);
+ 		while (m->symbols) {
+-			printf("alias symbol:%s %.*s\n",
++			printf("alias symbol:%s %s\n",
+ 				(char*)llist_pop(&m->symbols),
+-				fnlen, fname);
++				modname);
+ 		}
+ 	}
+ #endif
+--- busybox-1.23.0/modutils/modprobe.c
++++ busybox-1.23.0-modprobe/modutils/modprobe.c
+@@ -238,17 +238,6 @@ static void add_probe(const char *name)
+ {
+ 	struct module_entry *m;
+ 
+-	/*
+-	 * get_or_add_modentry() strips path from name and works
+-	 * on remaining basename.
+-	 * This would make "rmmod dir/name" and "modprobe dir/name"
+-	 * to work like "rmmod name" and "modprobe name",
+-	 * which is wrong, and can be abused via implicit modprobing:
+-	 * "ifconfig /usbserial up" tries to modprobe netdev-/usbserial.
+-	 */
+-	if (strchr(name, '/'))
+-		bb_error_msg_and_die("malformed module name '%s'", name);
+-
+ 	m = get_or_add_modentry(name);
+ 	if (!(option_mask32 & (OPT_REMOVE | OPT_SHOW_DEPS))
+ 	 && (m->flags & MODULE_FLAG_LOADED)
+--- busybox-1.23.0/modutils/modprobe-small.c
++++ busybox-1.23.0-modprobe/modutils/modprobe-small.c
+@@ -149,9 +149,13 @@ static void replace(char *s, char what,
+ static char *filename2modname(const char *filename, char *modname)
+ {
+ 	int i;
+-	char *from;
++	const char *from;
+ 
+-	from = bb_get_last_path_component_nostrip(filename);
++	// Disabled since otherwise "modprobe dir/name" would work
++	// as if it is "modprobe name". It is unclear why
++	// 'basenamization' was here in the first place.
++	//from = bb_get_last_path_component_nostrip(filename);
++	from = filename;
+ 	for (i = 0; i < (MODULE_NAME_LEN-1) && from[i] != '\0' && from[i] != '.'; i++)
+ 		modname[i] = (from[i] == '-') ? '_' : from[i];
+ 	modname[i] = '\0';
+--- busybox-1.23.0/modutils/modutils.c
++++ busybox-1.23.0-modprobe/modutils/modutils.c
+@@ -48,13 +48,17 @@ int FAST_FUNC string_to_llist(char *stri
+ char* FAST_FUNC filename2modname(const char *filename, char *modname)
+ {
+ 	int i;
+-	char *from;
++	const char *from;
+ 
+ 	if (filename == NULL)
+ 		return NULL;
+ 	if (modname == NULL)
+ 		modname = xmalloc(MODULE_NAME_LEN);
+-	from = bb_get_last_path_component_nostrip(filename);
++	// Disabled since otherwise "modprobe dir/name" would work
++	// as if it is "modprobe name". It is unclear why
++	// 'basenamization' was here in the first place.
++	//from = bb_get_last_path_component_nostrip(filename);
++	from = filename;
+ 	for (i = 0; i < (MODULE_NAME_LEN-1) && from[i] != '\0' && from[i] != '.'; i++)
+ 		modname[i] = (from[i] == '-') ? '_' : from[i];
+ 	modname[i] = '\0';

+ 49 - 0
package/busybox/patches/006-busybox-1.23.0-vi.patch

@@ -0,0 +1,49 @@
+--- busybox-1.23.0/editors/vi.c
++++ busybox-1.23.0-vi/editors/vi.c
+@@ -542,9 +542,6 @@ static void cookmode(void);	// return to
+ static int mysleep(int);
+ static int readit(void);	// read (maybe cursor) key from stdin
+ static int get_one_char(void);	// read 1 char from stdin
+-#if !ENABLE_FEATURE_VI_READONLY
+-#define file_insert(fn, p, update_ro_status) file_insert(fn, p)
+-#endif
+ // file_insert might reallocate text[]!
+ static int file_insert(const char *, char *, int);
+ static int file_write(char *, char *, char *);
+@@ -1325,7 +1322,7 @@ static void colon(char *buf)
+ 			q = next_line(q);
+ 		{ // dance around potentially-reallocated text[]
+ 			uintptr_t ofs = q - text;
+-			size = file_insert(fn, q, /*update_ro:*/ 0);
++			size = file_insert(fn, q, 0);
+ 			q = text + ofs;
+ 		}
+ 		if (size < 0)
+@@ -2905,7 +2902,7 @@ static char *get_input_line(const char *
+ }
+ 
+ // might reallocate text[]!
+-static int file_insert(const char *fn, char *p, int update_ro_status)
++static int file_insert(const char *fn, char *p, int initial)
+ {
+ 	int cnt = -1;
+ 	int fd, size;
+@@ -2918,7 +2915,8 @@ static int file_insert(const char *fn, c
+ 
+ 	fd = open(fn, O_RDONLY);
+ 	if (fd < 0) {
+-		status_line_bold_errno(fn);
++		if (!initial)
++			status_line_bold_errno(fn);
+ 		return cnt;
+ 	}
+ 
+@@ -2946,7 +2944,7 @@ static int file_insert(const char *fn, c
+ 	close(fd);
+ 
+ #if ENABLE_FEATURE_VI_READONLY
+-	if (update_ro_status
++	if (initial
+ 	 && ((access(fn, W_OK) < 0) ||
+ 		/* root will always have access()
+ 		 * so we check fileperms too */

+ 0 - 20
package/busybox/patches/011-utmp-segfault-mips64-fix.patch

@@ -1,20 +0,0 @@
-diff -Nur busybox-1.20.2.orig/libbb/utmp.c busybox-1.20.2/libbb/utmp.c
---- busybox-1.20.2.orig/libbb/utmp.c	2012-06-26 15:35:45.000000000 +0200
-+++ busybox-1.20.2/libbb/utmp.c	2012-09-24 20:25:27.000000000 +0200
-@@ -10,8 +10,14 @@
- 
- static void touch(const char *filename)
- {
--	if (access(filename, R_OK | W_OK) == -1)
--		close(open(filename, O_WRONLY | O_CREAT, 0664));
-+        int c = 0;
-+
-+        if (access(filename, R_OK | W_OK) == -1) {
-+                c=open(filename, O_WRONLY | O_CREAT, 0664);
-+                if (c > 0) {
-+                        close(c);
-+                }
-+        }
- }
- 
- void FAST_FUNC write_new_utmp(pid_t pid, int new_type, const char *tty_name, const char *username, const char *hostname)

+ 0 - 12
package/busybox/patches/012-find-posix.patch

@@ -1,12 +0,0 @@
-diff -Nur busybox-1.20.2.orig/scripts/gen_build_files.sh busybox-1.20.2/scripts/gen_build_files.sh
---- busybox-1.20.2.orig/scripts/gen_build_files.sh	2012-06-26 13:35:45.000000000 +0000
-+++ busybox-1.20.2/scripts/gen_build_files.sh	2013-04-29 12:18:26.089999426 +0000
-@@ -61,7 +61,7 @@
- 
- # (Re)generate */Kbuild and */Config.in
- # We skip .dotdirs - makes git/svn/etc users happier
--{ cd -- "$srctree" && find . -type d -not '(' -name '.?*' -prune ')'; } \
-+{ cd -- "$srctree" && find . -type d ! '(' -name '.?*' -prune ')'; } \
- | while read -r d; do
- 	d="${d#./}"
- 

+ 0 - 22
package/busybox/patches/017-remove-alloca.patch

@@ -1,22 +0,0 @@
-diff -Nur busybox-1.21.1.orig/scripts/basic/docproc.c busybox-1.21.1/scripts/basic/docproc.c
---- busybox-1.21.1.orig/scripts/basic/docproc.c	Sat May 11 17:30:44 2013
-+++ busybox-1.21.1/scripts/basic/docproc.c	Thu Jan 16 03:00:39 2014
-@@ -39,7 +39,6 @@
- #include <limits.h>
- #include <sys/types.h>
- #include <sys/wait.h>
--#include <alloca.h>
- 
- /* exitstatus is used to keep track of any failing calls to kernel-doc,
-  * but execution continues. */
-diff -Nur busybox-1.21.1.orig/scripts/basic/fixdep.c busybox-1.21.1/scripts/basic/fixdep.c
---- busybox-1.21.1.orig/scripts/basic/fixdep.c	Sat May 11 17:30:44 2013
-+++ busybox-1.21.1/scripts/basic/fixdep.c	Thu Jan 16 03:00:33 2014
-@@ -113,7 +113,6 @@
- #include <limits.h>
- #include <ctype.h>
- #include <arpa/inet.h>
--#include <alloca.h>
- 
- /* bbox: not needed
- #define INT_CONF ntohl(0x434f4e46)

部分文件因文件數量過多而無法顯示