Patch from vodz:
    Changed email address
    cmdedit API change
    optimizations for traceroute and md5sum
    added a new shared create_icmp_socket() function
diff --git a/shell/cmdedit.c b/shell/cmdedit.c
index 4f124d6..540eb7e 100644
--- a/shell/cmdedit.c
+++ b/shell/cmdedit.c
@@ -3,7 +3,7 @@
  * Termios command line History and Editting.
  *
  * Copyright (c) 1986-2001 may safely be consumed by a BSD or GPL license.
- * Written by:   Vladimir Oleynik <vodz@usa.net>
+ * Written by:   Vladimir Oleynik <dzo@simtreas.ru>
  *
  * Used ideas:
  *      Adam Rogoyski    <rogoyski@cs.utexas.edu>
@@ -123,9 +123,8 @@
 enum {
 	SET_ATEXIT = 1,		/* when atexit() has been called 
 				   and get euid,uid,gid to fast compare */
-	SET_TERM_HANDLERS = 2,	/* set many terminates signal handlers */
-	SET_WCHG_HANDLERS = 4,	/* winchg signal handler */
-	SET_RESET_TERM = 8,	/* if the terminal needs to be reset upon exit */
+	SET_WCHG_HANDLERS = 2,  /* winchg signal handler */
+	SET_RESET_TERM = 4,     /* if the terminal needs to be reset upon exit */
 };
 
 
@@ -142,10 +141,6 @@
 #endif
 char *cmdedit_prompt;		/* --- "" - - "" - -"- --""-- --""--- */
 
-/* Link into lash to reset context to 0 on ^C and such */
-extern unsigned int shell_context;
-
-
 #ifdef BB_FEATURE_GETUSERNAME_AND_HOMEDIR
 static char *user_buf = "";
 static char *home_pwd_buf = "";
@@ -319,6 +314,7 @@
 	out1str(cmdedit_prompt);
 	cmdedit_x = cmdedit_prmt_len;	/* count real x terminal position */
 	cursor = 0;
+	cmdedit_y = 0;                  /* new quasireal y */
 }
 
 #ifndef BB_FEATURE_SH_FANCY_PROMPT
@@ -456,7 +452,6 @@
 {
 	if (y > 0)				/* up to start y */
 		printf("\033[%dA", y);
-	cmdedit_y = 0;				/* new quasireal y */
 	putchar('\r');
 	put_prompt();
 	input_end();				/* rewrite */
@@ -497,14 +492,6 @@
 }
 
 
-static void clean_up_and_die(int sig)
-{
-	goto_new_line();
-	if (sig != SIGINT)
-		exit(EXIT_SUCCESS);	/* cmdedit_reset_term() called in atexit */
-	cmdedit_reset_term();
-}
-
 static void cmdedit_setwidth(int w, int redraw_flg)
 {
 	cmdedit_termw = cmdedit_prmt_len + 2;
@@ -525,7 +512,7 @@
 	} 
 }
 
-extern void cmdedit_init(void)
+static void cmdedit_init(void)
 {
 	cmdedit_prmt_len = 0;
 	if ((handlers_sets & SET_WCHG_HANDLERS) == 0) {
@@ -557,14 +544,6 @@
 		handlers_sets |= SET_ATEXIT;
 		atexit(cmdedit_reset_term);	/* be sure to do this only once */
 	}
-
-	if ((handlers_sets & SET_TERM_HANDLERS) == 0) {
-		signal(SIGKILL, clean_up_and_die);
-		signal(SIGINT, clean_up_and_die);
-		signal(SIGQUIT, clean_up_and_die);
-		signal(SIGTERM, clean_up_and_die);
-		handlers_sets |= SET_TERM_HANDLERS;
-	}
 }
 
 #ifdef BB_FEATURE_COMMAND_TAB_COMPLETION
@@ -1220,7 +1199,7 @@
 
 		fflush(stdout);			/* buffered out to fast */
 
-		if (read(0, &c, 1) < 1)
+		if (safe_read(0, &c, 1) < 1)
 			/* if we can't read input then exit */
 			goto prepare_to_die;
 
@@ -1241,22 +1220,21 @@
 			break;
 		case 3:
 			/* Control-c -- stop gathering input */
-
-			/* Link into lash to reset context to 0 on ^C and such */
-			shell_context = 0;
-
-			/* Go to the next line */
 			goto_new_line();
 			command[0] = 0;
-
-			return;
+			len = 0;
+			lastWasTab = FALSE;
+			put_prompt();
+			break;
 		case 4:
 			/* Control-d -- Delete one character, or exit
 			 * if the len=0 and no chars to delete */
 			if (len == 0) {
 prepare_to_die:
 				printf("exit");
-				clean_up_and_die(0);
+				goto_new_line();
+				/* cmdedit_reset_term() called in atexit */
+				exit(EXIT_SUCCESS);
 			} else {
 				input_delete();
 			}
@@ -1307,12 +1285,12 @@
 
 		case ESC:{
 			/* escape sequence follows */
-			if (read(0, &c, 1) < 1)
-				return;
+			if (safe_read(0, &c, 1) < 1)
+				goto prepare_to_die;
 			/* different vt100 emulations */
 			if (c == '[' || c == 'O') {
-				if (read(0, &c, 1) < 1)
-					return;
+				if (safe_read(0, &c, 1) < 1)
+					goto prepare_to_die;
 			}
 			switch (c) {
 #ifdef BB_FEATURE_COMMAND_TAB_COMPLETION
@@ -1376,8 +1354,8 @@
 			}
 			if (c >= '1' && c <= '9')
 				do
-					if (read(0, &c, 1) < 1)
-						return;
+					if (safe_read(0, &c, 1) < 1)
+						goto prepare_to_die;
 				while (c != '~');
 			break;
 		}
@@ -1386,8 +1364,8 @@
 #ifdef BB_FEATURE_NONPRINTABLE_INVERSE_PUT
 			/* Control-V -- Add non-printable symbol */
 			if (c == 22) {
-				if (read(0, &c, 1) < 1)
-					return;
+				if (safe_read(0, &c, 1) < 1)
+					goto prepare_to_die;
 				if (c == 0) {
 					beep();
 					break;
@@ -1485,24 +1463,11 @@
 #if defined(BB_FEATURE_SH_FANCY_PROMPT)
 	free(cmdedit_prompt);
 #endif
-	return;
-}
-
-
-/* Undo the effects of cmdedit_init(). */
-extern void cmdedit_terminate(void)
-{
 	cmdedit_reset_term();
-	if ((handlers_sets & SET_TERM_HANDLERS) != 0) {
-		signal(SIGKILL, SIG_DFL);
-		signal(SIGINT, SIG_DFL);
-		signal(SIGQUIT, SIG_DFL);
-		signal(SIGTERM, SIG_DFL);
-		signal(SIGWINCH, SIG_DFL);
-		handlers_sets &= ~SET_TERM_HANDLERS;
-	}
 }
 
+
+
 #endif	/* BB_FEATURE_COMMAND_EDITING */
 
 
@@ -1515,8 +1480,6 @@
 #include <locale.h>
 #endif
 
-unsigned int shell_context;
-
 int main(int argc, char **argv)
 {
 	char buff[BUFSIZ];
@@ -1532,15 +1495,16 @@
 #ifdef BB_FEATURE_NONPRINTABLE_INVERSE_PUT
 	setlocale(LC_ALL, "");
 #endif
-	shell_context = 1;
-	do {
+	while(1) {
 		int l;
 		cmdedit_read_input(prompt, buff);
 		l = strlen(buff);
+		if(l==0)
+			break;
 		if(l > 0 && buff[l-1] == '\n')
 			buff[l-1] = 0;
 		printf("*** cmdedit_read_input() returned line =%s=\n", buff);
-	} while (shell_context);
+	}
 	printf("*** cmdedit_read_input() detect ^C\n");
 	return 0;
 }