diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh
index f84dfd4b22d709a4e00bdd9bae9d3f7d7df92112..a507d30e5189fa562d451cc68073465e316528c4 100755
--- a/BUILD/SETUP.sh
+++ b/BUILD/SETUP.sh
@@ -53,11 +53,14 @@ max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --wit
 max_no_es_configs="$max_leave_isam_configs --without-isam"
 max_configs="$max_no_es_configs --with-embedded-server"
 
-alpha_cflags="-mcpu=ev6 -Wa,-mev6"	# Not used yet
-amd64_cflags=""				# If dropping '--with-big-tables', add here  "-DBIG_TABLES"
-pentium_cflags="-mcpu=pentiumpro"
-pentium64_cflags="-mcpu=nocona -m64"
-ppc_cflags="-mpowerpc -mcpu=powerpc"
+path=`dirname $0`
+. "$path/check-cpu"
+
+alpha_cflags="$check_cpu_cflags -Wa,-m$cpu_flag"
+amd64_cflags="$check_cpu_cflags"
+pentium_cflags="$check_cpu_cflags"
+pentium64_cflags="$check_cpu_cflags -m64"
+ppc_cflags="$check_cpu_cflags"
 sparc_cflags=""
 
 # be as fast as we can be without losing our ability to backtrace
diff --git a/BUILD/check-cpu b/BUILD/check-cpu
new file mode 100755
index 0000000000000000000000000000000000000000..553df39191f56cd900871ef6842c8c5b3760834a
--- /dev/null
+++ b/BUILD/check-cpu
@@ -0,0 +1,81 @@
+#!/bin/sh
+#
+# Check cpu of current machine and find the
+# best compiler optimization flags for gcc
+#
+#
+
+if test -r /proc/cpuinfo ; then
+  cpuinfo="cat /proc/cpuinfo"
+  cpu_family=`$cpuinfo | grep 'family' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1`
+  if test -z "$cpu_family" ; then
+    cpu_family=`$cpuinfo | grep 'cpu' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1`
+  fi
+  cpu_vendor=`$cpuinfo | grep 'vendor_id' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1`
+  model_name=`$cpuinfo | grep 'model name' | cut -d ':' -f 2 | head -1`
+  if test -z "$model_name" ; then
+    model_name=`$cpuinfo | grep 'cpu model' | cut -d ':' -f 2 | head -1`
+  fi
+  if test -z "$model_name" ; then
+    model_name=`uname -m`
+  fi
+fi
+
+case "$cpu_family--$model_name" in
+  Alpha*EV6*)
+    cpu_flag="ev6";
+    ;;
+  *Xeon*)
+    cpu_flag="nocona";
+    ;;
+  *Pentium*4*CPU*)
+    cpu_flag="pentium4";
+    ;;
+  *Athlon*64*)
+    cpu_flag="athlon64";
+    ;;
+  *Athlon*)
+    cpu_flag="athlon";
+    ;;
+  *Itanium*)
+    # Don't need to set any flags for itanium(at the moment)
+    cpu_flag="";
+    ;;
+  *ppc)
+    cpu_flag="powerpc";
+    ;;
+  *)
+    cpu_flag="";
+    ;;
+esac
+
+if test -z "$cpu_flag"; then
+  echo "BUILD/check-cpu: Oops, could not findout what kind of cpu this machine is using."
+  check_cpu_flags=""
+  return
+fi
+
+echo "cpu_flag: $cpu_flag"
+
+if test -z "$CC" ; then
+  cc="gcc";
+else
+  cc=$CC
+
+fi
+
+cc_ver=`$cc --version | sed 1q`
+cc_verno=`echo $cc_ver | sed -e 's/[^0-9. ]//g;	 s/^ *//g; s/ .*//g'`
+
+case "$cc_ver--$cc_verno" in
+  *GCC*--3.4*|*GCC*--3.5*|*GCC*--4.*)
+    check_cpu_cflags="-mtune=$cpu_flag -march=$cpu_flag"
+    ;;
+  *GCC*)
+    check_cpu_cflags="-mcpu=$cpu_flag -march=$cpu_flag"
+    ;;
+  *)
+    check_cpu_cflags=""
+    ;;
+esac
+echo $check_cpu_cflags
diff --git a/client/mysql.cc b/client/mysql.cc
index 4eed4349b451edfde2b7a140a70674be73cc240e..5282f74453d56b6a6e06f70b3095f47919c1455e 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -703,8 +703,16 @@ static void usage(int version)
 #ifdef __NETWARE__
 #define printf	consoleprintf
 #endif
-  printf("%s  Ver %s Distrib %s, for %s (%s)\n",
-	 my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
+
+#if defined(USE_LIBEDIT_INTERFACE)
+  const char* readline= "";
+#else
+  const char* readline= "readline";
+#endif
+
+  printf("%s  Ver %s Distrib %s, for %s (%s) using %s %s\n",
+	 my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE,
+         readline, rl_library_version);
   if (version)
     return;
   printf("\
@@ -1323,7 +1331,7 @@ static void initialize_readline (char *name)
   setlocale(LC_ALL,""); /* so as libedit use isprint */
 #endif
   rl_attempted_completion_function= (CPPFunction*)&new_mysql_completion;
-  rl_completion_entry_function= (CPFunction*)&no_completion;
+  rl_completion_entry_function= (Function*)&no_completion;
 #else
   rl_attempted_completion_function= (CPPFunction*)&new_mysql_completion;
   rl_completion_entry_function= (Function*)&no_completion;
diff --git a/cmd-line-utils/libedit/chared.c b/cmd-line-utils/libedit/chared.c
index 62a407e66a84214b06c6c271496aac760e5c2375..21fc8bc2c1d2ec2036fc44cb3a8b288eb863a576 100644
--- a/cmd-line-utils/libedit/chared.c
+++ b/cmd-line-utils/libedit/chared.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: chared.c,v 1.18 2002/11/20 16:50:08 christos Exp $	*/
+/*	$NetBSD: chared.c,v 1.22 2004/08/13 12:10:38 mycroft Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,14 +32,7 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)chared.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: chared.c,v 1.18 2002/11/20 16:50:08 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * chared.c: Character editor utilities
@@ -62,13 +51,13 @@ cv_undo(EditLine *el)
 {
 	c_undo_t *vu = &el->el_chared.c_undo;
 	c_redo_t *r = &el->el_chared.c_redo;
-	int size;
+	uint size;
 
 	/* Save entire line for undo */
 	size = el->el_line.lastchar - el->el_line.buffer;
 	vu->len = size;
 	vu->cursor = el->el_line.cursor - el->el_line.buffer;
-	memcpy(vu->buf, el->el_line.buffer, (size_t)size);
+	memcpy(vu->buf, el->el_line.buffer, size);
 
 	/* save command info for redo */
 	r->count = el->el_state.doingarg ? el->el_state.argument : 0;
@@ -139,6 +128,21 @@ c_delafter(EditLine *el, int num)
 }
 
 
+/* c_delafter1():
+ *	Delete the character after the cursor, do not yank
+ */
+protected void
+c_delafter1(EditLine *el)
+{
+	char *cp;
+
+	for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
+		*cp = cp[1];
+
+	el->el_line.lastchar--;
+}
+
+
 /* c_delbefore():
  *	Delete num characters before the cursor
  */
@@ -167,6 +171,21 @@ c_delbefore(EditLine *el, int num)
 }
 
 
+/* c_delbefore1():
+ *	Delete the character before the cursor, do not yank
+ */
+protected void
+c_delbefore1(EditLine *el)
+{
+	char *cp;
+
+	for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
+		*cp = cp[1];
+
+	el->el_line.lastchar--;
+}
+
+
 /* ce__isword():
  *	Return if p is part of a word according to emacs
  */
@@ -460,8 +479,8 @@ ch_init(EditLine *el)
 	el->el_state.argument		= 1;
 	el->el_state.lastcmd		= ED_UNASSIGNED;
 
-	el->el_chared.c_macro.nline	= NULL;
 	el->el_chared.c_macro.level	= -1;
+	el->el_chared.c_macro.offset	= 0;
 	el->el_chared.c_macro.macro	= (char **) el_malloc(EL_MAXMACRO *
 	    sizeof(char *));
 	if (el->el_chared.c_macro.macro == NULL)
@@ -582,7 +601,7 @@ ch_enlargebufs(el, addlen)
 		return 0;
 
 	/* Safe to set enlarged buffer size */
-	el->el_line.limit  = &newbuffer[newsz - EL_LEAVE];
+	el->el_line.limit  = &el->el_line.buffer[newsz - EL_LEAVE];
 	return 1;
 }
 
diff --git a/cmd-line-utils/libedit/chared.h b/cmd-line-utils/libedit/chared.h
index d2e6f742413d765d00c1c9e013bdccda5f07d56e..2dd0a5795c73ca28512fbe1c8ad727052da99558 100644
--- a/cmd-line-utils/libedit/chared.h
+++ b/cmd-line-utils/libedit/chared.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: chared.h,v 1.11 2002/11/20 16:50:08 christos Exp $	*/
+/*	$NetBSD: chared.h,v 1.14 2004/08/13 12:10:39 mycroft Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -66,8 +62,8 @@
 
 typedef struct c_macro_t {
 	int	  level;
+	int	  offset;
 	char	**macro;
-	char	 *nline;
 } c_macro_t;
 
 /*
@@ -158,7 +154,9 @@ protected char	*c__next_word(char *, char *, int, int (*)(int));
 protected char	*c__prev_word(char *, char *, int, int (*)(int));
 protected void	 c_insert(EditLine *, int);
 protected void	 c_delbefore(EditLine *, int);
+protected void	 c_delbefore1(EditLine *);
 protected void	 c_delafter(EditLine *, int);
+protected void	 c_delafter1(EditLine *);
 protected int	 c_gets(EditLine *, char *, const char *);
 protected int	 c_hpos(EditLine *);
 
diff --git a/cmd-line-utils/libedit/common.c b/cmd-line-utils/libedit/common.c
index f290057568a92fea45ee86b8e3a6c7e75df9739c..81bf9bf29ffb7c8864183d8293f2e6b7b721b884 100644
--- a/cmd-line-utils/libedit/common.c
+++ b/cmd-line-utils/libedit/common.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: common.c,v 1.14 2002/11/20 16:50:08 christos Exp $	*/
+/*	$NetBSD: common.c,v 1.16 2003/08/07 16:44:30 agc Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,14 +32,7 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)common.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: common.c,v 1.14 2002/11/20 16:50:08 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * common.c: Common Editor functions
@@ -56,7 +45,7 @@ __RCSID("$NetBSD: common.c,v 1.14 2002/11/20 16:50:08 christos Exp $");
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_end_of_file(EditLine *el, int c __attribute__((unused)))
+ed_end_of_file(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	re_goto_bottom(el);
@@ -113,7 +102,7 @@ ed_insert(EditLine *el, int c)
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_delete_prev_word(EditLine *el, int c __attribute__((unused)))
+ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *cp, *p, *kp;
 
@@ -141,7 +130,7 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_delete_next_char(EditLine *el, int c __attribute__((unused)))
+ed_delete_next_char(EditLine *el, int c __attribute__((__unused__)))
 {
 #ifdef notdef			/* XXX */
 #define	EL	el->el_line
@@ -192,7 +181,7 @@ ed_delete_next_char(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_kill_line(EditLine *el, int c __attribute__((unused)))
+ed_kill_line(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *kp, *cp;
 
@@ -213,7 +202,7 @@ ed_kill_line(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_move_to_end(EditLine *el, int c __attribute__((unused)))
+ed_move_to_end(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_line.cursor = el->el_line.lastchar;
@@ -236,7 +225,7 @@ ed_move_to_end(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_move_to_beg(EditLine *el, int c __attribute__((unused)))
+ed_move_to_beg(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_line.cursor = el->el_line.buffer;
@@ -285,7 +274,7 @@ ed_transpose_chars(EditLine *el, int c)
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_next_char(EditLine *el, int c __attribute__((unused)))
+ed_next_char(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *lim = el->el_line.lastchar;
 
@@ -314,7 +303,7 @@ ed_next_char(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_prev_word(EditLine *el, int c __attribute__((unused)))
+ed_prev_word(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_line.cursor == el->el_line.buffer)
@@ -340,7 +329,7 @@ ed_prev_word(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_prev_char(EditLine *el, int c __attribute__((unused)))
+ed_prev_char(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_line.cursor > el->el_line.buffer) {
@@ -437,8 +426,7 @@ ed_argument_digit(EditLine *el, int c)
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_unassigned(EditLine *el __attribute__((unused)), 
-	      int c __attribute__((unused)))
+ed_unassigned(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	return (CC_ERROR);
@@ -455,8 +443,8 @@ ed_unassigned(EditLine *el __attribute__((unused)),
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_tty_sigint(EditLine *el __attribute__((unused)), 
-	      int c __attribute__((unused)))
+ed_tty_sigint(EditLine *el __attribute__((__unused__)), 
+	      int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -469,8 +457,8 @@ ed_tty_sigint(EditLine *el __attribute__((unused)),
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_tty_dsusp(EditLine *el __attribute__((unused)),
-	     int c __attribute__((unused)))
+ed_tty_dsusp(EditLine *el __attribute__((__unused__)), 
+	     int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -483,8 +471,8 @@ ed_tty_dsusp(EditLine *el __attribute__((unused)),
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_tty_flush_output(EditLine *el __attribute__((unused)),
-		    int c __attribute__((unused)))
+ed_tty_flush_output(EditLine *el __attribute__((__unused__)), 
+		    int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -497,8 +485,8 @@ ed_tty_flush_output(EditLine *el __attribute__((unused)),
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_tty_sigquit(EditLine *el __attribute__((unused)),
-	       int c __attribute__((unused)))
+ed_tty_sigquit(EditLine *el __attribute__((__unused__)), 
+	       int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -511,8 +499,8 @@ ed_tty_sigquit(EditLine *el __attribute__((unused)),
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_tty_sigtstp(EditLine *el __attribute__((unused)),
-	       int c __attribute__((unused)))
+ed_tty_sigtstp(EditLine *el __attribute__((__unused__)), 
+	       int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -525,8 +513,8 @@ ed_tty_sigtstp(EditLine *el __attribute__((unused)),
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_tty_stop_output(EditLine *el __attribute__((unused)),
-		   int c __attribute__((unused)))
+ed_tty_stop_output(EditLine *el __attribute__((__unused__)), 
+		   int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -539,8 +527,8 @@ ed_tty_stop_output(EditLine *el __attribute__((unused)),
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_tty_start_output(EditLine *el __attribute__((unused)),
-		    int c __attribute__((unused)))
+ed_tty_start_output(EditLine *el __attribute__((__unused__)), 
+		    int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -553,7 +541,7 @@ ed_tty_start_output(EditLine *el __attribute__((unused)),
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_newline(EditLine *el, int c __attribute__((unused)))
+ed_newline(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	re_goto_bottom(el);
@@ -569,7 +557,7 @@ ed_newline(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_delete_prev_char(EditLine *el, int c __attribute__((unused)))
+ed_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_line.cursor <= el->el_line.buffer)
@@ -589,7 +577,7 @@ ed_delete_prev_char(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_clear_screen(EditLine *el, int c __attribute__((unused)))
+ed_clear_screen(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	term_clear_screen(el);	/* clear the whole real screen */
@@ -604,8 +592,8 @@ ed_clear_screen(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_redisplay(EditLine *el __attribute__((unused)),
-	     int c __attribute__((unused)))
+ed_redisplay(EditLine *el __attribute__((__unused__)), 
+	     int c __attribute__((__unused__)))
 {
 
 	return (CC_REDISPLAY);
@@ -618,7 +606,7 @@ ed_redisplay(EditLine *el __attribute__((unused)),
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_start_over(EditLine *el, int c __attribute__((unused)))
+ed_start_over(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	ch_reset(el);
@@ -632,8 +620,8 @@ ed_start_over(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_sequence_lead_in(EditLine *el __attribute__((unused)),
-		    int c __attribute__((unused)))
+ed_sequence_lead_in(EditLine *el __attribute__((__unused__)), 
+		    int c __attribute__((__unused__)))
 {
 
 	return (CC_NORM);
@@ -646,7 +634,7 @@ ed_sequence_lead_in(EditLine *el __attribute__((unused)),
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_prev_history(EditLine *el, int c __attribute__((unused)))
+ed_prev_history(EditLine *el, int c __attribute__((__unused__)))
 {
 	char beep = 0;
 	int sv_event = el->el_history.eventno;
@@ -684,7 +672,7 @@ ed_prev_history(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_next_history(EditLine *el, int c __attribute__((unused)))
+ed_next_history(EditLine *el, int c __attribute__((__unused__)))
 {
 	el_action_t beep = CC_REFRESH, rval;
 
@@ -711,7 +699,7 @@ ed_next_history(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_search_prev_history(EditLine *el, int c __attribute__((unused)))
+ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
 {
 	const char *hp;
 	int h;
@@ -779,7 +767,7 @@ ed_search_prev_history(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_search_next_history(EditLine *el, int c __attribute__((unused)))
+ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
 {
 	const char *hp;
 	int h;
@@ -833,7 +821,7 @@ ed_search_next_history(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_prev_line(EditLine *el, int c __attribute__((unused)))
+ed_prev_line(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *ptr;
 	int nchars = c_hpos(el);
@@ -876,7 +864,7 @@ ed_prev_line(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_next_line(EditLine *el, int c __attribute__((unused)))
+ed_next_line(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *ptr;
 	int nchars = c_hpos(el);
@@ -910,7 +898,7 @@ ed_next_line(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-ed_command(EditLine *el, int c __attribute__((unused)))
+ed_command(EditLine *el, int c __attribute__((__unused__)))
 {
 	char tmpbuf[EL_BUFSIZ];
 	int tmplen;
diff --git a/cmd-line-utils/libedit/el.c b/cmd-line-utils/libedit/el.c
index 1b445d40f1c8b310c30036fdf16d7daf188da9e5..c32a01b215153eacb321326c2f99cdd7c0efd936 100644
--- a/cmd-line-utils/libedit/el.c
+++ b/cmd-line-utils/libedit/el.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: el.c,v 1.30 2002/11/12 00:00:23 thorpej Exp $	*/
+/*	$NetBSD: el.c,v 1.39 2004/07/08 00:51:36 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,14 +32,7 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)el.c	8.2 (Berkeley) 1/3/94";
-#else
-__RCSID("$NetBSD: el.c,v 1.30 2002/11/12 00:00:23 thorpej Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * el.c: EditLine interface functions
@@ -72,7 +61,10 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
 	el->el_infd = fileno(fin);
 	el->el_outfile = fout;
 	el->el_errfile = ferr;
-	el->el_prog = strdup(prog);
+	if ((el->el_prog = el_strdup(prog)) == NULL) {
+		el_free(el);
+		return NULL;
+	}
 
 	/*
          * Initialize all the modules. Order is important!!!
@@ -80,11 +72,11 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
 	el->el_flags = 0;
 
 	if (term_init(el) == -1) {
-		free(el->el_prog);
+		el_free(el->el_prog);
 		el_free(el);
 		return NULL;
 	}
-	(void) el_key_init(el);
+	(void) key_init(el);
 	(void) map_init(el);
 	if (tty_init(el) == -1)
 		el->el_flags |= NO_TTY;
@@ -112,7 +104,7 @@ el_end(EditLine *el)
 	el_reset(el);
 
 	term_end(el);
-	el_key_end(el);
+	key_end(el);
 	map_end(el);
 	tty_end(el);
 	ch_end(el);
@@ -257,6 +249,27 @@ el_set(EditLine *el, int op, ...)
 		el->el_data = va_arg(va, void *);
 		break;
 
+	case EL_UNBUFFERED:
+		rv = va_arg(va, int);
+		if (rv && !(el->el_flags & UNBUFFERED)) {
+			el->el_flags |= UNBUFFERED;
+			read_prepare(el);
+		} else if (!rv && (el->el_flags & UNBUFFERED)) {
+			el->el_flags &= ~UNBUFFERED;
+			read_finish(el);
+		}
+		rv = 0;
+		break;
+
+	case EL_PREP_TERM:
+		rv = va_arg(va, int);
+		if (rv)
+			(void) tty_rawmode(el);
+		else
+			(void) tty_cookedmode(el);
+		rv = 0;
+		break;
+
 	default:
 		rv = -1;
 		break;
@@ -297,21 +310,22 @@ el_get(EditLine *el, int op, void *ret)
 		rv = 0;
 		break;
 
-#if 0				/* XXX */
 	case EL_TERMINAL:
-		rv = term_get(el, (const char *) &ret);
+		term_get(el, (const char **)ret);
+		rv = 0;
 		break;
 
+#if 0				/* XXX */
 	case EL_BIND:
 	case EL_TELLTC:
 	case EL_SETTC:
 	case EL_ECHOTC:
 	case EL_SETTY:
 	{
-		char *argv[20];
+		const char *argv[20];
 		int i;
 
-		for (i = 1; i < 20; i++)
+ 		for (i = 1; i < sizeof(argv) / sizeof(argv[0]); i++)
 			if ((argv[i] = va_arg(va, char *)) == NULL)
 				break;
 
@@ -378,6 +392,11 @@ el_get(EditLine *el, int op, void *ret)
 		rv = 0;
 		break;
 
+	case EL_UNBUFFERED:
+		*((int *) ret) = (!(el->el_flags & UNBUFFERED));
+		rv = 0;
+		break;
+
 	default:
 		rv = -1;
 	}
@@ -409,12 +428,17 @@ el_source(EditLine *el, const char *fname)
 
 	fp = NULL;
 	if (fname == NULL) {
-#ifdef HAVE_ISSETUGID
 		static const char elpath[] = "/.editrc";
+#ifdef MAXPATHLEN
 		char path[MAXPATHLEN];
+#else
+		char path[4096];
+#endif
 
+#ifdef HAVE_ISSETUGID
 		if (issetugid())
 			return (-1);
+#endif
 		if ((ptr = getenv("HOME")) == NULL)
 			return (-1);
 		if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))
@@ -422,14 +446,6 @@ el_source(EditLine *el, const char *fname)
 		if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
 			return (-1);
 		fname = path;
-#else
-		/*
-		 * If issetugid() is missing, always return an error, in order
-		 * to keep from inadvertently opening up the user to a security
-		 * hole.
-		 */
-		return (-1);
-#endif
 	}
 	if (fp == NULL)
 		fp = fopen(fname, "r");
@@ -496,10 +512,13 @@ el_editmode(EditLine *el, int argc, const char **argv)
 		return (-1);
 
 	how = argv[1];
-	if (strcmp(how, "on") == 0)
+	if (strcmp(how, "on") == 0) {
 		el->el_flags &= ~EDIT_DISABLED;
-	else if (strcmp(how, "off") == 0)
+		tty_rawmode(el);
+	} else if (strcmp(how, "off") == 0) {
+		tty_cookedmode(el);
 		el->el_flags |= EDIT_DISABLED;
+	}
 	else {
 		(void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how);
 		return (-1);
diff --git a/cmd-line-utils/libedit/el.h b/cmd-line-utils/libedit/el.h
index 49bd462ad3bceba7ca11bc2dbbfd21723d74a1cf..c4b6cff218684088004f72ed4813f0d22e784045 100644
--- a/cmd-line-utils/libedit/el.h
+++ b/cmd-line-utils/libedit/el.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: el.h,v 1.13 2002/11/15 14:32:33 christos Exp $	*/
+/*	$NetBSD: el.h,v 1.16 2003/10/18 23:48:42 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -55,9 +51,10 @@
 
 #define	EL_BUFSIZ	1024		/* Maximum line size		*/
 
-#define	HANDLE_SIGNALS	1<<0
-#define	NO_TTY		1<<1
-#define	EDIT_DISABLED	1<<2
+#define	HANDLE_SIGNALS	0x01
+#define	NO_TTY		0x02
+#define	EDIT_DISABLED	0x04
+#define	UNBUFFERED	0x08
 
 typedef int bool_t;			/* True or not			*/
 
@@ -91,6 +88,7 @@ typedef struct el_state_t {
 /*
  * Until we come up with something better...
  */
+#define	el_strdup(a)	strdup(a)
 #define	el_malloc(a)	malloc(a)
 #define	el_realloc(a,b)	realloc(a, b)
 #define	el_free(a)	free(a)
@@ -98,7 +96,7 @@ typedef struct el_state_t {
 #include "tty.h"
 #include "prompt.h"
 #include "key.h"
-#include "libedit_term.h"
+#include "el_term.h"
 #include "refresh.h"
 #include "chared.h"
 #include "common.h"
diff --git a/cmd-line-utils/libedit/el_term.h b/cmd-line-utils/libedit/el_term.h
new file mode 100644
index 0000000000000000000000000000000000000000..9e5588ee96f29d09c963ffbc4e61589dfc67dcf9
--- /dev/null
+++ b/cmd-line-utils/libedit/el_term.h
@@ -0,0 +1,131 @@
+/*	$NetBSD: term.h,v 1.15 2003/09/14 21:48:55 christos Exp $	*/
+
+/*-
+ * Copyright (c) 1992, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Christos Zoulas of Cornell University.
+ *
+ * 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. 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.
+ *
+ *	@(#)term.h	8.1 (Berkeley) 6/4/93
+ */
+
+/*
+ * el.term.h: Termcap header
+ */
+#ifndef _h_el_term
+#define	_h_el_term
+
+#include "histedit.h"
+
+typedef struct {		/* Symbolic function key bindings	*/
+	const char	*name;	/* name of the key			*/
+	int		 key;	/* Index in termcap table		*/
+	key_value_t	 fun;	/* Function bound to it			*/
+	int		 type;	/* Type of function			*/
+} fkey_t;
+
+typedef struct {
+	const char *t_name;		/* the terminal name	*/
+	coord_t	  t_size;		/* # lines and cols	*/
+	int	  t_flags;
+#define	TERM_CAN_INSERT		0x001	/* Has insert cap	*/
+#define	TERM_CAN_DELETE		0x002	/* Has delete cap	*/
+#define	TERM_CAN_CEOL		0x004	/* Has CEOL cap		*/
+#define	TERM_CAN_TAB		0x008	/* Can use tabs		*/
+#define	TERM_CAN_ME		0x010	/* Can turn all attrs.	*/
+#define	TERM_CAN_UP		0x020	/* Can move up		*/
+#define	TERM_HAS_META		0x040	/* Has a meta key	*/
+#define	TERM_HAS_AUTO_MARGINS	0x080	/* Has auto margins	*/
+#define	TERM_HAS_MAGIC_MARGINS	0x100	/* Has magic margins	*/
+	char	 *t_buf;		/* Termcap buffer	*/
+	int	  t_loc;		/* location used	*/
+	char	**t_str;		/* termcap strings	*/
+	int	 *t_val;		/* termcap values	*/
+	char	 *t_cap;		/* Termcap buffer	*/
+	fkey_t	 *t_fkey;		/* Array of keys	*/
+} el_term_t;
+
+/*
+ * fKey indexes
+ */
+#define	A_K_DN		0
+#define	A_K_UP		1
+#define	A_K_LT		2
+#define	A_K_RT		3
+#define	A_K_HO		4
+#define	A_K_EN		5
+#define	A_K_NKEYS	6
+
+#ifdef _SUNOS
+extern int tgetent(char *, const char *);
+extern int tgetflag(char *);
+extern int tgetnum(char *);
+extern int tputs(const char *, int, int (*)(int));
+extern char* tgoto(const char*, int, int);
+extern char* tgetstr(char*, char**);
+#endif
+
+protected void	term_move_to_line(EditLine *, int);
+protected void	term_move_to_char(EditLine *, int);
+protected void	term_clear_EOL(EditLine *, int);
+protected void	term_overwrite(EditLine *, const char *, int);
+protected void	term_insertwrite(EditLine *, char *, int);
+protected void	term_deletechars(EditLine *, int);
+protected void	term_clear_screen(EditLine *);
+protected void	term_beep(EditLine *);
+protected int	term_change_size(EditLine *, int, int);
+protected int	term_get_size(EditLine *, int *, int *);
+protected int	term_init(EditLine *);
+protected void	term_bind_arrow(EditLine *);
+protected void	term_print_arrow(EditLine *, const char *);
+protected int	term_clear_arrow(EditLine *, const char *);
+protected int	term_set_arrow(EditLine *, const char *, key_value_t *, int);
+protected void	term_end(EditLine *);
+protected void	term_get(EditLine *, const char **);
+protected int	term_set(EditLine *, const char *);
+protected int	term_settc(EditLine *, int, const char **);
+protected int	term_telltc(EditLine *, int, const char **);
+protected int	term_echotc(EditLine *, int, const char **);
+protected int	term__putc(int);
+protected void	term__flush(void);
+
+/*
+ * Easy access macros
+ */
+#define	EL_FLAGS	(el)->el_term.t_flags
+
+#define	EL_CAN_INSERT		(EL_FLAGS & TERM_CAN_INSERT)
+#define	EL_CAN_DELETE		(EL_FLAGS & TERM_CAN_DELETE)
+#define	EL_CAN_CEOL		(EL_FLAGS & TERM_CAN_CEOL)
+#define	EL_CAN_TAB		(EL_FLAGS & TERM_CAN_TAB)
+#define	EL_CAN_ME		(EL_FLAGS & TERM_CAN_ME)
+#define	EL_HAS_META		(EL_FLAGS & TERM_HAS_META)
+#define	EL_HAS_AUTO_MARGINS	(EL_FLAGS & TERM_HAS_AUTO_MARGINS)
+#define	EL_HAS_MAGIC_MARGINS	(EL_FLAGS & TERM_HAS_MAGIC_MARGINS)
+
+#endif /* _h_el_term */
diff --git a/cmd-line-utils/libedit/emacs.c b/cmd-line-utils/libedit/emacs.c
index d58d162069325bcf883fff498da16a0c17b5bdff..79f2bf0c8180f517dc31d7ba92dd42ec357a5580 100644
--- a/cmd-line-utils/libedit/emacs.c
+++ b/cmd-line-utils/libedit/emacs.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: emacs.c,v 1.12 2002/11/15 14:32:33 christos Exp $	*/
+/*	$NetBSD: emacs.c,v 1.19 2004/10/28 21:14:52 dsl Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,14 +32,7 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)emacs.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: emacs.c,v 1.12 2002/11/15 14:32:33 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * emacs.c: Emacs functions
@@ -56,7 +45,7 @@ __RCSID("$NetBSD: emacs.c,v 1.12 2002/11/15 14:32:33 christos Exp $");
  */
 protected el_action_t
 /*ARGSUSED*/
-em_delete_or_list(EditLine *el, int c __attribute__((unused)))
+em_delete_or_list(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_line.cursor == el->el_line.lastchar) {
@@ -75,7 +64,10 @@ em_delete_or_list(EditLine *el, int c __attribute__((unused)))
 			return (CC_ERROR);
 		}
 	} else {
-		c_delafter(el, el->el_state.argument);	/* delete after dot */
+		if (el->el_state.doingarg)
+			c_delafter(el, el->el_state.argument);
+		else
+			c_delafter1(el);
 		if (el->el_line.cursor > el->el_line.lastchar)
 			el->el_line.cursor = el->el_line.lastchar;
 				/* bounds check */
@@ -90,7 +82,7 @@ em_delete_or_list(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_delete_next_word(EditLine *el, int c __attribute__((unused)))
+em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *cp, *p, *kp;
 
@@ -119,14 +111,12 @@ em_delete_next_word(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_yank(EditLine *el, int c __attribute__((unused)))
+em_yank(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *kp, *cp;
 
-	if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) {
-		if (!ch_enlargebufs(el, 1))
-			return (CC_ERROR);
-	}
+	if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
+		return (CC_NORM);
 
 	if (el->el_line.lastchar +
 	    (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
@@ -156,7 +146,7 @@ em_yank(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_kill_line(EditLine *el, int c __attribute__((unused)))
+em_kill_line(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *kp, *cp;
 
@@ -178,7 +168,7 @@ em_kill_line(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_kill_region(EditLine *el, int c __attribute__((unused)))
+em_kill_region(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *kp, *cp;
 
@@ -211,7 +201,7 @@ em_kill_region(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_copy_region(EditLine *el, int c __attribute__((unused)))
+em_copy_region(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *kp, *cp;
 
@@ -235,12 +225,12 @@ em_copy_region(EditLine *el, int c __attribute__((unused)))
 }
 
 
-/* em_gosmacs_traspose():
+/* em_gosmacs_transpose():
  *	Exchange the two characters before the cursor
  *	Gosling emacs transpose chars [^T]
  */
 protected el_action_t
-em_gosmacs_traspose(EditLine *el, int c)
+em_gosmacs_transpose(EditLine *el, int c)
 {
 
 	if (el->el_line.cursor > &el->el_line.buffer[1]) {
@@ -260,7 +250,7 @@ em_gosmacs_traspose(EditLine *el, int c)
  */
 protected el_action_t
 /*ARGSUSED*/
-em_next_word(EditLine *el, int c __attribute__((unused)))
+em_next_word(EditLine *el, int c __attribute__((__unused__)))
 {
 	if (el->el_line.cursor == el->el_line.lastchar)
 		return (CC_ERROR);
@@ -285,7 +275,7 @@ em_next_word(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_upper_case(EditLine *el, int c __attribute__((unused)))
+em_upper_case(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *cp, *ep;
 
@@ -293,8 +283,8 @@ em_upper_case(EditLine *el, int c __attribute__((unused)))
 	    el->el_state.argument, ce__isword);
 
 	for (cp = el->el_line.cursor; cp < ep; cp++)
-		if (islower((unsigned char) *cp))
-			*cp = toupper(*cp);
+		if (islower((unsigned char)*cp))
+			*cp = toupper((unsigned char)*cp);
 
 	el->el_line.cursor = ep;
 	if (el->el_line.cursor > el->el_line.lastchar)
@@ -309,7 +299,7 @@ em_upper_case(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_capitol_case(EditLine *el, int c __attribute__((unused)))
+em_capitol_case(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *cp, *ep;
 
@@ -317,16 +307,16 @@ em_capitol_case(EditLine *el, int c __attribute__((unused)))
 	    el->el_state.argument, ce__isword);
 
 	for (cp = el->el_line.cursor; cp < ep; cp++) {
-		if (isalpha((unsigned char) *cp)) {
-			if (islower((unsigned char) *cp))
-				*cp = toupper(*cp);
+		if (isalpha((unsigned char)*cp)) {
+			if (islower((unsigned char)*cp))
+				*cp = toupper((unsigned char)*cp);
 			cp++;
 			break;
 		}
 	}
 	for (; cp < ep; cp++)
-		if (isupper((unsigned char) *cp))
-			*cp = tolower(*cp);
+		if (isupper((unsigned char)*cp))
+			*cp = tolower((unsigned char)*cp);
 
 	el->el_line.cursor = ep;
 	if (el->el_line.cursor > el->el_line.lastchar)
@@ -341,7 +331,7 @@ em_capitol_case(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_lower_case(EditLine *el, int c __attribute__((unused)))
+em_lower_case(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *cp, *ep;
 
@@ -349,8 +339,8 @@ em_lower_case(EditLine *el, int c __attribute__((unused)))
 	    el->el_state.argument, ce__isword);
 
 	for (cp = el->el_line.cursor; cp < ep; cp++)
-		if (isupper((unsigned char) *cp))
-			*cp = tolower(*cp);
+		if (isupper((unsigned char)*cp))
+			*cp = tolower((unsigned char)*cp);
 
 	el->el_line.cursor = ep;
 	if (el->el_line.cursor > el->el_line.lastchar)
@@ -365,7 +355,7 @@ em_lower_case(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_set_mark(EditLine *el, int c __attribute__((unused)))
+em_set_mark(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_chared.c_kill.mark = el->el_line.cursor;
@@ -379,7 +369,7 @@ em_set_mark(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_exchange_mark(EditLine *el, int c __attribute__((unused)))
+em_exchange_mark(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *cp;
 
@@ -396,7 +386,7 @@ em_exchange_mark(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_universal_argument(EditLine *el, int c __attribute__((unused)))
+em_universal_argument(EditLine *el, int c __attribute__((__unused__)))
 {				/* multiply current argument by 4 */
 
 	if (el->el_state.argument > 1000000)
@@ -413,7 +403,7 @@ em_universal_argument(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_meta_next(EditLine *el, int c __attribute__((unused)))
+em_meta_next(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_state.metanext = 1;
@@ -426,7 +416,7 @@ em_meta_next(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_toggle_overwrite(EditLine *el, int c __attribute__((unused)))
+em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
@@ -440,7 +430,7 @@ em_toggle_overwrite(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_copy_prev_word(EditLine *el, int c __attribute__((unused)))
+em_copy_prev_word(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *cp, *oldc, *dp;
 
@@ -467,7 +457,7 @@ em_copy_prev_word(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_inc_search_next(EditLine *el, int c __attribute__((unused)))
+em_inc_search_next(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_search.patlen = 0;
@@ -480,9 +470,32 @@ em_inc_search_next(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-em_inc_search_prev(EditLine *el, int c __attribute__((unused)))
+em_inc_search_prev(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_search.patlen = 0;
 	return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
 }
+
+
+/* em_delete_prev_char():
+ *	Delete the character to the left of the cursor
+ *	[^?]
+ */
+protected el_action_t
+/*ARGSUSED*/
+em_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
+{
+
+	if (el->el_line.cursor <= el->el_line.buffer)
+		return (CC_ERROR);
+
+	if (el->el_state.doingarg)
+		c_delbefore(el, el->el_state.argument);
+	else
+		c_delbefore1(el);
+	el->el_line.cursor -= el->el_state.argument;
+	if (el->el_line.cursor < el->el_line.buffer)
+		el->el_line.cursor = el->el_line.buffer;
+	return (CC_REFRESH);
+}
diff --git a/cmd-line-utils/libedit/fgetln.c b/cmd-line-utils/libedit/fgetln.c
index 4f7416a4c8da174e014f1991f0dd32fec1971b48..5b95b2f6584cd7d13e034f122661a7a9e3782b06 100644
--- a/cmd-line-utils/libedit/fgetln.c
+++ b/cmd-line-utils/libedit/fgetln.c
@@ -1,109 +1,88 @@
+/*	$NetBSD: fgetln.c,v 1.2 2003/12/10 01:30:27 lukem Exp $	*/
+
+/*-
+ * Copyright (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Christos Zoulas.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#include <config.h>
 #include <stdio.h>
-#include "compat.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
 
-#ifndef HAVE_FGETLN
 
-#ifdef HAVE_GETLINE
-
-extern int getline (char **lineptr, size_t *n, FILE *stream);
-
-#else
-
-/* The interface here is that of GNU libc's getline */
-static int
-getline (char **lineptr, size_t *n, FILE *stream)
+char *
+fgetln(FILE *fp, size_t *len)
 {
-#define EXPAND_CHUNK 16
-
-  int n_read = 0;
-  char *line = *lineptr;
-
-  if (lineptr == NULL) return -1;
-  if (n == NULL) return -1;
-  if (stream == NULL) return -1;
-  if (*lineptr == NULL || *n == 0) return -1;
-  
-#ifdef HAVE_FLOCKFILE
-  flockfile (stream);
-#endif  
-  
-  while (1)
-    {
-      int c;
-      
-#ifdef HAVE_FLOCKFILE
-      c = getc_unlocked (stream);
-#else
-      c = getc (stream);
-#endif      
-
-      if (c == EOF)
-        {
-          if (n_read > 0)
-	    line[n_read] = '\0';
-          break;
-        }
-
-      if (n_read + 2 >= *n)
-        {
-	  size_t new_size;
-
-	  if (*n == 0)
-	    new_size = 16;
-	  else
-	    new_size = *n * 2;
-
-	  if (*n >= new_size)    /* Overflowed size_t */
-	    line = NULL;
-	  else
-	    line = (char *) (*lineptr ? (char*) realloc(*lineptr, new_size) :
-			     (char*) malloc(new_size));
-
-	  if (line)
-	    {
-	      *lineptr = line;
-	      *n = new_size;
-	    }
-	  else
-	    {
-	      if (*n > 0)
-		{
-		  (*lineptr)[*n - 1] = '\0';
-		  n_read = *n - 2;
-		}
-	      break;
-	    }
-        }
-
-      line[n_read] = c;
-      n_read++;
-
-      if (c == '\n')
-        {
-          line[n_read] = '\0';
-          break;
-        }
-    }
-
-#ifdef HAVE_FLOCKFILE
-  funlockfile (stream);
-#endif
-
-  return n_read - 1;
+	static char *buf = NULL;
+	static size_t bufsiz = 0;
+	char *ptr;
+
+
+	if (buf == NULL) {
+		bufsiz = BUFSIZ;
+		if ((buf = malloc(bufsiz)) == NULL)
+			return NULL;
+	}
+
+	if (fgets(buf, bufsiz, fp) == NULL)
+		return NULL;
+	*len = 0;
+
+	while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
+		size_t nbufsiz = bufsiz + BUFSIZ;
+		char *nbuf = realloc(buf, nbufsiz);
+
+		if (nbuf == NULL) {
+			int oerrno = errno;
+			free(buf);
+			errno = oerrno;
+			buf = NULL;
+			return NULL;
+		} else
+			buf = nbuf;
+
+		*len = bufsiz;
+		if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL)
+			return buf;
+
+		bufsiz = nbufsiz;
+	}
+
+	*len = (ptr - buf) + 1;
+	return buf;
 }
-#endif /* ! HAVE_GETLINE */
 
-char *fgetln(FILE *stream, size_t *len)
-{
-  char *ptr = NULL;
-  int sz;
-  size_t length= 0;
-
-  sz = getline(&ptr,  &length, stream);
-  if(len) {
-    *len = sz;
-  }
-
-  return sz >= 0 ? ptr : NULL;
-}
-#endif
diff --git a/cmd-line-utils/libedit/hist.c b/cmd-line-utils/libedit/hist.c
index 59c2f39dd349d82fdab9e05192c7c531ef89b5f4..e8f5c0f39bad0ac00929cb09b94a3b010bd9cc59 100644
--- a/cmd-line-utils/libedit/hist.c
+++ b/cmd-line-utils/libedit/hist.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: hist.c,v 1.12 2003/01/21 18:40:23 christos Exp $	*/
+/*	$NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,14 +32,7 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)hist.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: hist.c,v 1.12 2003/01/21 18:40:23 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * hist.c: History access functions
@@ -157,7 +146,6 @@ hist_get(EditLine *el)
  *	process a history command
  */
 protected int
-/*ARGSUSED*/
 hist_command(EditLine *el, int argc, const char **argv)
 {
 	const char *str;
@@ -167,7 +155,7 @@ hist_command(EditLine *el, int argc, const char **argv)
 	if (el->el_history.ref == NULL)
 		return (-1);
 
-	if (argc == 0 || strcmp(argv[0], "list") == 1) {
+	if (argc == 1 || strcmp(argv[1], "list") == 0) {
 		 /* List history entries */
 
 		for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
@@ -176,15 +164,15 @@ hist_command(EditLine *el, int argc, const char **argv)
 		return (0);
 	}
 
-	if (argc != 2)
+	if (argc != 3)
 		return (-1);
 
-	num = (int)strtol(argv[1], NULL, 0);
+	num = (int)strtol(argv[2], NULL, 0);
 
-	if (strcmp(argv[0], "size") == 0)
+	if (strcmp(argv[1], "size") == 0)
 		return history(el->el_history.ref, &ev, H_SETSIZE, num);
 
-	if (strcmp(argv[0], "unique") == 0)
+	if (strcmp(argv[1], "unique") == 0)
 		return history(el->el_history.ref, &ev, H_SETUNIQUE, num);
 
 	return -1;
diff --git a/cmd-line-utils/libedit/hist.h b/cmd-line-utils/libedit/hist.h
index b713281b382d916a7b44bbb9586b9b24269452b0..46e14634adf807bb285b1a584b1b030b399620b4 100644
--- a/cmd-line-utils/libedit/hist.h
+++ b/cmd-line-utils/libedit/hist.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: hist.h,v 1.9 2003/01/21 18:40:23 christos Exp $	*/
+/*	$NetBSD: hist.h,v 1.10 2003/08/07 16:44:31 agc Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
diff --git a/cmd-line-utils/libedit/histedit.h b/cmd-line-utils/libedit/histedit.h
index 3137bd680a7c6884a9f65507ce300aecc75488f2..c58eb62dcfab3df062394bd024c639fa2a7d1583 100644
--- a/cmd-line-utils/libedit/histedit.h
+++ b/cmd-line-utils/libedit/histedit.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: histedit.h,v 1.21 2003/01/21 18:40:24 christos Exp $	*/
+/*	$NetBSD: histedit.h,v 1.25 2003/12/05 13:37:48 lukem Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -45,7 +41,7 @@
 #define	_HISTEDIT_H_
 
 #define	LIBEDIT_MAJOR 2
-#define	LIBEDIT_MINOR 6
+#define	LIBEDIT_MINOR 9
 
 #include <sys/types.h>
 #include <stdio.h>
@@ -53,6 +49,7 @@
 /*
  * ==== Editing ====
  */
+
 typedef struct editline EditLine;
 
 /*
@@ -64,7 +61,6 @@ typedef struct lineinfo {
 	const char	*lastchar;
 } LineInfo;
 
-
 /*
  * EditLine editor function return codes.
  * For user-defined function interface
@@ -84,9 +80,8 @@ typedef struct lineinfo {
  * Initialization, cleanup, and resetting
  */
 EditLine	*el_init(const char *, FILE *, FILE *, FILE *);
-void		 el_reset(EditLine *);
 void		 el_end(EditLine *);
-
+void		 el_reset(EditLine *);
 
 /*
  * Get a line, a character or push a string back in the input queue
@@ -131,6 +126,8 @@ int		 el_get(EditLine *, int, void *);
 #define	EL_RPROMPT	12	/* , el_pfunc_t);		*/
 #define	EL_GETCFN	13	/* , el_rfunc_t);		*/
 #define	EL_CLIENTDATA	14	/* , void *);			*/
+#define	EL_UNBUFFERED	15	/* , int);			*/
+#define	EL_PREP_TERM    16      /* , int);                      */
 
 #define EL_BUILTIN_GETCFN	(NULL)
 
@@ -146,7 +143,6 @@ int		el_source(EditLine *, const char *);
  */
 void		 el_resize(EditLine *);
 
-
 /*
  * User-defined function interface.
  */
@@ -154,6 +150,7 @@ const LineInfo	*el_line(EditLine *);
 int		 el_insertstr(EditLine *, const char *);
 void		 el_deletestr(EditLine *, int);
 
+
 /*
  * ==== History ====
  */
@@ -196,4 +193,22 @@ int		history(History *, HistEvent *, int, ...);
 #define	H_SETUNIQUE	20	/* , int);		*/
 #define	H_GETUNIQUE	21	/* , void);		*/
 
+
+/*
+ * ==== Tokenization ====
+ */
+
+typedef struct tokenizer Tokenizer;
+
+/*
+ * String tokenization functions, using simplified sh(1) quoting rules
+ */
+Tokenizer	*tok_init(const char *);
+void		 tok_end(Tokenizer *);
+void		 tok_reset(Tokenizer *);
+int		 tok_line(Tokenizer *, const LineInfo *,
+		    int *, const char ***, int *, int *);
+int		 tok_str(Tokenizer *, const char *,
+		    int *, const char ***);
+
 #endif /* _HISTEDIT_H_ */
diff --git a/cmd-line-utils/libedit/history.c b/cmd-line-utils/libedit/history.c
index 53648203bf03cc9e083a1d5a8937019897d99901..1da6a8641810cc16043cb0e5f9efa2a5406361dc 100644
--- a/cmd-line-utils/libedit/history.c
+++ b/cmd-line-utils/libedit/history.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: history.c,v 1.22 2003/01/21 18:40:24 christos Exp $	*/
+/*	$NetBSD: history.c,v 1.28 2004/11/27 18:31:45 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,14 +32,7 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)history.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: history.c,v 1.22 2003/01/21 18:40:24 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * hist.c: History access functions
@@ -51,11 +40,7 @@ __RCSID("$NetBSD: history.c,v 1.22 2003/01/21 18:40:24 christos Exp $");
 #include <string.h>
 #include <stdlib.h>
 #include <stdarg.h>
-#ifdef HAVE_VIS_H
 #include <vis.h>
-#else
-#include "np/vis.h"
-#endif
 #include <sys/stat.h>
 
 static const char hist_cookie[] = "_HiStOrY_V2_\n";
@@ -91,6 +76,7 @@ struct history {
 #define	HENTER(h, ev, str)	(*(h)->h_enter)((h)->h_ref, ev, str)
 #define	HADD(h, ev, str)	(*(h)->h_add)((h)->h_ref, ev, str)
 
+#define	h_strdup(a)	strdup(a)
 #define	h_malloc(a)	malloc(a)
 #define	h_realloc(a, b)	realloc((a), (b))
 #define	h_free(a)	free(a)
@@ -249,20 +235,19 @@ history_def_next(ptr_t p, HistEvent *ev)
 {
 	history_t *h = (history_t *) p;
 
-	if (h->cursor != &h->list)
-		h->cursor = h->cursor->next;
-	else {
+	if (h->cursor == &h->list) {
 		he_seterrev(ev, _HE_EMPTY_LIST);
 		return (-1);
 	}
 
-	if (h->cursor != &h->list)
-		*ev = h->cursor->ev;
-	else {
+	if (h->cursor->next == &h->list) {
 		he_seterrev(ev, _HE_END_REACHED);
 		return (-1);
 	}
 
+        h->cursor = h->cursor->next;
+        *ev = h->cursor->ev;
+
 	return (0);
 }
 
@@ -275,21 +260,20 @@ history_def_prev(ptr_t p, HistEvent *ev)
 {
 	history_t *h = (history_t *) p;
 
-	if (h->cursor != &h->list)
-		h->cursor = h->cursor->prev;
-	else {
+	if (h->cursor == &h->list) {
 		he_seterrev(ev,
 		    (h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST);
 		return (-1);
 	}
 
-	if (h->cursor != &h->list)
-		*ev = h->cursor->ev;
-	else {
+	if (h->cursor->prev == &h->list) {
 		he_seterrev(ev, _HE_START_REACHED);
 		return (-1);
 	}
 
+        h->cursor = h->cursor->prev;
+        *ev = h->cursor->ev;
+
 	return (0);
 }
 
@@ -374,7 +358,8 @@ history_def_add(ptr_t p, HistEvent *ev, const char *str)
  */
 /* ARGSUSED */
 private void
-history_def_delete(history_t *h, HistEvent *ev __attribute__((unused)), hentry_t *hp)
+history_def_delete(history_t *h, 
+		   HistEvent *ev __attribute__((__unused__)), hentry_t *hp)
 {
 	HistEventPrivate *evp = (void *)&hp->ev;
 	if (hp == &h->list)
@@ -397,7 +382,7 @@ history_def_insert(history_t *h, HistEvent *ev, const char *str)
 	h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t));
 	if (h->cursor == NULL)
 		goto oomem;
-	if ((h->cursor->ev.str = strdup(str)) == NULL) {
+	if ((h->cursor->ev.str = h_strdup(str)) == NULL) {
 		h_free((ptr_t)h->cursor);
 		goto oomem;
 	}
@@ -447,7 +432,7 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str)
  */
 /* ARGSUSED */
 private int
-history_def_init(ptr_t *p, HistEvent *ev __attribute__((unused)), int n)
+history_def_init(ptr_t *p, HistEvent *ev __attribute__((__unused__)), int n)
 {
 	history_t *h = (history_t *) h_malloc(sizeof(history_t));
 	if (h == NULL)
@@ -661,6 +646,12 @@ history_load(History *h, const char *fname)
 	if ((fp = fopen(fname, "r")) == NULL)
 		return (i);
 
+	if ((line = fgetln(fp, &sz)) == NULL)
+		goto done;
+
+	if (strncmp(line, hist_cookie, sz) != 0)
+		goto done;
+
 	ptr = h_malloc(max_size = 1024);
 	if (ptr == NULL)
 		goto done;
@@ -674,7 +665,7 @@ history_load(History *h, const char *fname)
 
 		if (max_size < sz) {
 			char *nptr;
-			max_size = (sz + 1023) & ~1023;
+			max_size = (sz + 1024) & ~1023;
 			nptr = h_realloc(ptr, max_size);
 			if (nptr == NULL) {
 				i = -1;
@@ -714,16 +705,18 @@ history_save(History *h, const char *fname)
 
 	if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1)
 		goto done;
+	if (fputs(hist_cookie, fp) == EOF)
+		goto done;
 	ptr = h_malloc(max_size = 1024);
 	if (ptr == NULL)
 		goto done;
 	for (i = 0, retval = HLAST(h, &ev);
 	    retval != -1;
 	    retval = HPREV(h, &ev), i++) {
-		len = strlen(ev.str) * 4 + 1;
+		len = strlen(ev.str) * 4;
 		if (len >= max_size) {
 			char *nptr;
-			max_size = (len + 1023) & ~1023;
+			max_size = (len + 1024) & ~1023;
 			nptr = h_realloc(ptr, max_size);
 			if (nptr == NULL) {
 				i = -1;
@@ -732,7 +725,7 @@ history_save(History *h, const char *fname)
 			ptr = nptr;
 		}
 		(void) strvis(ptr, ev.str, VIS_WHITE);
-		(void) fprintf(fp, "%s\n", ev.str);
+		(void) fprintf(fp, "%s\n", ptr);
 	}
 oomem:
 	h_free((ptr_t)ptr);
diff --git a/cmd-line-utils/libedit/key.c b/cmd-line-utils/libedit/key.c
index e75db00ce1b41645582aabbcbebed563986c38dd..090a2684e929f54a2863ef1e3e718ff1e143dc07 100644
--- a/cmd-line-utils/libedit/key.c
+++ b/cmd-line-utils/libedit/key.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: key.c,v 1.13 2002/03/18 16:00:55 christos Exp $	*/
+/*	$NetBSD: key.c,v 1.15 2003/10/18 23:48:42 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,14 +32,7 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)key.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: key.c,v 1.13 2002/03/18 16:00:55 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * key.c: This module contains the procedures for maintaining
@@ -103,14 +92,14 @@ private int		 key__decode_char(char *, int, int);
  *	Initialize the key maps
  */
 protected int
-el_key_init(EditLine *el)
+key_init(EditLine *el)
 {
 
 	el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ);
 	if (el->el_key.buf == NULL)
 		return (-1);
 	el->el_key.map = NULL;
-	el_key_reset(el);
+	key_reset(el);
 	return (0);
 }
 
@@ -119,7 +108,7 @@ el_key_init(EditLine *el)
  *	Free the key maps
  */
 protected void
-el_key_end(EditLine *el)
+key_end(EditLine *el)
 {
 
 	el_free((ptr_t) el->el_key.buf);
@@ -133,7 +122,7 @@ el_key_end(EditLine *el)
  *	Associate cmd with a key value
  */
 protected key_value_t *
-el_key_map_cmd(EditLine *el, int cmd)
+key_map_cmd(EditLine *el, int cmd)
 {
 
 	el->el_key.val.cmd = (el_action_t) cmd;
@@ -145,7 +134,7 @@ el_key_map_cmd(EditLine *el, int cmd)
  *	Associate str with a key value
  */
 protected key_value_t *
-el_key_map_str(EditLine *el, char *str)
+key_map_str(EditLine *el, char *str)
 {
 
 	el->el_key.val.str = str;
@@ -159,7 +148,7 @@ el_key_map_str(EditLine *el, char *str)
  *	[Always bind the ansi arrow keys?]
  */
 protected void
-el_key_reset(EditLine *el)
+key_reset(EditLine *el)
 {
 
 	node__put(el, el->el_key.map);
@@ -177,7 +166,7 @@ el_key_reset(EditLine *el)
  *      The last character read is returned in *ch.
  */
 protected int
-el_key_get(EditLine *el, char *ch, key_value_t *val)
+key_get(EditLine *el, char *ch, key_value_t *val)
 {
 
 	return (node_trav(el, el->el_key.map, ch, val));
@@ -191,7 +180,7 @@ el_key_get(EditLine *el, char *ch, key_value_t *val)
  *      out str or a unix command.
  */
 protected void
-el_key_add(EditLine *el, const char *key, key_value_t *val, int ntype)
+key_add(EditLine *el, const char *key, key_value_t *val, int ntype)
 {
 
 	if (key[0] == '\0') {
@@ -219,7 +208,7 @@ el_key_add(EditLine *el, const char *key, key_value_t *val, int ntype)
  *
  */
 protected void
-el_key_clear(EditLine *el, el_action_t *map, const char *in)
+key_clear(EditLine *el, el_action_t *map, const char *in)
 {
 
 	if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) &&
@@ -227,7 +216,7 @@ el_key_clear(EditLine *el, el_action_t *map, const char *in)
 	    el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) ||
 	    (map == el->el_map.alt &&
 	    el->el_map.key[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN)))
-		(void) el_key_delete(el, in);
+		(void) key_delete(el, in);
 }
 
 
@@ -236,7 +225,7 @@ el_key_clear(EditLine *el, el_action_t *map, const char *in)
  *      they exists.
  */
 protected int
-el_key_delete(EditLine *el, const char *key)
+key_delete(EditLine *el, const char *key)
 {
 
 	if (key[0] == '\0') {
@@ -257,7 +246,7 @@ el_key_delete(EditLine *el, const char *key)
  *	Print entire el->el_key.map if null
  */
 protected void
-el_key_print(EditLine *el, const char *key)
+key_print(EditLine *el, const char *key)
 {
 
 	/* do nothing if el->el_key.map is empty and null key specified */
@@ -356,7 +345,8 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
 			break;
 		case XK_STR:
 		case XK_EXE:
-			ptr->val.str = strdup(val->str);
+			if ((ptr->val.str = el_strdup(val->str)) == NULL)
+				return -1;
 			break;
 		default:
 			EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype));
@@ -504,7 +494,7 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
 				if (str[1] == 0) {
 					el->el_key.buf[ncnt + 1] = '"';
 					el->el_key.buf[ncnt + 2] = '\0';
-					el_key_kprint(el, el->el_key.buf,
+					key_kprint(el, el->el_key.buf,
 					    &ptr->val, ptr->type);
 					return (0);
 				} else
@@ -552,7 +542,7 @@ node_enum(EditLine *el, key_node_t *ptr, int cnt)
 		/* print this key and function */
 		el->el_key.buf[ncnt + 1] = '"';
 		el->el_key.buf[ncnt + 2] = '\0';
-		el_key_kprint(el, el->el_key.buf, &ptr->val, ptr->type);
+		key_kprint(el, el->el_key.buf, &ptr->val, ptr->type);
 	} else
 		(void) node_enum(el, ptr->next, ncnt + 1);
 
@@ -568,7 +558,7 @@ node_enum(EditLine *el, key_node_t *ptr, int cnt)
  *	function specified by val
  */
 protected void
-el_key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
+key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
 {
 	el_bindings_t *fp;
 	char unparsbuf[EL_BUFSIZ];
@@ -579,7 +569,7 @@ el_key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
 		case XK_STR:
 		case XK_EXE:
 			(void) fprintf(el->el_outfile, fmt, key,
-			    el_key__decode_str(val->str, unparsbuf,
+			    key__decode_str(val->str, unparsbuf,
 				ntype == XK_STR ? "\"\"" : "[]"));
 			break;
 		case XK_CMD:
@@ -644,7 +634,7 @@ key__decode_char(char *buf, int cnt, int ch)
  *	Make a printable version of the ey
  */
 protected char *
-el_key__decode_str(const char *str, char *buf, const char *sep)
+key__decode_str(const char *str, char *buf, const char *sep)
 {
 	char *b;
 	const char *p;
diff --git a/cmd-line-utils/libedit/key.h b/cmd-line-utils/libedit/key.h
index 9d83d7c25219e193a900fcf35b8e5b2dbaa868d1..39a075c504e1eb8245d9f9a71d2f82846c3db72e 100644
--- a/cmd-line-utils/libedit/key.h
+++ b/cmd-line-utils/libedit/key.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: key.h,v 1.6 2002/03/18 16:00:55 christos Exp $	*/
+/*	$NetBSD: key.h,v 1.8 2003/08/07 16:44:32 agc Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -62,19 +58,22 @@ typedef struct el_key_t {
 #define	XK_NOD	2
 #define	XK_EXE	3
 
-protected int		 el_key_init(EditLine *);
-protected void		 el_key_end(EditLine *);
-protected key_value_t	*el_key_map_cmd(EditLine *, int);
-protected key_value_t	*el_key_map_str(EditLine *, char *);
-protected void		 el_key_reset(EditLine *);
-protected int		 el_key_get(EditLine *, char *, key_value_t *);
-protected void		 el_key_add(EditLine *, 
-                                    const char *, key_value_t *, int);
-protected void		 el_key_clear(EditLine *, el_action_t *, const char *);
-protected int		 el_key_delete(EditLine *, const char *);
-protected void		 el_key_print(EditLine *, const char *);
-protected void	         el_key_kprint(EditLine *, const char *, key_value_t *,
+#undef key_end
+#undef key_clear
+#undef key_print
+
+protected int		 key_init(EditLine *);
+protected void		 key_end(EditLine *);
+protected key_value_t	*key_map_cmd(EditLine *, int);
+protected key_value_t	*key_map_str(EditLine *, char *);
+protected void		 key_reset(EditLine *);
+protected int		 key_get(EditLine *, char *, key_value_t *);
+protected void		 key_add(EditLine *, const char *, key_value_t *, int);
+protected void		 key_clear(EditLine *, el_action_t *, const char *);
+protected int		 key_delete(EditLine *, const char *);
+protected void		 key_print(EditLine *, const char *);
+protected void	         key_kprint(EditLine *, const char *, key_value_t *,
     int);
-protected char		*el_key__decode_str(const char *, char *, const char *);
+protected char		*key__decode_str(const char *, char *, const char *);
 
 #endif /* _h_el_key */
diff --git a/cmd-line-utils/libedit/makelist.sh b/cmd-line-utils/libedit/makelist.sh
index b2502d16ed157e5dc027358b22f2ffb650a812f3..502604791f5981cb7d970d056c86b01afb3ea973 100644
--- a/cmd-line-utils/libedit/makelist.sh
+++ b/cmd-line-utils/libedit/makelist.sh
@@ -68,7 +68,7 @@ case $FLAG in
 	/\(\):/ {
 	    pr = substr($2, 1, 2);
 	    if (pr == "vi" || pr == "em" || pr == "ed") {
-		name = substr($2, 1, length($2) - 3);
+		name = substr($2, 1, index($2,"(") - 1);
 #
 # XXX:	need a space between name and prototype so that -fc and -fh
 #	parsing is much easier
@@ -97,7 +97,7 @@ case $FLAG in
 	/\(\):/ {
 	    pr = substr($2, 1, 2);
 	    if (pr == "vi" || pr == "em" || pr == "ed") {
-		name = substr($2, 1, length($2) - 3);
+		name = substr($2, 1, index($2,"(") - 1);
 		uname = "";
 		fname = "";
 		for (i = 1; i <= length(name); i++) {
@@ -117,6 +117,7 @@ case $FLAG in
 		printf("      \"");
 		for (i = 2; i < NF; i++)
 		    printf("%s ", $i);
+                sub("\r", "", $i);
 		printf("%s\" },\n", $i);
 		ok = 0;
 	    }
@@ -219,7 +220,7 @@ case $FLAG in
 	/\(\):/ {
 	    pr = substr($2, 1, 2);
 	    if (pr == "vi" || pr == "em" || pr == "ed") {
-		name = substr($2, 1, length($2) - 3);
+		name = substr($2, 1, index($2, "(") - 1);
 		fname = "";
 		for (i = 1; i <= length(name); i++) {
 		    s = substr(name, i, 1);
diff --git a/cmd-line-utils/libedit/map.c b/cmd-line-utils/libedit/map.c
index a16625311ae1fd1f6d2265dcc6a7f8e73f7f5b08..d99c36ff6650fcc2eb1f437fc69cf1a5404657f1 100644
--- a/cmd-line-utils/libedit/map.c
+++ b/cmd-line-utils/libedit/map.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: map.c,v 1.18 2002/11/15 14:32:33 christos Exp $	*/
+/*	$NetBSD: map.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,14 +32,7 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)map.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: map.c,v 1.18 2002/11/15 14:32:33 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * map.c: Editor function definitions
@@ -71,7 +60,7 @@ private const el_action_t  el_map_emacs[] = {
 	/*   5 */	ED_MOVE_TO_END,		/* ^E */
 	/*   6 */	ED_NEXT_CHAR,		/* ^F */
 	/*   7 */	ED_UNASSIGNED,		/* ^G */
-	/*   8 */	ED_DELETE_PREV_CHAR,	/* ^H */
+	/*   8 */	EM_DELETE_PREV_CHAR,	/* ^H */
 	/*   9 */	ED_UNASSIGNED,		/* ^I */
 	/*  10 */	ED_NEWLINE,		/* ^J */
 	/*  11 */	ED_KILL_LINE,		/* ^K */
@@ -190,7 +179,7 @@ private const el_action_t  el_map_emacs[] = {
 	/* 124 */	ED_INSERT,		/* | */
 	/* 125 */	ED_INSERT,		/* } */
 	/* 126 */	ED_INSERT,		/* ~ */
-	/* 127 */	ED_DELETE_PREV_CHAR,	/* ^? */
+	/* 127 */	EM_DELETE_PREV_CHAR,	/* ^? */
 	/* 128 */	ED_UNASSIGNED,		/* M-^@ */
 	/* 129 */	ED_UNASSIGNED,		/* M-^A */
 	/* 130 */	ED_UNASSIGNED,		/* M-^B */
@@ -1011,8 +1000,7 @@ map_init_meta(EditLine *el)
 			break;
 		default:
 			buf[1] = i & 0177;
-			el_key_add(el, buf, 
-				   el_key_map_cmd(el, (int) map[i]), XK_CMD);
+			key_add(el, buf, key_map_cmd(el, (int) map[i]), XK_CMD);
 			break;
 		}
 	map[(int) buf[0]] = ED_SEQUENCE_LEAD_IN;
@@ -1034,7 +1022,7 @@ map_init_vi(EditLine *el)
 	el->el_map.type = MAP_VI;
 	el->el_map.current = el->el_map.key;
 
-	el_key_reset(el);
+	key_reset(el);
 
 	for (i = 0; i < N_KEYS; i++) {
 		key[i] = vii[i];
@@ -1063,7 +1051,7 @@ map_init_emacs(EditLine *el)
 
 	el->el_map.type = MAP_EMACS;
 	el->el_map.current = el->el_map.key;
-	el_key_reset(el);
+	key_reset(el);
 
 	for (i = 0; i < N_KEYS; i++) {
 		key[i] = emacs[i];
@@ -1076,7 +1064,7 @@ map_init_emacs(EditLine *el)
 	buf[0] = CONTROL('X');
 	buf[1] = CONTROL('X');
 	buf[2] = 0;
-	el_key_add(el, buf, el_key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
+	key_add(el, buf, key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
 
 	tty_bind_char(el, 1);
 	term_bind_arrow(el);
@@ -1133,7 +1121,7 @@ map_print_key(EditLine *el, el_action_t *map, const char *in)
 	el_bindings_t *bp;
 
 	if (in[0] == '\0' || in[1] == '\0') {
-		(void) el_key__decode_str(in, outbuf, "");
+		(void) key__decode_str(in, outbuf, "");
 		for (bp = el->el_map.help; bp->name != NULL; bp++)
 			if (bp->func == map[(unsigned char) *in]) {
 				(void) fprintf(el->el_outfile,
@@ -1141,7 +1129,7 @@ map_print_key(EditLine *el, el_action_t *map, const char *in)
 				return;
 			}
 	} else
-		el_key_print(el, in);
+		key_print(el, in);
 }
 
 
@@ -1163,20 +1151,20 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
 		if (first == last)
 			(void) fprintf(el->el_outfile,
 			    "%-15s->  is undefined\n",
-			    el_key__decode_str(firstbuf, unparsbuf, STRQQ));
+			    key__decode_str(firstbuf, unparsbuf, STRQQ));
 		return;
 	}
 	for (bp = el->el_map.help; bp->name != NULL; bp++) {
 		if (bp->func == map[first]) {
 			if (first == last) {
 				(void) fprintf(el->el_outfile, "%-15s->  %s\n",
-				    el_key__decode_str(firstbuf, unparsbuf, STRQQ),
+				    key__decode_str(firstbuf, unparsbuf, STRQQ),
 				    bp->name);
 			} else {
 				(void) fprintf(el->el_outfile,
 				    "%-4s to %-7s->  %s\n",
-				    el_key__decode_str(firstbuf, unparsbuf, STRQQ),
-				    el_key__decode_str(lastbuf, extrabuf, STRQQ),
+				    key__decode_str(firstbuf, unparsbuf, STRQQ),
+				    key__decode_str(lastbuf, extrabuf, STRQQ),
 				    bp->name);
 			}
 			return;
@@ -1230,7 +1218,7 @@ map_print_all_keys(EditLine *el)
 	map_print_some_keys(el, el->el_map.alt, prev, i - 1);
 
 	(void) fprintf(el->el_outfile, "Multi-character bindings\n");
-	el_key_print(el, "");
+	key_print(el, "");
 	(void) fprintf(el->el_outfile, "Arrow key bindings\n");
 	term_print_arrow(el, "");
 }
@@ -1323,9 +1311,9 @@ map_bind(EditLine *el, int argc, const char **argv)
 			return (-1);
 		}
 		if (in[1])
-			(void) el_key_delete(el, in);
+			(void) key_delete(el, in);
 		else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN)
-			(void) el_key_delete(el, in);
+			(void) key_delete(el, in);
 		else
 			map[(unsigned char) *in] = ED_UNASSIGNED;
 		return (0);
@@ -1353,9 +1341,9 @@ map_bind(EditLine *el, int argc, const char **argv)
 			return (-1);
 		}
 		if (key)
-			term_set_arrow(el, in, el_key_map_str(el, out), ntype);
+			term_set_arrow(el, in, key_map_str(el, out), ntype);
 		else
-			el_key_add(el, in, el_key_map_str(el, out), ntype);
+			key_add(el, in, key_map_str(el, out), ntype);
 		map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
 		break;
 
@@ -1366,13 +1354,13 @@ map_bind(EditLine *el, int argc, const char **argv)
 			return (-1);
 		}
 		if (key)
-			term_set_arrow(el, in, el_key_map_str(el, out), ntype);
+			term_set_arrow(el, in, key_map_str(el, out), ntype);
 		else {
 			if (in[1]) {
-				el_key_add(el, in, el_key_map_cmd(el, cmd), ntype);
+				key_add(el, in, key_map_cmd(el, cmd), ntype);
 				map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
 			} else {
-				el_key_clear(el, map, in);
+				key_clear(el, map, in);
 				map[(unsigned char) *in] = cmd;
 			}
 		}
diff --git a/cmd-line-utils/libedit/map.h b/cmd-line-utils/libedit/map.h
index 3c9948ccf887e21e20e44cdff7f5247664fc15fd..3b08f48be7a1e406c6b3c49a9159981f298a52a2 100644
--- a/cmd-line-utils/libedit/map.h
+++ b/cmd-line-utils/libedit/map.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: map.h,v 1.7 2002/03/18 16:00:56 christos Exp $	*/
+/*	$NetBSD: map.h,v 1.8 2003/08/07 16:44:32 agc Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
diff --git a/cmd-line-utils/libedit/parse.c b/cmd-line-utils/libedit/parse.c
index d09b890c1abbb341fc9867f1a6ae818ba4c1e89c..993cf5b752d215e998507ddc516e77577238e0e7 100644
--- a/cmd-line-utils/libedit/parse.c
+++ b/cmd-line-utils/libedit/parse.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: parse.c,v 1.16 2003/01/21 18:40:24 christos Exp $	*/
+/*	$NetBSD: parse.c,v 1.20 2003/12/05 13:37:48 lukem Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,14 +32,7 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)parse.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: parse.c,v 1.16 2003/01/21 18:40:24 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * parse.c: parse an editline extended command
@@ -59,7 +48,6 @@ __RCSID("$NetBSD: parse.c,v 1.16 2003/01/21 18:40:24 christos Exp $");
  *	setty
  */
 #include "el.h"
-#include "tokenizer.h"
 #include <stdlib.h>
 
 private const struct {
@@ -87,9 +75,8 @@ parse_line(EditLine *el, const char *line)
 	int argc;
 	Tokenizer *tok;
 
-	if (!(tok = tok_init(NULL)))
-          return -1;
-	tok_line(tok, line, &argc, &argv);
+	tok = tok_init(NULL);
+	tok_str(tok, line, &argc, &argv);
 	argc = el_parse(el, argc, argv);
 	tok_end(tok);
 	return (argc);
@@ -207,7 +194,7 @@ parse__escape(const char **const ptr)
 			c = *p;
 			break;
 		}
-	} else if (*p == '^' && isalpha((unsigned char) p[1])) {
+	} else if (*p == '^') {
 		p++;
 		c = (*p == '?') ? '\177' : (*p & 0237);
 	} else
@@ -215,6 +202,7 @@ parse__escape(const char **const ptr)
 	*ptr = ++p;
 	return (c);
 }
+
 /* parse__string():
  *	Parse the escapes from in and put the raw string out
  */
@@ -237,6 +225,14 @@ parse__string(char *out, const char *in)
 			*out++ = n;
 			break;
 
+		case 'M':
+			if (in[1] == '-' && in[2] != '\0') {
+				*out++ = '\033';
+				in += 2;
+				break;
+			}
+			/*FALLTHROUGH*/
+
 		default:
 			*out++ = *in++;
 			break;
diff --git a/cmd-line-utils/libedit/parse.h b/cmd-line-utils/libedit/parse.h
index 4aaef2f834a4fd84e5b16b05b73829370508a9ca..4b796666b8ecef2e9f3fd210bb72a21421f81bd3 100644
--- a/cmd-line-utils/libedit/parse.h
+++ b/cmd-line-utils/libedit/parse.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: parse.h,v 1.4 2000/09/04 22:06:31 lukem Exp $	*/
+/*	$NetBSD: parse.h,v 1.5 2003/08/07 16:44:32 agc Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
diff --git a/cmd-line-utils/libedit/prompt.c b/cmd-line-utils/libedit/prompt.c
index 03d8309a991bd57225278d02840a15617f9b709b..455dd60331b5e2d7fb02575c267be0ccab060a5b 100644
--- a/cmd-line-utils/libedit/prompt.c
+++ b/cmd-line-utils/libedit/prompt.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: prompt.c,v 1.9 2002/03/18 16:00:56 christos Exp $	*/
+/*	$NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,14 +32,7 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)prompt.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: prompt.c,v 1.9 2002/03/18 16:00:56 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * prompt.c: Prompt printing functions
@@ -59,7 +48,7 @@ private char	*prompt_default_r(EditLine *);
  */
 private char *
 /*ARGSUSED*/
-prompt_default(EditLine *el __attribute__((unused)))
+prompt_default(EditLine *el __attribute__((__unused__)))
 {
 	static char a[3] = {'?', ' ', '\0'};
 
@@ -72,7 +61,7 @@ prompt_default(EditLine *el __attribute__((unused)))
  */
 private char *
 /*ARGSUSED*/
-prompt_default_r(EditLine *el __attribute__((unused)))
+prompt_default_r(EditLine *el __attribute__((__unused__)))
 {
 	static char a[1] = {'\0'};
 
@@ -127,7 +116,7 @@ prompt_init(EditLine *el)
  */
 protected void
 /*ARGSUSED*/
-prompt_end(EditLine *el __attribute__((unused)))
+prompt_end(EditLine *el __attribute__((__unused__)))
 {
 }
 
diff --git a/cmd-line-utils/libedit/prompt.h b/cmd-line-utils/libedit/prompt.h
index 08810e22a0cbb3ebb7e4797a49ecc14748c5961f..d18110861f8d6529ee7d3418b3478a7b43c659b5 100644
--- a/cmd-line-utils/libedit/prompt.h
+++ b/cmd-line-utils/libedit/prompt.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: prompt.h,v 1.5 2000/09/04 22:06:31 lukem Exp $	*/
+/*	$NetBSD: prompt.h,v 1.6 2003/08/07 16:44:32 agc Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
diff --git a/cmd-line-utils/libedit/read.c b/cmd-line-utils/libedit/read.c
index 5eaa83bf482b2a0b4691691755bd8db2b9e14def..40093d6647f7fffa2c49925dc3c3679430da849f 100644
--- a/cmd-line-utils/libedit/read.c
+++ b/cmd-line-utils/libedit/read.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: read.c,v 1.24 2002/11/20 16:50:08 christos Exp $	*/
+/*	$NetBSD: read.c,v 1.35 2005/03/09 23:55:02 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,20 +32,14 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)read.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: read.c,v 1.24 2002/11/20 16:50:08 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * read.c: Clean this junk up! This is horrible code.
  *	   Terminal read functions
  */
 #include <errno.h>
+#include <fcntl.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include "el.h"
@@ -97,6 +87,10 @@ el_read_getfn(EditLine *el)
 }
 
 
+#ifndef MIN
+#define MIN(A,B) ((A) < (B) ? (A) : (B))
+#endif
+
 #ifdef DEBUG_EDIT
 private void
 read_debug(EditLine *el)
@@ -121,11 +115,7 @@ read_debug(EditLine *el)
  */
 /* ARGSUSED */
 private int
-read__fixio(int fd 
-#if !(defined(TRY_AGAIN) && (defined(FIONBIO) || (defined(F_SETFL) && defined(O_NDELAY))))
- __attribute__((unused))
-#endif /* !(defined(TRY_AGAIN) && (defined(FIONBIO) || (defined(F_SETFL) && defined(O_NDELAY)))) */
-, int e)
+read__fixio(int fd __attribute__((__unused__)), int e)
 {
 
 	switch (e) {
@@ -190,18 +180,10 @@ read_preread(EditLine *el)
 {
 	int chrs = 0;
 
-	if (el->el_chared.c_macro.nline) {
-		el_free((ptr_t) el->el_chared.c_macro.nline);
-		el->el_chared.c_macro.nline = NULL;
-	}
 	if (el->el_tty.t_mode == ED_IO)
 		return (0);
 
 #ifdef FIONREAD
-
-#ifndef MIN // definition of MIN is lacking on hpux..
-#define MIN(x,y) (((x)<(y))?(x):(y))
-#endif
 	(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
 	if (chrs > 0) {
 		char buf[EL_BUFSIZ];
@@ -210,8 +192,7 @@ read_preread(EditLine *el)
 		    (size_t) MIN(chrs, EL_BUFSIZ - 1));
 		if (chrs > 0) {
 			buf[chrs] = '\0';
-			el->el_chared.c_macro.nline = strdup(buf);
-			el_push(el, el->el_chared.c_macro.nline);
+			el_push(el, buf);
 		}
 	}
 #endif /* FIONREAD */
@@ -230,11 +211,12 @@ el_push(EditLine *el, char *str)
 
 	if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
 		ma->level++;
-		ma->macro[ma->level] = str;
-	} else {
-		term_beep(el);
-		term__flush();
+		if ((ma->macro[ma->level] = el_strdup(str)) != NULL)
+			return;
+		ma->level--;
 	}
+	term_beep(el);
+	term__flush();
 }
 
 
@@ -266,7 +248,7 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
 		cmd = el->el_map.current[(unsigned char) *ch];
 		if (cmd == ED_SEQUENCE_LEAD_IN) {
 			key_value_t val;
-			switch (el_key_get(el, ch, &val)) {
+			switch (key_get(el, ch, &val)) {
 			case XK_CMD:
 				cmd = val.cmd;
 				break;
@@ -331,14 +313,16 @@ el_getc(EditLine *el, char *cp)
 		if (ma->level < 0)
 			break;
 
-		if (*ma->macro[ma->level] == 0) {
-			ma->level--;
+		if (ma->macro[ma->level][ma->offset] == '\0') {
+			el_free(ma->macro[ma->level--]);
+			ma->offset = 0;
 			continue;
 		}
-		*cp = *ma->macro[ma->level]++ & 0377;
-		if (*ma->macro[ma->level] == 0) {	/* Needed for QuoteMode
-							 * On */
-			ma->level--;
+		*cp = ma->macro[ma->level][ma->offset++] & 0377;
+		if (ma->macro[ma->level][ma->offset] == '\0') {
+			/* Needed for QuoteMode On */
+			el_free(ma->macro[ma->level--]);
+			ma->offset = 0;
 		}
 		return (1);
 	}
@@ -359,6 +343,35 @@ el_getc(EditLine *el, char *cp)
 	return (num_read);
 }
 
+protected void
+read_prepare(EditLine *el)
+{
+	if (el->el_flags & HANDLE_SIGNALS)
+		sig_set(el);
+	if (el->el_flags & NO_TTY)
+		return;
+	if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED)
+		tty_rawmode(el);
+
+	/* This is relatively cheap, and things go terribly wrong if
+	   we have the wrong size. */
+	el_resize(el);
+	re_clear_display(el);	/* reset the display stuff */
+	ch_reset(el);
+	re_refresh(el);		/* print the prompt */
+
+	if (el->el_flags & UNBUFFERED)
+		term__flush();
+}
+
+protected void
+read_finish(EditLine *el)
+{
+	if ((el->el_flags & UNBUFFERED) == 0)
+		(void) tty_cookedmode(el);
+	if (el->el_flags & HANDLE_SIGNALS)
+		sig_clr(el);
+}
 
 public const char *
 el_gets(EditLine *el, int *nread)
@@ -367,13 +380,11 @@ el_gets(EditLine *el, int *nread)
 	el_action_t cmdnum = 0;
 	int num;		/* how many chars we have read at NL */
 	char ch;
+	int crlf = 0;
 #ifdef FIONREAD
 	c_macro_t *ma = &el->el_chared.c_macro;
 #endif /* FIONREAD */
 
-	if (el->el_flags & HANDLE_SIGNALS)
-		sig_set(el);
-
 	if (el->el_flags & NO_TTY) {
 		char *cp = el->el_line.buffer;
 		size_t idx;
@@ -387,6 +398,8 @@ el_gets(EditLine *el, int *nread)
 				cp = &el->el_line.buffer[idx];
 			}
 			cp++;
+			if (el->el_flags & UNBUFFERED)
+				break;
 			if (cp[-1] == '\r' || cp[-1] == '\n')
 				break;
 		}
@@ -398,12 +411,6 @@ el_gets(EditLine *el, int *nread)
 		return (el->el_line.buffer);
 	}
 
-	/* This is relatively cheap, and things go terribly wrong if
-	   we have the wrong size. */
-	el_resize(el);
-
-	re_clear_display(el);	/* reset the display stuff */
-	ch_reset(el);
 
 #ifdef FIONREAD
 	if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
@@ -420,11 +427,16 @@ el_gets(EditLine *el, int *nread)
 	}
 #endif /* FIONREAD */
 
-	re_refresh(el);		/* print the prompt */
+	if ((el->el_flags & UNBUFFERED) == 0)
+		read_prepare(el);
 
 	if (el->el_flags & EDIT_DISABLED) {
-		char *cp = el->el_line.buffer;
+		char *cp;
 		size_t idx;
+		if ((el->el_flags & UNBUFFERED) == 0)
+			cp = el->el_line.buffer;
+		else
+			cp = el->el_line.lastchar;
 
 		term__flush();
 
@@ -439,7 +451,10 @@ el_gets(EditLine *el, int *nread)
 			if (*cp == 4)	/* ought to be stty eof */
 				break;
 			cp++;
-			if (cp[-1] == '\r' || cp[-1] == '\n')
+			crlf = cp[-1] == '\r' || cp[-1] == '\n';
+			if (el->el_flags & UNBUFFERED)
+				break;
+			if (crlf)
 				break;
 		}
 
@@ -463,8 +478,7 @@ el_gets(EditLine *el, int *nread)
 #endif /* DEBUG_READ */
 			break;
 		}
-		if ((unsigned int)cmdnum >= (unsigned int)(el->el_map.nfunc)) 
-                {	/* BUG CHECK command */
+		if ((uint)cmdnum >= el->el_map.nfunc) {	/* BUG CHECK command */
 #ifdef DEBUG_EDIT
 			(void) fprintf(el->el_errfile,
 			    "ERROR: illegal command from key 0%o\r\n", ch);
@@ -494,7 +508,7 @@ el_gets(EditLine *el, int *nread)
 		    el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
 			if (cmdnum == VI_DELETE_PREV_CHAR &&
 			    el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
-			    && isprint(el->el_chared.c_redo.pos[-1]))
+			    && isprint((unsigned char)el->el_chared.c_redo.pos[-1]))
 				el->el_chared.c_redo.pos--;
 			else
 				*el->el_chared.c_redo.pos++ = ch;
@@ -536,7 +550,13 @@ el_gets(EditLine *el, int *nread)
 			continue;	/* keep going... */
 
 		case CC_EOF:	/* end of file typed */
-			num = 0;
+			if ((el->el_flags & UNBUFFERED) == 0)
+				num = 0;
+			else if (num == -1) {
+				*el->el_line.lastchar++ = CONTROL('d');
+				el->el_line.cursor = el->el_line.lastchar;
+				num = 1;
+			}
 			break;
 
 		case CC_NEWLINE:	/* normal end of line */
@@ -567,14 +587,19 @@ el_gets(EditLine *el, int *nread)
 		el->el_state.argument = 1;
 		el->el_state.doingarg = 0;
 		el->el_chared.c_vcmd.action = NOP;
+		if (el->el_flags & UNBUFFERED)
+			break;
 	}
 
 	term__flush();		/* flush any buffered output */
 	/* make sure the tty is set up correctly */
-	(void) tty_cookedmode(el);
-	if (el->el_flags & HANDLE_SIGNALS)
-		sig_clr(el);
-	if (nread)
-		*nread = num;
+	if ((el->el_flags & UNBUFFERED) == 0) {
+		read_finish(el);
+		if (nread)
+			*nread = num;
+	} else {
+		if (nread)
+			*nread = el->el_line.lastchar - el->el_line.buffer;
+	}
 	return (num ? el->el_line.buffer : NULL);
 }
diff --git a/cmd-line-utils/libedit/read.h b/cmd-line-utils/libedit/read.h
index b01e77db2398d5c20df795b2572aee5681c471c6..1982f47253bc53ce3d7a4878d2a4eb80571126bb 100644
--- a/cmd-line-utils/libedit/read.h
+++ b/cmd-line-utils/libedit/read.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: read.h,v 1.1 2001/09/27 19:29:50 christos Exp $	*/
+/*	$NetBSD: read.h,v 1.4 2004/02/27 14:52:18 christos Exp $	*/
 
 /*-
  * Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -49,6 +49,8 @@ typedef struct el_read_t {
 } el_read_t;
  
 protected int		read_init(EditLine *);
+protected void		read_prepare(EditLine *);
+protected void		read_finish(EditLine *);
 protected int		el_read_setfn(EditLine *, el_rfunc_t);
 protected el_rfunc_t	el_read_getfn(EditLine *);
 
diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c
index 5b40ade582c8f28d6735692e10bd7c263dc48016..3a38e8a99abd99fc750d64593ea8ee2553f34e27 100644
--- a/cmd-line-utils/libedit/readline.c
+++ b/cmd-line-utils/libedit/readline.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: readline.c,v 1.28 2003/03/10 01:14:54 christos Exp $	*/
+/*	$NetBSD: readline.c,v 1.49 2005/03/10 19:34:46 christos Exp $	*/
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -36,10 +36,25 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-__RCSID("$NetBSD: readline.c,v 1.28 2003/03/10 01:14:54 christos Exp $");
-#endif /* not lint && not SCCSID */
+/* AIX requires this to be the first thing in the file.  */
+#if defined (_AIX) && !defined (__GNUC__)
+ #pragma alloca
+#endif
+
+#include <config.h>
+
+#ifdef __GNUC__
+# undef alloca
+# define alloca(n) __builtin_alloca (n)
+#else
+# ifdef HAVE_ALLOCA_H
+#  include <alloca.h>
+# else
+#  ifndef _AIX
+extern char *alloca ();
+#  endif
+# endif
+#endif
 
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -51,19 +66,20 @@ __RCSID("$NetBSD: readline.c,v 1.28 2003/03/10 01:14:54 christos Exp $");
 #include <stdlib.h>
 #include <unistd.h>
 #include <limits.h>
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-#include "histedit.h"
-#include "readline/readline.h"
+#include <errno.h>
+#include <fcntl.h>
+#include <vis.h>
+
 #include "el.h"
 #include "fcns.h"		/* for EL_NUM_FCNS */
+#include "histedit.h"
+#include "readline/readline.h"
 
 /* for rl_complete() */
-#define	TAB		'\r'
+#define TAB		'\r'
 
 /* see comment at the #ifdef for sense of this */
-#define	GDB_411_HACK
+/* #define GDB_411_HACK */
 
 /* readline compatibility stuff - look at readline sources/documentation */
 /* to see what these variables mean */
@@ -78,6 +94,9 @@ FILE *rl_outstream = NULL;
 int rl_point = 0;
 int rl_end = 0;
 char *rl_line_buffer = NULL;
+VFunction *rl_linefunc = NULL;
+int rl_done = 0;
+VFunction *rl_event_hook = NULL;
 
 int history_base = 1;		/* probably never subject to change */
 int history_length = 0;
@@ -86,15 +105,33 @@ char history_expansion_char = '!';
 char history_subst_char = '^';
 char *history_no_expand_chars = expand_chars;
 Function *history_inhibit_expansion_function = NULL;
+char *history_arg_extract(int start, int end, const char *str);
 
 int rl_inhibit_completion = 0;
 int rl_attempted_completion_over = 0;
 char *rl_basic_word_break_characters = break_chars;
 char *rl_completer_word_break_characters = NULL;
 char *rl_completer_quote_characters = NULL;
-CPFunction *rl_completion_entry_function = NULL;
+Function *rl_completion_entry_function = NULL;
 CPPFunction *rl_attempted_completion_function = NULL;
+Function *rl_pre_input_hook = NULL;
+Function *rl_startup1_hook = NULL;
+Function *rl_getc_function = NULL;
+char *rl_terminal_name = NULL;
+int rl_already_prompted = 0;
+int rl_filename_completion_desired = 0;
+int rl_ignore_completion_duplicates = 0;
+int rl_catch_signals = 1;
+VFunction *rl_redisplay_function = NULL;
+Function *rl_startup_hook = NULL;
+VFunction *rl_completion_display_matches_hook = NULL;
+VFunction *rl_prep_term_function = NULL;
+VFunction *rl_deprep_term_function = NULL;
 
+/*
+ * The current prompt string.
+ */
+char *rl_prompt = NULL;
 /*
  * This is set to character indicating type of completion being done by
  * rl_complete_internal(); this is available for application completion
@@ -128,30 +165,30 @@ static int _rl_complete_show_all = 0;
 
 static History *h = NULL;
 static EditLine *e = NULL;
+static Function *map[256];
 static int el_rl_complete_cmdnum = 0;
 
 /* internal functions */
 static unsigned char	 _el_rl_complete(EditLine *, int);
+static unsigned char	 _el_rl_tstp(EditLine *, int);
 static char		*_get_prompt(EditLine *);
 static HIST_ENTRY	*_move_history(int);
-static int		 _history_search_gen(const char *, int, int);
-static int		 _history_expand_command(const char *, size_t, char **);
+static int		 _history_expand_command(const char *, size_t, size_t,
+    char **);
 static char		*_rl_compat_sub(const char *, const char *,
-			    const char *, int);
-static int		 rl_complete_internal(int);
+    const char *, int);
+static int		 _rl_complete_internal(int);
 static int		 _rl_qsort_string_compare(const void *, const void *);
-
-/*
- * needed for prompt switching in readline()
- */
-static char *el_rl_prompt = NULL;
+static int		 _rl_event_read_char(EditLine *, char *);
+static void		 _rl_update_pos(void);
 
 
 /* ARGSUSED */
 static char *
-_get_prompt(EditLine *el __attribute__((unused)))
+_get_prompt(EditLine *el __attribute__((__unused__)))
 {
-	return (el_rl_prompt);
+	rl_already_prompted = 1;
+	return (rl_prompt);
 }
 
 
@@ -168,7 +205,7 @@ _move_history(int op)
 		return (HIST_ENTRY *) NULL;
 
 	rl_he.line = ev.str;
-	rl_he.data = "";
+	rl_he.data = (histdata_t) &(ev.num);
 
 	return (&rl_he);
 }
@@ -221,28 +258,40 @@ rl_initialize(void)
 	el_set(e, EL_HIST, history, h);
 
 	/* for proper prompt printing in readline() */
-	el_rl_prompt = strdup("");
-	if (el_rl_prompt == NULL) {
+	rl_prompt = strdup("");
+	if (rl_prompt == NULL) {
 		history_end(h);
 		el_end(e);
 		return -1;
 	}
 	el_set(e, EL_PROMPT, _get_prompt);
-	el_set(e, EL_SIGNAL, 1);
+	el_set(e, EL_SIGNAL, rl_catch_signals);
 
 	/* set default mode to "emacs"-style and read setting afterwards */
 	/* so this can be overriden */
 	el_set(e, EL_EDITOR, "emacs");
+	if (rl_terminal_name != NULL)
+		el_set(e, EL_TERMINAL, rl_terminal_name);
+	else
+		el_get(e, EL_TERMINAL, &rl_terminal_name);
 
 	/*
-	 * Word completition - this has to go AFTER rebinding keys
+	 * Word completion - this has to go AFTER rebinding keys
 	 * to emacs-style.
 	 */
 	el_set(e, EL_ADDFN, "rl_complete",
-	    "ReadLine compatible completition function",
+	    "ReadLine compatible completion function",
 	    _el_rl_complete);
 	el_set(e, EL_BIND, "^I", "rl_complete", NULL);
 
+	/*
+	 * Send TSTP when ^Z is pressed.
+	 */
+	el_set(e, EL_ADDFN, "rl_tstp",
+	    "ReadLine compatible suspend function",
+	    _el_rl_tstp);
+	el_set(e, EL_BIND, "^Z", "rl_tstp", NULL);
+
 	/*
 	 * Find out where the rl_complete function was added; this is
 	 * used later to detect that lastcmd was also rl_complete.
@@ -264,7 +313,10 @@ rl_initialize(void)
 	li = el_line(e);
 	/* a cheesy way to get rid of const cast. */
 	rl_line_buffer = memchr(li->buffer, *li->buffer, 1);
-	rl_point = rl_end = 0;
+	_rl_update_pos();
+
+	if (rl_startup_hook)
+		(*rl_startup_hook)(NULL, 0);
 
 	return (0);
 }
@@ -281,19 +333,38 @@ readline(const char *prompt)
 	int count;
 	const char *ret;
 	char *buf;
+	static int used_event_hook;
 
 	if (e == NULL || h == NULL)
 		rl_initialize();
 
+	rl_done = 0;
+
 	/* update prompt accordingly to what has been passed */
 	if (!prompt)
 		prompt = "";
-	if (strcmp(el_rl_prompt, prompt) != 0) {
-		free(el_rl_prompt);
-		el_rl_prompt = strdup(prompt);
-		if (el_rl_prompt == NULL)
+	if (strcmp(rl_prompt, prompt) != 0) {
+		free(rl_prompt);
+		rl_prompt = strdup(prompt);
+		if (rl_prompt == NULL)
 			return NULL;
 	}
+
+	if (rl_pre_input_hook)
+		(*rl_pre_input_hook)(NULL, 0);
+
+	if (rl_event_hook && !(e->el_flags&NO_TTY)) {
+		el_set(e, EL_GETCFN, _rl_event_read_char);
+		used_event_hook = 1;
+	}
+
+	if (!rl_event_hook && used_event_hook) {
+		el_set(e, EL_GETCFN, EL_BUILTIN_GETCFN);
+		used_event_hook = 0;
+	}
+
+	rl_already_prompted = 0;
+
 	/* get one line from input stream */
 	ret = el_gets(e, &count);
 
@@ -333,73 +404,178 @@ using_history(void)
 
 /*
  * substitute ``what'' with ``with'', returning resulting string; if
- * globally == 1, substitutes all occurences of what, otherwise only the
+ * globally == 1, substitutes all occurrences of what, otherwise only the
  * first one
  */
 static char *
 _rl_compat_sub(const char *str, const char *what, const char *with,
     int globally)
 {
-	char *result;
-	const char *temp, *new;
-	unsigned int len, with_len, what_len, add;
-	size_t size, i;
+	const	char	*s;
+	char	*r, *result;
+	size_t	len, with_len, what_len;
 
-	result = malloc((size = 16));
-	if (result == NULL)
-		return NULL;
-	temp = str;
+	len = strlen(str);
 	with_len = strlen(with);
 	what_len = strlen(what);
-	len = 0;
-	do {
-		new = strstr(temp, what);
-		if (new) {
-			i = new - temp;
-			add = i + with_len;
-			if (i + add + 1 >= size) {
-				char *nresult;
-				size += add + 1;
-				nresult = realloc(result, size);
-				if (nresult == NULL) {
-					free(result);
-					return NULL;
-				}
-				result = nresult;
-			}
-			(void) strncpy(&result[len], temp, i);
-			len += i;
-			(void) strcpy(&result[len], with);	/* safe */
-			len += with_len;
-			temp = new + what_len;
-		} else {
-			add = strlen(temp);
-			if (len + add + 1 >= size) {
-				char *nresult;
-				size += add + 1;
-				nresult = realloc(result, size);
-				if (nresult == NULL) {
-					free(result);
-					return NULL;
-				}
-				result = nresult;
+
+	/* calculate length we need for result */
+	s = str;
+	while (*s) {
+		if (*s == *what && !strncmp(s, what, what_len)) {
+			len += with_len - what_len;
+			if (!globally)
+				break;
+			s += what_len;
+		} else
+			s++;
+	}
+	r = result = malloc(len + 1);
+	if (result == NULL)
+		return NULL;
+	s = str;
+	while (*s) {
+		if (*s == *what && !strncmp(s, what, what_len)) {
+			(void)strncpy(r, with, with_len);
+			r += with_len;
+			s += what_len;
+			if (!globally) {
+				(void)strcpy(r, s);
+				return(result);
 			}
-			(void) strcpy(&result[len], temp);	/* safe */
-			len += add;
-			temp = NULL;
+		} else
+			*r++ = *s++;
+	}
+	*r = 0;
+	return(result);
+}
+
+static	char	*last_search_pat;	/* last !?pat[?] search pattern */
+static	char	*last_search_match;	/* last !?pat[?] that matched */
+
+const char *
+get_history_event(const char *cmd, int *cindex, int qchar)
+{
+	int idx, sign, sub, num, begin, ret;
+	size_t len;
+	char	*pat;
+	const char *rptr;
+	HistEvent ev;
+
+	idx = *cindex;
+	if (cmd[idx++] != history_expansion_char)
+		return(NULL);
+
+	/* find out which event to take */
+	if (cmd[idx] == history_expansion_char || cmd[idx] == 0) {
+		if (history(h, &ev, H_FIRST) != 0)
+			return(NULL);
+		*cindex = cmd[idx]? (idx + 1):idx;
+		return(ev.str);
+	}
+	sign = 0;
+	if (cmd[idx] == '-') {
+		sign = 1;
+		idx++;
+	}
+
+	if ('0' <= cmd[idx] && cmd[idx] <= '9') {
+		HIST_ENTRY *rl_he;
+
+		num = 0;
+		while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') {
+			num = num * 10 + cmd[idx] - '0';
+			idx++;
 		}
-	} while (temp && globally);
-	result[len] = '\0';
+		if (sign)
+			num = history_length - num + 1;
 
-	return (result);
-}
+		if (!(rl_he = history_get(num)))
+			return(NULL);
+
+		*cindex = idx;
+		return(rl_he->line);
+	}
+	sub = 0;
+	if (cmd[idx] == '?') {
+		sub = 1;
+		idx++;
+	}
+	begin = idx;
+	while (cmd[idx]) {
+		if (cmd[idx] == '\n')
+			break;
+		if (sub && cmd[idx] == '?')
+			break;
+		if (!sub && (cmd[idx] == ':' || cmd[idx] == ' '
+				    || cmd[idx] == '\t' || cmd[idx] == qchar))
+			break;
+		idx++;
+	}
+	len = idx - begin;
+	if (sub && cmd[idx] == '?')
+		idx++;
+	if (sub && len == 0 && last_search_pat && *last_search_pat)
+		pat = last_search_pat;
+	else if (len == 0)
+		return(NULL);
+	else {
+		if ((pat = malloc(len + 1)) == NULL)
+			return NULL;
+		(void)strncpy(pat, cmd + begin, len);
+		pat[len] = '\0';
+	}
 
+	if (history(h, &ev, H_CURR) != 0) {
+		if (pat != last_search_pat)
+			free(pat);
+		return (NULL);
+	}
+	num = ev.num;
+
+	if (sub) {
+		if (pat != last_search_pat) {
+			if (last_search_pat)
+				free(last_search_pat);
+			last_search_pat = pat;
+		}
+		ret = history_search(pat, -1);
+	} else
+		ret = history_search_prefix(pat, -1);
+
+	if (ret == -1) {
+		/* restore to end of list on failed search */
+		history(h, &ev, H_FIRST);
+		(void)fprintf(rl_outstream, "%s: Event not found\n", pat);
+		if (pat != last_search_pat)
+			free(pat);
+		return(NULL);
+	}
+
+	if (sub && len) {
+		if (last_search_match && last_search_match != pat)
+			free(last_search_match);
+		last_search_match = pat;
+	}
+
+	if (pat != last_search_pat)
+		free(pat);
+
+	if (history(h, &ev, H_CURR) != 0)
+		return(NULL);
+	*cindex = idx;
+	rptr = ev.str;
+
+	/* roll back to original position */
+	(void)history(h, &ev, H_SET, num);
+
+	return rptr;
+}
 
 /*
  * the real function doing history expansion - takes as argument command
  * to do and data upon which the command should be executed
  * does expansion the way I've understood readline documentation
- * word designator ``%'' isn't supported (yet ?)
  *
  * returns 0 if data was not modified, 1 if it was and 2 if the string
  * should be only printed and not executed; in case of error,
@@ -407,144 +583,145 @@ _rl_compat_sub(const char *str, const char *what, const char *with,
  * it's callers responsibility to free() string returned in *result
  */
 static int
-_history_expand_command(const char *command, size_t cmdlen, char **result)
+_history_expand_command(const char *command, size_t offs, size_t cmdlen,
+    char **result)
 {
-	char **arr, *tempcmd, *line, *search = NULL, *cmd;
-	const char *event_data = NULL;
+	char *tmp, *search = NULL, *aptr;
+	const char *ptr, *cmd;
 	static char *from = NULL, *to = NULL;
-	int start = -1, end = -1, max, i, idx;
-	int h_on = 0, t_on = 0, r_on = 0, e_on = 0, p_on = 0, g_on = 0;
-	int event_num = 0, retval;
-	size_t cmdsize;
+	int start, end, idx, has_mods = 0;
+	int p_on = 0, g_on = 0;
 
 	*result = NULL;
+	aptr = NULL;
+	ptr = NULL;
 
-	cmd = alloca(cmdlen + 1);
-	(void) strncpy(cmd, command, cmdlen);
-	cmd[cmdlen] = 0;
+	/* First get event specifier */
+	idx = 0;
 
-	idx = 1;
-	/* find out which event to take */
-	if (cmd[idx] == history_expansion_char) {
-		event_num = history_length;
-		idx++;
+	if (strchr(":^*$", command[offs + 1])) {
+		char str[4];
+		/*
+		* "!:" is shorthand for "!!:".
+		* "!^", "!*" and "!$" are shorthand for
+		* "!!:^", "!!:*" and "!!:$" respectively.
+		*/
+		str[0] = str[1] = '!';
+		str[2] = '0';
+		ptr = get_history_event(str, &idx, 0);
+		idx = (command[offs + 1] == ':')? 1:0;
+		has_mods = 1;
 	} else {
-		int off, num;
-		size_t len;
-		off = idx;
-		while (cmd[off] && !strchr(":^$*-%", cmd[off]))
-			off++;
-		num = atoi(&cmd[idx]);
-		if (num != 0) {
-			event_num = num;
-			if (num < 0)
-				event_num += history_length + 1;
+		if (command[offs + 1] == '#') {
+			/* use command so far */
+			if ((aptr = malloc(offs + 1)) == NULL)
+				return -1;
+			(void)strncpy(aptr, command, offs);
+			aptr[offs] = '\0';
+			idx = 1;
 		} else {
-			int prefix = 1, curr_num;
-			HistEvent ev;
-
-			len = off - idx;
-			if (cmd[idx] == '?') {
-				idx++, len--;
-				if (cmd[off - 1] == '?')
-					len--;
-				else if (cmd[off] != '\n' && cmd[off] != '\0')
-					return (-1);
-				prefix = 0;
-			}
-			search = alloca(len + 1);
-			(void) strncpy(search, &cmd[idx], len);
-			search[len] = '\0';
-
-			if (history(h, &ev, H_CURR) != 0)
-				return (-1);
-			curr_num = ev.num;
+			int	qchar;
 
-			if (prefix)
-				retval = history_search_prefix(search, -1);
-			else
-				retval = history_search(search, -1);
+			qchar = (offs > 0 && command[offs - 1] == '"')? '"':0;
+			ptr = get_history_event(command + offs, &idx, qchar);
+		}
+		has_mods = command[offs + idx] == ':';
+	}
 
-			if (retval == -1) {
-				fprintf(rl_outstream, "%s: Event not found\n",
-				    search);
-				return (-1);
-			}
-			if (history(h, &ev, H_CURR) != 0)
-				return (-1);
-			event_data = ev.str;
+	if (ptr == NULL && aptr == NULL)
+		return(-1);
 
-			/* roll back to original position */
-			history(h, &ev, H_NEXT_EVENT, curr_num);
-		}
-		idx = off;
+	if (!has_mods) {
+		*result = strdup(aptr? aptr : ptr);
+		if (aptr)
+			free(aptr);
+		return(1);
 	}
 
-	if (!event_data && event_num >= 0) {
-		HIST_ENTRY *rl_he;
-		rl_he = history_get(event_num);
-		if (!rl_he)
-			return (0);
-		event_data = rl_he->line;
+	cmd = command + offs + idx + 1;
+
+	/* Now parse any word designators */
+
+	if (*cmd == '%')	/* last word matched by ?pat? */
+		tmp = strdup(last_search_match? last_search_match:"");
+	else if (strchr("^*$-0123456789", *cmd)) {
+		start = end = -1;
+		if (*cmd == '^')
+			start = end = 1, cmd++;
+		else if (*cmd == '$')
+			start = -1, cmd++;
+		else if (*cmd == '*')
+			start = 1, cmd++;
+	       else if (*cmd == '-' || isdigit((unsigned char) *cmd)) {
+			start = 0;
+			while (*cmd && '0' <= *cmd && *cmd <= '9')
+				start = start * 10 + *cmd++ - '0';
+
+			if (*cmd == '-') {
+				if (isdigit((unsigned char) cmd[1])) {
+					cmd++;
+					end = 0;
+					while (*cmd && '0' <= *cmd && *cmd <= '9')
+						end = end * 10 + *cmd++ - '0';
+				} else if (cmd[1] == '$') {
+					cmd += 2;
+					end = -1;
+				} else {
+					cmd++;
+					end = -2;
+				}
+			} else if (*cmd == '*')
+				end = -1, cmd++;
+			else
+				end = start;
+		}
+		tmp = history_arg_extract(start, end, aptr? aptr:ptr);
+		if (tmp == NULL) {
+			(void)fprintf(rl_outstream, "%s: Bad word specifier",
+			    command + offs + idx);
+			if (aptr)
+				free(aptr);
+			return(-1);
+		}
 	} else
-		return (-1);
+		tmp = strdup(aptr? aptr:ptr);
 
-	if (cmd[idx] != ':')
-		return (-1);
-	cmd += idx + 1;
-
-	/* recognize cmd */
-	if (*cmd == '^')
-		start = end = 1, cmd++;
-	else if (*cmd == '$')
-		start = end = -1, cmd++;
-	else if (*cmd == '*')
-		start = 1, end = -1, cmd++;
-	else if (isdigit((unsigned char) *cmd)) {
-		const char *temp;
-		int shifted = 0;
-
-		start = atoi(cmd);
-		temp = cmd;
-		for (; isdigit((unsigned char) *cmd); cmd++);
-		if (temp != cmd)
-			shifted = 1;
-		if (shifted && *cmd == '-') {
-			if (!isdigit((unsigned char) *(cmd + 1)))
-				end = -2;
-			else {
-				end = atoi(cmd + 1);
-				for (; isdigit((unsigned char) *cmd); cmd++);
-			}
-		} else if (shifted && *cmd == '*')
-			end = -1, cmd++;
-		else if (shifted)
-			end = start;
+	if (aptr)
+		free(aptr);
+
+	if (*cmd == 0 || (cmd - (command + offs) >= cmdlen)) {
+		*result = tmp;
+		return(1);
 	}
-	if (*cmd == ':')
-		cmd++;
 
-	line = strdup(event_data);
-	if (line == NULL)
-		return 0;
 	for (; *cmd; cmd++) {
 		if (*cmd == ':')
 			continue;
-		else if (*cmd == 'h')
-			h_on = 1 | g_on, g_on = 0;
-		else if (*cmd == 't')
-			t_on = 1 | g_on, g_on = 0;
-		else if (*cmd == 'r')
-			r_on = 1 | g_on, g_on = 0;
-		else if (*cmd == 'e')
-			e_on = 1 | g_on, g_on = 0;
-		else if (*cmd == 'p')
-			p_on = 1 | g_on, g_on = 0;
+		else if (*cmd == 'h') {		/* remove trailing path */
+			if ((aptr = strrchr(tmp, '/')) != NULL)
+				*aptr = 0;
+		} else if (*cmd == 't') {	/* remove leading path */
+			if ((aptr = strrchr(tmp, '/')) != NULL) {
+				aptr = strdup(aptr + 1);
+				free(tmp);
+				tmp = aptr;
+			}
+		} else if (*cmd == 'r') {	/* remove trailing suffix */
+			if ((aptr = strrchr(tmp, '.')) != NULL)
+				*aptr = 0;
+		} else if (*cmd == 'e') {	/* remove all but suffix */
+			if ((aptr = strrchr(tmp, '.')) != NULL) {
+				aptr = strdup(aptr);
+				free(tmp);
+				tmp = aptr;
+			}
+		} else if (*cmd == 'p')		/* print only */
+			p_on = 1;
 		else if (*cmd == 'g')
 			g_on = 2;
 		else if (*cmd == 's' || *cmd == '&') {
 			char *what, *with, delim;
-			unsigned int len, from_len;
+			size_t len, from_len;
 			size_t size;
 
 			if (*cmd == '&' && (from == NULL || to == NULL))
@@ -559,13 +736,12 @@ _history_expand_command(const char *command, size_t cmdlen, char **result)
 				}
 				len = 0;
 				for (; *cmd && *cmd != delim; cmd++) {
-					if (*cmd == '\\'
-					    && *(cmd + 1) == delim)
+					if (*cmd == '\\' && cmd[1] == delim)
 						cmd++;
 					if (len >= size) {
 						char *nwhat;
 						nwhat = realloc(what,
-						    (size <<= 1));
+								(size <<= 1));
 						if (nwhat == NULL) {
 							free(what);
 							return 0;
@@ -612,7 +788,7 @@ _history_expand_command(const char *command, size_t cmdlen, char **result)
 					}
 					if (*cmd == '&') {
 						/* safe */
-						(void) strcpy(&with[len], from);
+						(void)strcpy(&with[len], from);
 						len += from_len;
 						continue;
 					}
@@ -624,88 +800,18 @@ _history_expand_command(const char *command, size_t cmdlen, char **result)
 				}
 				with[len] = '\0';
 				to = with;
-
-				tempcmd = _rl_compat_sub(line, from, to,
-				    (g_on) ? 1 : 0);
-				if (tempcmd) {
-					free(line);
-					line = tempcmd;
-				}
-				g_on = 0;
 			}
-		}
-	}
-
-	arr = history_tokenize(line);
-	free(line);		/* no more needed */
-	if (arr && *arr == NULL)
-		free(arr), arr = NULL;
-	if (!arr)
-		return (-1);
-
-	/* find out max valid idx to array of array */
-	max = 0;
-	for (i = 0; arr[i]; i++)
-		max++;
-	max--;
-
-	/* set boundaries to something relevant */
-	if (start < 0)
-		start = 1;
-	if (end < 0)
-		end = max - ((end < -1) ? 1 : 0);
-
-	/* check boundaries ... */
-	if (start > max || end > max || start > end)
-		return (-1);
 
-	for (i = 0; i <= max; i++) {
-		char *temp;
-		if (h_on && (i == 1 || h_on > 1) &&
-		    (temp = strrchr(arr[i], '/')))
-			*(temp + 1) = '\0';
-		if (t_on && (i == 1 || t_on > 1) &&
-		    (temp = strrchr(arr[i], '/')))
-			(void) strcpy(arr[i], temp + 1);
-		if (r_on && (i == 1 || r_on > 1) &&
-		    (temp = strrchr(arr[i], '.')))
-			*temp = '\0';
-		if (e_on && (i == 1 || e_on > 1) &&
-		    (temp = strrchr(arr[i], '.')))
-			(void) strcpy(arr[i], temp);
-	}
-
-	cmdsize = 1, cmdlen = 0;
-	if ((tempcmd = malloc(cmdsize)) == NULL)
-		return 0;
-	for (i = start; start <= i && i <= end; i++) {
-		int arr_len;
-
-		arr_len = strlen(arr[i]);
-		if (cmdlen + arr_len + 1 >= cmdsize) {
-			char *ntempcmd;
-			cmdsize += arr_len + 1;
-			ntempcmd = realloc(tempcmd, cmdsize);
-			if (ntempcmd == NULL) {
-				free(tempcmd);
-				return 0;
+			aptr = _rl_compat_sub(tmp, from, to, g_on);
+			if (aptr) {
+				free(tmp);
+				tmp = aptr;
 			}
-			tempcmd = ntempcmd;
+			g_on = 0;
 		}
-		(void) strcpy(&tempcmd[cmdlen], arr[i]);	/* safe */
-		cmdlen += arr_len;
-		tempcmd[cmdlen++] = ' ';	/* add a space */
 	}
-	while (cmdlen > 0 && isspace((unsigned char) tempcmd[cmdlen - 1]))
-		cmdlen--;
-	tempcmd[cmdlen] = '\0';
-
-	*result = tempcmd;
-
-	for (i = 0; i <= max; i++)
-		free(arr[i]);
-	free(arr), arr = (char **) NULL;
-	return (p_on) ? 2 : 1;
+	*result = tmp;
+	return (p_on? 2:1);
 }
 
 
@@ -715,27 +821,36 @@ _history_expand_command(const char *command, size_t cmdlen, char **result)
 int
 history_expand(char *str, char **output)
 {
-	int i, retval = 0, idx;
-	size_t size;
-	char *temp, *result;
+	int ret = 0;
+	size_t idx, i, size;
+	char *tmp, *result;
 
 	if (h == NULL || e == NULL)
 		rl_initialize();
 
-	*output = strdup(str);	/* do it early */
-	if (*output == NULL)
-		return 0;
+	if (history_expansion_char == 0) {
+		*output = strdup(str);
+		return(0);
+	}
 
+	*output = NULL;
 	if (str[0] == history_subst_char) {
 		/* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */
-		temp = alloca(4 + strlen(str) + 1);
-		temp[0] = temp[1] = history_expansion_char;
-		temp[2] = ':';
-		temp[3] = 's';
-		(void) strcpy(temp + 4, str);
-		str = temp;
+		*output = malloc(strlen(str) + 4 + 1);
+		if (*output == NULL)
+			return 0;
+		(*output)[0] = (*output)[1] = history_expansion_char;
+		(*output)[2] = ':';
+		(*output)[3] = 's';
+		(void)strcpy((*output) + 4, str);
+		str = *output;
+	} else {
+		*output = strdup(str);
+		if (*output == NULL)
+			return 0;
 	}
-#define	ADD_STRING(what, len) 						\
+
+#define ADD_STRING(what, len)						\
 	{								\
 		if (idx + len + 1 > size) {				\
 			char *nresult = realloc(result, (size += len + 1));\
@@ -753,35 +868,35 @@ history_expand(char *str, char **output)
 	result = NULL;
 	size = idx = 0;
 	for (i = 0; str[i];) {
-		int start, j, loop_again;
-		size_t len;
+		int qchar, loop_again;
+		size_t len, start, j;
 
+		qchar = 0;
 		loop_again = 1;
 		start = j = i;
 loop:
 		for (; str[j]; j++) {
 			if (str[j] == '\\' &&
 			    str[j + 1] == history_expansion_char) {
-				(void) strcpy(&str[j], &str[j + 1]);
+				(void)strcpy(&str[j], &str[j + 1]);
 				continue;
 			}
 			if (!loop_again) {
-				if (str[j] == '?') {
-					while (str[j] && str[++j] != '?');
-					if (str[j] == '?')
-						j++;
-				} else if (isspace((unsigned char) str[j]))
+				if (isspace((unsigned char) str[j])
+				    || str[j] == qchar)
 					break;
 			}
 			if (str[j] == history_expansion_char
 			    && !strchr(history_no_expand_chars, str[j + 1])
 			    && (!history_inhibit_expansion_function ||
-			    (*history_inhibit_expansion_function)(str, j) == 0))
+			    (*history_inhibit_expansion_function)(str,
+			    (int)j) == 0))
 				break;
 		}
 
-		if (str[j] && str[j + 1] != '#' && loop_again) {
+		if (str[j] && loop_again) {
 			i = j;
+			qchar = (j > 0 && str[j - 1] == '"' )? '"':0;
 			j++;
 			if (str[j] == history_expansion_char)
 				j++;
@@ -789,61 +904,116 @@ loop:
 			goto loop;
 		}
 		len = i - start;
-		temp = &str[start];
-		ADD_STRING(temp, len);
+		tmp = &str[start];
+		ADD_STRING(tmp, len);
 
-		if (str[i] == '\0' || str[i] != history_expansion_char
-		    || str[i + 1] == '#') {
+		if (str[i] == '\0' || str[i] != history_expansion_char) {
 			len = j - i;
-			temp = &str[i];
-			ADD_STRING(temp, len);
+			tmp = &str[i];
+			ADD_STRING(tmp, len);
 			if (start == 0)
-				retval = 0;
+				ret = 0;
 			else
-				retval = 1;
+				ret = 1;
 			break;
 		}
-		retval = _history_expand_command(&str[i], (size_t) (j - i),
-		    &temp);
-		if (retval != -1) {
-			len = strlen(temp);
-			ADD_STRING(temp, len);
+		ret = _history_expand_command (str, i, (j - i), &tmp);
+		if (ret > 0 && tmp) {
+			len = strlen(tmp);
+			ADD_STRING(tmp, len);
+			free(tmp);
 		}
 		i = j;
-	}			/* for(i ...) */
+	}
 
-	if (retval == 2) {
-		add_history(temp);
+	/* ret is 2 for "print only" option */
+	if (ret == 2) {
+		add_history(result);
 #ifdef GDB_411_HACK
 		/* gdb 4.11 has been shipped with readline, where */
 		/* history_expand() returned -1 when the line	  */
 		/* should not be executed; in readline 2.1+	  */
 		/* it should return 2 in such a case		  */
-		retval = -1;
+		ret = -1;
 #endif
 	}
 	free(*output);
 	*output = result;
 
-	return (retval);
+	return (ret);
 }
 
+/*
+* Return a string consisting of arguments of "str" from "start" to "end".
+*/
+char *
+history_arg_extract(int start, int end, const char *str)
+{
+	size_t  i, len, max;
+	char	**arr, *result;
+
+	arr = history_tokenize(str);
+	if (!arr)
+		return(NULL);
+	if (arr && *arr == NULL) {
+		free(arr);
+		return(NULL);
+	}
+
+	for (max = 0; arr[max]; max++)
+		continue;
+	max--;
+
+	if (start == '$')
+		start = max;
+	if (end == '$')
+		end = max;
+	if (end < 0)
+		end = max + end + 1;
+	if (start < 0)
+		start = end;
+
+	if (start < 0 || end < 0 || start > max || end > max || start > end)
+		return(NULL);
+
+	for (i = start, len = 0; i <= end; i++)
+		len += strlen(arr[i]) + 1;
+	len++;
+	result = malloc(len);
+	if (result == NULL)
+		return NULL;
+
+	for (i = start, len = 0; i <= end; i++) {
+		(void)strcpy(result + len, arr[i]);
+		len += strlen(arr[i]);
+		if (i < end)
+			result[len++] = ' ';
+	}
+	result[len] = 0;
+
+	for (i = 0; arr[i]; i++)
+		free(arr[i]);
+	free(arr);
+
+	return(result);
+}
 
 /*
- * Parse the string into individual tokens, similarily to how shell would do it.
+ * Parse the string into individual tokens,
+ * similar to how shell would do it.
  */
 char **
 history_tokenize(const char *str)
 {
-	int size = 1, result_idx = 0, i, start;
+	int size = 1, idx = 0, i, start;
 	size_t len;
 	char **result = NULL, *temp, delim = '\0';
 
-	for (i = 0; str[i]; i++) {
+	for (i = 0; str[i];) {
 		while (isspace((unsigned char) str[i]))
 			i++;
 		start = i;
-		for (; str[i]; i++) {
+		for (; str[i];) {
 			if (str[i] == '\\') {
 				if (str[i+1] != '\0')
 					i++;
@@ -855,9 +1025,11 @@ history_tokenize(const char *str)
 				break;
 			else if (!delim && strchr("'`\"", str[i]))
 				delim = str[i];
+			if (str[i])
+				i++;
 		}
 
-		if (result_idx + 2 >= size) {
+		if (idx + 2 >= size) {
 			char **nresult;
 			size <<= 1;
 			nresult = realloc(result, size * sizeof(char *));
@@ -870,15 +1042,18 @@ history_tokenize(const char *str)
 		len = i - start;
 		temp = malloc(len + 1);
 		if (temp == NULL) {
+			for (i = 0; i < idx; i++)
+				free(result[i]);
 			free(result);
 			return NULL;
 		}
-		(void) strncpy(temp, &str[start], len);
+		(void)strncpy(temp, &str[start], len);
 		temp[len] = '\0';
-		result[result_idx++] = temp;
-		result[result_idx] = NULL;
+		result[idx++] = temp;
+		result[idx] = NULL;
+		if (str[i])
+			i++;
 	}
-
 	return (result);
 }
 
@@ -962,28 +1137,29 @@ history_get(int num)
 {
 	static HIST_ENTRY she;
 	HistEvent ev;
-	int i = 1, curr_num;
+	int curr_num;
 
 	if (h == NULL || e == NULL)
 		rl_initialize();
 
-	/* rewind to beginning */
+	/* save current position */
 	if (history(h, &ev, H_CURR) != 0)
 		return (NULL);
 	curr_num = ev.num;
-	if (history(h, &ev, H_LAST) != 0)
+
+	/* start from most recent */
+	if (history(h, &ev, H_FIRST) != 0)
 		return (NULL);	/* error */
-	while (i < num && history(h, &ev, H_PREV) == 0)
-		i++;
-	if (i != num)
-		return (NULL);	/* not so many entries */
+
+	/* look backwards for event matching specified offset */
+	if (history(h, &ev, H_NEXT_EVENT, num))
+		return (NULL);
 
 	she.line = ev.str;
 	she.data = NULL;
 
-	/* rewind history to the same event it was before */
-	(void) history(h, &ev, H_FIRST);
-	(void) history(h, &ev, H_NEXT_EVENT, curr_num);
+	/* restore pointer to where it was */
+	(void)history(h, &ev, H_SET, curr_num);
 
 	return (&she);
 }
@@ -1000,11 +1176,11 @@ add_history(const char *line)
 	if (h == NULL || e == NULL)
 		rl_initialize();
 
-	(void) history(h, &ev, H_ENTER, line);
+	(void)history(h, &ev, H_ENTER, line);
 	if (history(h, &ev, H_GETSIZE) == 0)
 		history_length = ev.num;
 
-	return (!(history_length > 0));	/* return 0 if all is okay */
+	return (!(history_length > 0)); /* return 0 if all is okay */
 }
 
 
@@ -1086,22 +1262,17 @@ int
 history_set_pos(int pos)
 {
 	HistEvent ev;
-	int off, curr_num;
+	int curr_num;
 
 	if (pos > history_length || pos < 0)
 		return (-1);
 
 	history(h, &ev, H_CURR);
 	curr_num = ev.num;
-	history(h, &ev, H_FIRST);
-	off = 0;
-	while (off < pos && history(h, &ev, H_NEXT) == 0)
-		off++;
 
-	if (off != pos) {	/* do a rollback in case of error */
-		history(h, &ev, H_FIRST);
-		history(h, &ev, H_NEXT_EVENT, curr_num);
-		return (-1);
+	if (history(h, &ev, H_SET, pos)) {
+		history(h, &ev, H_SET, curr_num);
+		return(-1);
 	}
 	return (0);
 }
@@ -1130,10 +1301,10 @@ next_history(void)
 
 
 /*
- * generic history search function
+ * searches for first history event containing the str
  */
-static int
-_history_search_gen(const char *str, int direction, int pos)
+int
+history_search(const char *str, int direction)
 {
 	HistEvent ev;
 	const char *strp;
@@ -1144,38 +1315,25 @@ _history_search_gen(const char *str, int direction, int pos)
 	curr_num = ev.num;
 
 	for (;;) {
-		strp = strstr(ev.str, str);
-		if (strp && (pos < 0 || &ev.str[pos] == strp))
+		if ((strp = strstr(ev.str, str)) != NULL)
 			return (int) (strp - ev.str);
-		if (history(h, &ev, direction < 0 ? H_PREV : H_NEXT) != 0)
+		if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0)
 			break;
 	}
-
-	history(h, &ev, direction < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num);
-
+	history(h, &ev, H_SET, curr_num);
 	return (-1);
 }
 
 
-/*
- * searches for first history event containing the str
- */
-int
-history_search(const char *str, int direction)
-{
-
-	return (_history_search_gen(str, direction, -1));
-}
-
-
 /*
  * searches for first history event beginning with str
  */
 int
 history_search_prefix(const char *str, int direction)
 {
+	HistEvent ev;
 
-	return (_history_search_gen(str, direction, 0));
+	return (history(h, &ev, direction < 0? H_PREV_STR:H_NEXT_STR, str));
 }
 
 
@@ -1185,8 +1343,8 @@ history_search_prefix(const char *str, int direction)
  */
 /* ARGSUSED */
 int
-history_search_pos(const char *str, 
-		   int direction __attribute__((unused)), int pos)
+history_search_pos(const char *str,
+		   int direction __attribute__((__unused__)), int pos)
 {
 	HistEvent ev;
 	int curr_num, off;
@@ -1217,7 +1375,7 @@ history_search_pos(const char *str,
 
 
 /********************************/
-/* completition functions	*/
+/* completion functions */
 
 /*
  * does tilde expansion of strings of type ``~user/foo''
@@ -1246,7 +1404,7 @@ tilde_expand(char *txt)
 		temp = malloc(len);
 		if (temp == NULL)
 			return NULL;
-		(void) strncpy(temp, txt + 1, len - 2);
+		(void)strncpy(temp, txt + 1, len - 2);
 		temp[len - 2] = '\0';
 	}
 	pass = getpwnam(temp);
@@ -1261,7 +1419,7 @@ tilde_expand(char *txt)
 	temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1);
 	if (temp == NULL)
 		return NULL;
-	(void) sprintf(temp, "%s/%s", pass->pw_dir, txt);
+	(void)sprintf(temp, "%s/%s", pass->pw_dir, txt);
 
 	return (temp);
 }
@@ -1295,7 +1453,7 @@ filename_completion_function(const char *text, int state)
 				return NULL;
 			}
 			filename = nptr;
-			(void) strcpy(filename, temp);
+			(void)strcpy(filename, temp);
 			len = temp - text;	/* including last slash */
 			nptr = realloc(dirname, len + 1);
 			if (nptr == NULL) {
@@ -1303,12 +1461,16 @@ filename_completion_function(const char *text, int state)
 				return NULL;
 			}
 			dirname = nptr;
-			(void) strncpy(dirname, text, len);
+			(void)strncpy(dirname, text, len);
 			dirname[len] = '\0';
 		} else {
-			filename = strdup(text);
-			if (filename == NULL)
-				return NULL;
+			if (*text == 0)
+				filename = NULL;
+			else {
+				filename = strdup(text);
+				if (filename == NULL)
+					return NULL;
+			}
 			dirname = NULL;
 		}
 
@@ -1324,13 +1486,11 @@ filename_completion_function(const char *text, int state)
 				return NULL;
 			}
 			dirname = nptr;
-			(void) strcpy(dirname, temp);	/* safe */
+			(void)strcpy(dirname, temp);	/* safe */
 			free(temp);	/* no longer needed */
 		}
 		/* will be used in cycle */
-		filename_len = strlen(filename);
-		if (filename_len == 0)
-			return (NULL);	/* no expansion possible */
+		filename_len = filename ? strlen(filename) : 0;
 
 		if (dir != NULL) {
 			(void)closedir(dir);
@@ -1342,14 +1502,17 @@ filename_completion_function(const char *text, int state)
 	}
 	/* find the match */
 	while ((entry = readdir(dir)) != NULL) {
+		/* skip . and .. */
+		if (entry->d_name[0] == '.' && (!entry->d_name[1]
+		    || (entry->d_name[1] == '.' && !entry->d_name[2])))
+			continue;
+		if (filename_len == 0)
+			break;
 		/* otherwise, get first entry where first */
 		/* filename_len characters are equal	  */
 		if (entry->d_name[0] == filename[0]
-#ifndef STRUCT_DIRENT_HAS_D_NAMLEN
+          /* Some dirents have d_namlen, but it is not portable. */
 		    && strlen(entry->d_name) >= filename_len
-#else
-		    && entry->d_namlen >= filename_len
-#endif
 		    && strncmp(entry->d_name, filename,
 			filename_len) == 0)
 			break;
@@ -1358,16 +1521,13 @@ filename_completion_function(const char *text, int state)
 	if (entry) {		/* match found */
 
 		struct stat stbuf;
-#ifndef STRUCT_DIRENT_HAS_D_NAMLEN
+      /* Some dirents have d_namlen, but it is not portable. */
 		len = strlen(entry->d_name) +
-#else
-		len = entry->d_namlen +
-#endif
 		    ((dirname) ? strlen(dirname) : 0) + 1 + 1;
 		temp = malloc(len);
 		if (temp == NULL)
 			return NULL;
-		(void) sprintf(temp, "%s%s",
+		(void)sprintf(temp, "%s%s",
 		    dirname ? dirname : "", entry->d_name);	/* safe */
 
 		/* test, if it's directory */
@@ -1420,32 +1580,43 @@ username_completion_function(const char *text, int state)
  */
 /* ARGSUSED */
 static unsigned char
-_el_rl_complete(EditLine *el __attribute__((unused)), int ch)
+_el_rl_complete(EditLine *el __attribute__((__unused__)), int ch)
 {
 	return (unsigned char) rl_complete(0, ch);
 }
 
+/*
+ * el-compatible wrapper to send TSTP on ^Z
+ */
+/* ARGSUSED */
+static unsigned char
+_el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__unused__)))
+{
+	(void)kill(0, SIGTSTP);
+	return CC_NORM;
+}
 
 /*
- * returns list of completitions for text given
+ * returns list of completions for text given
  */
 char **
 completion_matches(const char *text, CPFunction *genfunc)
 {
 	char **match_list = NULL, *retstr, *prevstr;
 	size_t match_list_len, max_equal, which, i;
-	unsigned int matches;
+	size_t matches;
 
 	if (h == NULL || e == NULL)
 		rl_initialize();
 
 	matches = 0;
 	match_list_len = 1;
-	while ((retstr = (*genfunc) (text, matches)) != NULL) {
+	while ((retstr = (*genfunc) (text, (int)matches)) != NULL) {
 		/* allow for list terminator here */
-		if (matches + 2 >= match_list_len) {
+		if (matches + 3 >= match_list_len) {
 			char **nmatch_list;
-			match_list_len <<= 1;
+			while (matches + 3 >= match_list_len)
+				match_list_len <<= 1;
 			nmatch_list = realloc(match_list,
 			    match_list_len * sizeof(char *));
 			if (nmatch_list == NULL) {
@@ -1477,7 +1648,7 @@ completion_matches(const char *text, CPFunction *genfunc)
 		free(match_list);
 		return NULL;
 	}
-	(void) strncpy(retstr, match_list[1], max_equal);
+	(void)strncpy(retstr, match_list[1], max_equal);
 	retstr[max_equal] = '\0';
 	match_list[0] = retstr;
 
@@ -1532,9 +1703,10 @@ rl_display_match_list (matches, len, max)
 
 	idx = 1;
 	for(; count > 0; count--) {
-		for(i=0; i < limit && matches[idx]; i++, idx++)
-			fprintf(e->el_outfile, "%-*s  ", max, matches[idx]);
-		fprintf(e->el_outfile, "\n");
+		for(i = 0; i < limit && matches[idx]; i++, idx++)
+			(void)fprintf(e->el_outfile, "%-*s  ", max,
+			    matches[idx]);
+		(void)fprintf(e->el_outfile, "\n");
 	}
 }
 
@@ -1550,9 +1722,9 @@ rl_display_match_list (matches, len, max)
  * Note: '*' support is not implemented
  */
 static int
-rl_complete_internal(int what_to_do)
+_rl_complete_internal(int what_to_do)
 {
-	CPFunction *complet_func;
+	Function *complet_func;
 	const LineInfo *li;
 	char *temp, **matches;
 	const char *ctemp;
@@ -1565,7 +1737,7 @@ rl_complete_internal(int what_to_do)
 
 	complet_func = rl_completion_entry_function;
 	if (!complet_func)
-		complet_func = filename_completion_function;
+		complet_func = (Function *)(void *)filename_completion_function;
 
 	/* We now look backwards for the start of a filename/variable word */
 	li = el_line(e);
@@ -1573,26 +1745,26 @@ rl_complete_internal(int what_to_do)
 	while (ctemp > li->buffer
 	    && !strchr(rl_basic_word_break_characters, ctemp[-1])
 	    && (!rl_special_prefixes
-			|| !strchr(rl_special_prefixes, ctemp[-1]) ) )
+		|| !strchr(rl_special_prefixes, ctemp[-1]) ) )
 		ctemp--;
 
 	len = li->cursor - ctemp;
 	temp = alloca(len + 1);
-	(void) strncpy(temp, ctemp, len);
+	(void)strncpy(temp, ctemp, len);
 	temp[len] = '\0';
 
 	/* these can be used by function called in completion_matches() */
 	/* or (*rl_attempted_completion_function)() */
-	rl_point = li->cursor - li->buffer;
-	rl_end = li->lastchar - li->buffer;
+	_rl_update_pos();
 
-	if (!rl_attempted_completion_function)
-		matches = completion_matches(temp, complet_func);
-	else {
+	if (rl_attempted_completion_function) {
 		int end = li->cursor - li->buffer;
 		matches = (*rl_attempted_completion_function) (temp, (int)
 		    (end - len), end);
-	}
+	} else
+		matches = 0;
+	if (!rl_attempted_completion_function || !matches)
+		matches = completion_matches(temp, (CPFunction *)complet_func);
 
 	if (matches) {
 		int i, retval = CC_REFRESH;
@@ -1613,11 +1785,12 @@ rl_complete_internal(int what_to_do)
 		if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) {
 			/*
 			 * We found exact match. Add a space after
-			 * it, unless we do filename completition and the
+			 * it, unless we do filename completion and the
 			 * object is a directory.
 			 */
 			size_t alen = strlen(matches[0]);
-			if ((complet_func != filename_completion_function
+			if ((complet_func !=
+			    (Function *)filename_completion_function
 			      || (alen > 0 && (matches[0])[alen - 1] != '/'))
 			    && rl_completion_append_character) {
 				char buf[2];
@@ -1640,20 +1813,20 @@ rl_complete_internal(int what_to_do)
 			matches_num = i - 1;
 				
 			/* newline to get on next line from command line */
-			fprintf(e->el_outfile, "\n");
+			(void)fprintf(e->el_outfile, "\n");
 
 			/*
 			 * If there are too many items, ask user for display
 			 * confirmation.
 			 */
 			if (matches_num > rl_completion_query_items) {
-				fprintf(e->el_outfile,
-				"Display all %d possibilities? (y or n) ",
-					matches_num);
-				fflush(e->el_outfile);
+				(void)fprintf(e->el_outfile,
+				    "Display all %d possibilities? (y or n) ",
+				    matches_num);
+				(void)fflush(e->el_outfile);
 				if (getc(stdin) != 'y')
 					match_display = 0;
-				fprintf(e->el_outfile, "\n");
+				(void)fprintf(e->el_outfile, "\n");
 			}
 
 			if (match_display)
@@ -1689,20 +1862,24 @@ rl_complete_internal(int what_to_do)
  * complete word at current point
  */
 int
+/*ARGSUSED*/
 rl_complete(int ignore, int invoking_key)
 {
 	if (h == NULL || e == NULL)
 		rl_initialize();
 
 	if (rl_inhibit_completion) {
-		rl_insert(ignore, invoking_key);
+		char arr[2];
+		arr[0] = (char)invoking_key;
+		arr[1] = '\0';
+		el_insertstr(e, arr);
 		return (CC_REFRESH);
 	} else if (e->el_state.lastcmd == el_rl_complete_cmdnum)
-		return rl_complete_internal('?');
+		return _rl_complete_internal('?');
 	else if (_rl_complete_show_all)
-		return rl_complete_internal('!');
+		return _rl_complete_internal('!');
 	else
-		return (rl_complete_internal(TAB));
+		return _rl_complete_internal(TAB);
 }
 
 
@@ -1751,7 +1928,7 @@ rl_read_key(void)
  */
 /* ARGSUSED */
 void
-rl_reset_terminal(const char *p __attribute__((unused)))
+rl_reset_terminal(const char *p __attribute__((__unused__)))
 {
 
 	if (h == NULL || e == NULL)
@@ -1780,3 +1957,211 @@ rl_insert(int count, int c)
 
 	return (0);
 }
+
+/*ARGSUSED*/
+int
+rl_newline(int count, int c)
+{
+	/*
+	 * Readline-4.0 appears to ignore the args.
+	 */
+	return rl_insert(1, '\n');
+}
+
+/*ARGSUSED*/
+static unsigned char
+rl_bind_wrapper(EditLine *el, unsigned char c)
+{
+	if (map[c] == NULL)
+	    return CC_ERROR;
+
+	_rl_update_pos();
+
+	(*map[c])(NULL, c);
+
+	/* If rl_done was set by the above call, deal with it here */
+	if (rl_done)
+		return CC_EOF;
+
+	return CC_NORM;
+}
+
+int
+rl_add_defun(const char *name, Function *fun, int c)
+{
+	char dest[8];
+	if (c >= sizeof(map) / sizeof(map[0]) || c < 0)
+		return -1;
+	map[(unsigned char)c] = fun;
+	el_set(e, EL_ADDFN, name, name, rl_bind_wrapper);
+	vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0);
+	el_set(e, EL_BIND, dest, name);
+	return 0;
+}
+
+void
+rl_callback_read_char()
+{
+	int count = 0, done = 0;
+	const char *buf = el_gets(e, &count);
+	char *wbuf;
+
+	if (buf == NULL || count-- <= 0)
+		return;
+#ifdef CTRL2 /* _AIX */
+	if (count == 0 && buf[0] == CTRL2('d'))
+#else
+	if (count == 0 && buf[0] == CTRL('d'))
+#endif
+		done = 1;
+	if (buf[count] == '\n' || buf[count] == '\r')
+		done = 2;
+
+	if (done && rl_linefunc != NULL) {
+		el_set(e, EL_UNBUFFERED, 0);
+		if (done == 2) {
+		    if ((wbuf = strdup(buf)) != NULL)
+			wbuf[count] = '\0';
+		} else
+			wbuf = NULL;
+		(*(void (*)(const char *))rl_linefunc)(wbuf);
+		el_set(e, EL_UNBUFFERED, 1);
+	}
+}
+
+void 
+rl_callback_handler_install (const char *prompt, VFunction *linefunc)
+{
+	if (e == NULL) {
+		rl_initialize();
+	}
+	if (rl_prompt)
+		free(rl_prompt);
+	rl_prompt = prompt ? strdup(strchr(prompt, *prompt)) : NULL;
+	rl_linefunc = linefunc;
+	el_set(e, EL_UNBUFFERED, 1);
+}   
+
+void 
+rl_callback_handler_remove(void)
+{
+	el_set(e, EL_UNBUFFERED, 0);
+}
+
+void
+rl_redisplay(void)
+{
+	char a[2];
+#ifdef CTRL2 /* _AIX */
+	a[0] = CTRL2('r');
+#else
+	a[0] = CTRL('r');
+#endif
+	a[1] = '\0';
+	el_push(e, a);
+}
+
+int
+rl_get_previous_history(int count, int key)
+{
+	char a[2];
+	a[0] = key;
+	a[1] = '\0';
+	while (count--)
+		el_push(e, a);
+	return 0;
+}
+
+void
+/*ARGSUSED*/
+rl_prep_terminal(int meta_flag)
+{
+	el_set(e, EL_PREP_TERM, 1);
+}
+
+void
+rl_deprep_terminal()
+{
+	el_set(e, EL_PREP_TERM, 0);
+}
+
+int
+rl_read_init_file(const char *s)
+{
+	return(el_source(e, s));
+}
+
+int
+rl_parse_and_bind(const char *line)
+{
+	const char **argv;
+	int argc;
+	Tokenizer *tok;
+
+	tok = tok_init(NULL);
+	tok_str(tok, line, &argc, &argv);
+	argc = el_parse(e, argc, argv);
+	tok_end(tok);
+	return (argc ? 1 : 0);
+}
+
+void
+rl_stuff_char(int c)
+{
+	char buf[2];
+
+	buf[0] = c;
+	buf[1] = '\0';
+	el_insertstr(e, buf);
+}
+
+static int
+_rl_event_read_char(EditLine *el, char *cp)
+{
+	int	n, num_read = 0;
+
+	*cp = 0;
+	while (rl_event_hook) {
+
+		(*rl_event_hook)();
+
+#if defined(FIONREAD)
+		if (ioctl(el->el_infd, FIONREAD, &n) < 0)
+			return(-1);
+		if (n)
+			num_read = read(el->el_infd, cp, 1);
+		else
+			num_read = 0;
+#elif defined(F_SETFL) && defined(O_NDELAY)
+		if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0)
+			return(-1);
+		if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0)
+			return(-1);
+		num_read = read(el->el_infd, cp, 1);
+		if (fcntl(el->el_infd, F_SETFL, n))
+			return(-1);
+#else
+		/* not non-blocking, but what you gonna do? */
+		num_read = read(el->el_infd, cp, 1);
+		return(-1);
+#endif
+
+		if (num_read < 0 && errno == EAGAIN)
+			continue;
+		if (num_read == 0)
+			continue;
+		break;
+	}
+	if (!rl_event_hook)
+		el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN);
+	return(num_read);
+}
+
+static void
+_rl_update_pos(void)
+{
+	const LineInfo *li = el_line(e);
+
+	rl_point = li->cursor - li->buffer;
+	rl_end = li->lastchar - li->buffer;
+}
diff --git a/cmd-line-utils/libedit/readline/readline.h b/cmd-line-utils/libedit/readline/readline.h
index 7485dde4052f246b4a565a308a1537bf895dd6cb..902179c208aa48750835c2e589d8ff2aa2e55cc9 100644
--- a/cmd-line-utils/libedit/readline/readline.h
+++ b/cmd-line-utils/libedit/readline/readline.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: readline.h,v 1.1 2001/01/05 21:15:50 jdolecek Exp $	*/
+/*	$NetBSD: readline.h,v 1.12 2004/09/08 18:15:37 christos Exp $	*/
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
  * POSSIBILITY OF SUCH DAMAGE.
  */
 #ifndef _READLINE_H_
-#define	_READLINE_H_
+#define _READLINE_H_
 
 #include <sys/types.h>
 
@@ -48,11 +48,45 @@ typedef void	  VFunction(void);
 typedef char	 *CPFunction(const char *, int);
 typedef char	**CPPFunction(const char *, int, int);
 
+typedef void *histdata_t;
+
 typedef struct _hist_entry {
 	const char	*line;
-	const char	*data;
+	histdata_t	*data;
 } HIST_ENTRY;
 
+typedef struct _keymap_entry {
+	char type;
+#define ISFUNC	0
+#define ISKMAP	1
+#define ISMACR	2
+	Function *function;
+} KEYMAP_ENTRY;
+
+#define KEYMAP_SIZE	256
+
+typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE];
+typedef KEYMAP_ENTRY *Keymap;
+
+#define control_character_threshold	0x20
+#define control_character_bit		0x40
+
+#ifndef CTRL
+#include <sys/ioctl.h>
+#ifdef __GLIBC__
+#include <sys/ttydefaults.h>
+#endif
+#ifndef CTRL
+#define CTRL(c)		((c) & 037)
+#endif
+#endif
+#ifndef UNCTRL
+#define UNCTRL(c)	(((c) - 'a' + 'A')|control_character_bit)
+#endif
+
+#define RUBOUT		0x7f
+#define ABORT_CHAR	CTRL('G')
+
 /* global variables used by readline enabled applications */
 #ifdef __cplusplus
 extern "C" {
@@ -68,12 +102,31 @@ extern int		 max_input_history;
 extern char		*rl_basic_word_break_characters;
 extern char		*rl_completer_word_break_characters;
 extern char		*rl_completer_quote_characters;
-extern CPFunction	*rl_completion_entry_function;
+extern Function		*rl_completion_entry_function;
 extern CPPFunction	*rl_attempted_completion_function;
 extern int		rl_completion_type;
 extern int		rl_completion_query_items;
 extern char		*rl_special_prefixes;
 extern int		rl_completion_append_character;
+extern int		rl_inhibit_completion;
+extern Function		*rl_pre_input_hook;
+extern Function		*rl_startup_hook;
+extern char		*rl_terminal_name;
+extern int		rl_already_prompted;
+extern char		*rl_prompt;
+/*
+ * The following is not implemented
+ */
+extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
+			emacs_meta_keymap,
+			emacs_ctlx_keymap;
+extern int		rl_filename_completion_desired;
+extern int		rl_ignore_completion_duplicates;
+extern Function		*rl_getc_function;
+extern VFunction	*rl_redisplay_function;
+extern VFunction	*rl_completion_display_matches_hook;
+extern VFunction	*rl_prep_term_function;
+extern VFunction	*rl_deprep_term_function;
 
 /* supported functions */
 char		*readline(const char *);
@@ -99,6 +152,8 @@ int		 read_history(const char *);
 int		 write_history(const char *);
 int		 history_expand(char *, char **);
 char	       **history_tokenize(const char *);
+const char	*get_history_event(const char *, int *, int);
+char		*history_arg_extract(int, int, const char *);
 
 char		*tilde_expand(char *);
 char		*filename_completion_function(const char *, int);
@@ -111,6 +166,26 @@ void		 rl_display_match_list(char **, int, int);
 int		 rl_insert(int, int);
 void		 rl_reset_terminal(const char *);
 int		 rl_bind_key(int, int (*)(int, int));
+int		 rl_newline(int, int);
+void		 rl_callback_read_char(void);
+void		 rl_callback_handler_install(const char *, VFunction *);
+void		 rl_callback_handler_remove(void);
+void		 rl_redisplay(void);
+int		 rl_get_previous_history(int, int);
+void		 rl_prep_terminal(int);
+void		 rl_deprep_terminal(void);
+int		 rl_read_init_file(const char *);
+int		 rl_parse_and_bind(const char *);
+void		 rl_stuff_char(int);
+int		 rl_add_defun(const char *, Function *, int);
+
+/*
+ * The following are not implemented
+ */
+Keymap		 rl_get_keymap(void);
+Keymap		 rl_make_bare_keymap(void);
+int		 rl_generic_bind(int, const char *, const char *, Keymap);
+int		 rl_bind_key_in_map(int, Function *, Keymap);
 #ifdef __cplusplus
 }
 #endif
diff --git a/cmd-line-utils/libedit/refresh.c b/cmd-line-utils/libedit/refresh.c
index e71bdba2b616edaf102abf505ef002f606ee14d6..b2833d215c5a6a1bf2c2131d5c989a9c0a261977 100644
--- a/cmd-line-utils/libedit/refresh.c
+++ b/cmd-line-utils/libedit/refresh.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: refresh.c,v 1.24 2003/03/10 21:18:49 christos Exp $	*/
+/*	$NetBSD: refresh.c,v 1.26 2003/08/07 16:44:33 agc Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,14 +32,7 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)refresh.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: refresh.c,v 1.24 2003/03/10 21:18:49 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * refresh.c: Lower level screen refreshing functions
@@ -57,8 +46,8 @@ __RCSID("$NetBSD: refresh.c,v 1.24 2003/03/10 21:18:49 christos Exp $");
 
 private void	re_addc(EditLine *, int);
 private void	re_update_line(EditLine *, char *, char *, int);
-private void	re_insert (EditLine *el, char *, int, int, char *, int);
-private void	re_delete(EditLine *el, char *, int, int, int);
+private void	re_insert (EditLine *, char *, int, int, char *, int);
+private void	re_delete(EditLine *, char *, int, int, int);
 private void	re_fastputc(EditLine *, int);
 private void	re__strncopy(char *, char *, size_t);
 private void	re__copy_and_pad(char *, const char *, size_t);
@@ -338,8 +327,8 @@ re_goto_bottom(EditLine *el)
  */
 private void
 /*ARGSUSED*/
-re_insert(EditLine *el __attribute__((unused)),
-	  char *d, int dat, int dlen, char *s, int num)
+re_insert(EditLine *el __attribute__((__unused__)),
+    char *d, int dat, int dlen, char *s, int num)
 {
 	char *a, *b;
 
@@ -382,8 +371,8 @@ re_insert(EditLine *el __attribute__((unused)),
  */
 private void
 /*ARGSUSED*/
-re_delete(EditLine *el __attribute__((unused)),
-	  char *d, int dat, int dlen, int num)
+re_delete(EditLine *el __attribute__((__unused__)),
+    char *d, int dat, int dlen, int num)
 {
 	char *a, *b;
 
diff --git a/cmd-line-utils/libedit/refresh.h b/cmd-line-utils/libedit/refresh.h
index 33c0887c1b3888ef3934acc8970f57a04c0ceaa7..dd2bd02094baebf3a0974a1e966a5e900b620f79 100644
--- a/cmd-line-utils/libedit/refresh.h
+++ b/cmd-line-utils/libedit/refresh.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: refresh.h,v 1.4 2001/01/10 07:45:42 jdolecek Exp $	*/
+/*	$NetBSD: refresh.h,v 1.5 2003/08/07 16:44:33 agc Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
diff --git a/cmd-line-utils/libedit/search.c b/cmd-line-utils/libedit/search.c
index 0957529485c5e367c3b44659c75efe4a920befe9..848429e091b5834795a993e7be19e744ae5c9db2 100644
--- a/cmd-line-utils/libedit/search.c
+++ b/cmd-line-utils/libedit/search.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: search.c,v 1.14 2002/11/20 16:50:08 christos Exp $	*/
+/*	$NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,21 +32,13 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)search.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: search.c,v 1.14 2002/11/20 16:50:08 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * search.c: History and character search functions
  */
 #include <stdlib.h>
 #if defined(REGEX)
-#include <sys/types.h>
 #include <regex.h>
 #elif defined(REGEXP)
 #include <regexp.h>
@@ -227,8 +215,11 @@ ce_inc_search(EditLine *el, int dir)
 		if (el->el_search.patlen == 0) {	/* first round */
 			pchar = ':';
 #ifdef ANCHOR
+#define	LEN	2
 			el->el_search.patbuf[el->el_search.patlen++] = '.';
 			el->el_search.patbuf[el->el_search.patlen++] = '*';
+#else
+#define	LEN	0
 #endif
 		}
 		done = redo = 0;
@@ -237,7 +228,7 @@ ce_inc_search(EditLine *el, int dir)
 		    *cp; *el->el_line.lastchar++ = *cp++)
 			continue;
 		*el->el_line.lastchar++ = pchar;
-		for (cp = &el->el_search.patbuf[1];
+		for (cp = &el->el_search.patbuf[LEN];
 		    cp < &el->el_search.patbuf[el->el_search.patlen];
 		    *el->el_line.lastchar++ = *cp++)
 			continue;
@@ -250,7 +241,7 @@ ce_inc_search(EditLine *el, int dir)
 		switch (el->el_map.current[(unsigned char) ch]) {
 		case ED_INSERT:
 		case ED_DIGIT:
-			if (el->el_search.patlen > EL_BUFSIZ - 3)
+			if (el->el_search.patlen >= EL_BUFSIZ - LEN)
 				term_beep(el);
 			else {
 				el->el_search.patbuf[el->el_search.patlen++] =
@@ -271,8 +262,9 @@ ce_inc_search(EditLine *el, int dir)
 			redo++;
 			break;
 
+		case EM_DELETE_PREV_CHAR:
 		case ED_DELETE_PREV_CHAR:
-			if (el->el_search.patlen > 1)
+			if (el->el_search.patlen > LEN)
 				done++;
 			else
 				term_beep(el);
@@ -287,17 +279,18 @@ ce_inc_search(EditLine *el, int dir)
 
 			case 0027:	/* ^W: Append word */
 			/* No can do if globbing characters in pattern */
-				for (cp = &el->el_search.patbuf[1];; cp++)
-				    if (cp >= &el->el_search.patbuf[el->el_search.patlen]) {
+				for (cp = &el->el_search.patbuf[LEN];; cp++)
+				    if (cp >= &el->el_search.patbuf[
+					el->el_search.patlen]) {
 					el->el_line.cursor +=
-					    el->el_search.patlen - 1;
+					    el->el_search.patlen - LEN - 1;
 					cp = c__next_word(el->el_line.cursor,
 					    el->el_line.lastchar, 1,
 					    ce__isword);
 					while (el->el_line.cursor < cp &&
 					    *el->el_line.cursor != '\n') {
-						if (el->el_search.patlen >
-						    EL_BUFSIZ - 3) {
+						if (el->el_search.patlen >=
+						    EL_BUFSIZ - LEN) {
 							term_beep(el);
 							break;
 						}
@@ -339,13 +332,13 @@ ce_inc_search(EditLine *el, int dir)
 			/* Can't search if unmatched '[' */
 			for (cp = &el->el_search.patbuf[el->el_search.patlen-1],
 			    ch = ']';
-			    cp > el->el_search.patbuf;
+			    cp >= &el->el_search.patbuf[LEN];
 			    cp--)
 				if (*cp == '[' || *cp == ']') {
 					ch = *cp;
 					break;
 				}
-			if (el->el_search.patlen > 1 && ch != '[') {
+			if (el->el_search.patlen > LEN && ch != '[') {
 				if (redo && newdir == dir) {
 					if (pchar == '?') { /* wrap around */
 						el->el_history.eventno =
@@ -375,9 +368,8 @@ ce_inc_search(EditLine *el, int dir)
 				    '\0';
 				if (el->el_line.cursor < el->el_line.buffer ||
 				    el->el_line.cursor > el->el_line.lastchar ||
-				    (ret = ce_search_line(el,
-				    &el->el_search.patbuf[1],
-				    newdir)) == CC_ERROR) {
+				    (ret = ce_search_line(el, newdir))
+				    == CC_ERROR) {
 					/* avoid c_setpat */
 					el->el_state.lastcmd =
 					    (el_action_t) newdir;
@@ -390,11 +382,11 @@ ce_inc_search(EditLine *el, int dir)
 						    el->el_line.lastchar :
 						    el->el_line.buffer;
 						(void) ce_search_line(el,
-						    &el->el_search.patbuf[1],
 						    newdir);
 					}
 				}
-				el->el_search.patbuf[--el->el_search.patlen] =
+				el->el_search.patlen -= LEN;
+				el->el_search.patbuf[el->el_search.patlen] =
 				    '\0';
 				if (ret == CC_ERROR) {
 					term_beep(el);
@@ -453,9 +445,6 @@ cv_search(EditLine *el, int dir)
 #ifdef ANCHOR
 	tmpbuf[0] = '.';
 	tmpbuf[1] = '*';
-#define	LEN	2
-#else
-#define	LEN	0
 #endif
 	tmplen = LEN;
 
@@ -521,24 +510,39 @@ cv_search(EditLine *el, int dir)
  *	Look for a pattern inside a line
  */
 protected el_action_t
-ce_search_line(EditLine *el, char *pattern, int dir)
+ce_search_line(EditLine *el, int dir)
 {
-	char *cp;
+	char *cp = el->el_line.cursor;
+	char *pattern = el->el_search.patbuf;
+	char oc, *ocp;
+#ifdef ANCHOR
+	ocp = &pattern[1];
+	oc = *ocp;
+	*ocp = '^';
+#else
+	ocp = pattern;
+	oc = *ocp;
+#endif
 
 	if (dir == ED_SEARCH_PREV_HISTORY) {
-		for (cp = el->el_line.cursor; cp >= el->el_line.buffer; cp--)
-			if (el_match(cp, pattern)) {
+		for (; cp >= el->el_line.buffer; cp--) {
+			if (el_match(cp, ocp)) {
+				*ocp = oc;
 				el->el_line.cursor = cp;
 				return (CC_NORM);
 			}
+		}
+		*ocp = oc;
 		return (CC_ERROR);
 	} else {
-		for (cp = el->el_line.cursor; *cp != '\0' &&
-		    cp < el->el_line.limit; cp++)
-			if (el_match(cp, pattern)) {
+		for (; *cp != '\0' && cp < el->el_line.limit; cp++) {
+			if (el_match(cp, ocp)) {
+				*ocp = oc;
 				el->el_line.cursor = cp;
 				return (CC_NORM);
 			}
+		}
+		*ocp = oc;
 		return (CC_ERROR);
 	}
 }
diff --git a/cmd-line-utils/libedit/search.h b/cmd-line-utils/libedit/search.h
index a7363072a4cd0817045299c9607990fd3e41f065..2aa8f9850132c2ebdf4c37bee8f41179fac34606 100644
--- a/cmd-line-utils/libedit/search.h
+++ b/cmd-line-utils/libedit/search.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: search.h,v 1.6 2002/11/15 14:32:34 christos Exp $	*/
+/*	$NetBSD: search.h,v 1.8 2003/10/18 23:27:36 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -63,7 +59,7 @@ protected int		c_hmatch(EditLine *, const char *);
 protected void		c_setpat(EditLine *);
 protected el_action_t	ce_inc_search(EditLine *, int);
 protected el_action_t	cv_search(EditLine *, int);
-protected el_action_t	ce_search_line(EditLine *, char *, int);
+protected el_action_t	ce_search_line(EditLine *, int);
 protected el_action_t	cv_repeat_srch(EditLine *, int);
 protected el_action_t	cv_csearch(EditLine *, int, int, int, int);
 
diff --git a/cmd-line-utils/libedit/sig.c b/cmd-line-utils/libedit/sig.c
index 3730067ed5fca036816c501e06eb83923568e366..8e70933d606e2bc0a8ad54fb964df7380d4de320 100644
--- a/cmd-line-utils/libedit/sig.c
+++ b/cmd-line-utils/libedit/sig.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: sig.c,v 1.10 2003/03/10 00:58:05 christos Exp $	*/
+/*	$NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,14 +32,7 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)sig.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: sig.c,v 1.10 2003/03/10 00:58:05 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * sig.c: Signal handling stuff.
diff --git a/cmd-line-utils/libedit/sig.h b/cmd-line-utils/libedit/sig.h
index 8effea8e1217a263c74bbd12930ef3ee3c51a43e..0bf1fc37e39451adb9f04654dedee11f4e9e8693 100644
--- a/cmd-line-utils/libedit/sig.h
+++ b/cmd-line-utils/libedit/sig.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: sig.h,v 1.4 2003/03/10 00:58:05 christos Exp $	*/
+/*	$NetBSD: sig.h,v 1.5 2003/08/07 16:44:33 agc Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
diff --git a/cmd-line-utils/libedit/strlcpy.c b/cmd-line-utils/libedit/strlcpy.c
index 74317d99cd2b70d95012375ad791709950e1562f..e38d6cf1c4b61ded014e43139c25913d1c8c6992 100644
--- a/cmd-line-utils/libedit/strlcpy.c
+++ b/cmd-line-utils/libedit/strlcpy.c
@@ -1,28 +1,73 @@
+/*	$NetBSD: strlcpy.c,v 1.14 2003/10/27 00:12:42 lukem Exp $	*/
+/*	$OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $	*/
+
+/*
+ * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
+ * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <assert.h>
 #include <string.h>
 
-#ifndef HAVE_STRLCPY
-size_t strlcpy(char *dst, const char *src, size_t size)
+#ifdef _LIBC
+# ifdef __weak_alias
+__weak_alias(strlcpy, _strlcpy)
+# endif
+#endif
+
+#if !HAVE_STRLCPY
+/*
+ * Copy src to string dst of size siz.  At most siz-1 characters
+ * will be copied.  Always NUL terminates (unless siz == 0).
+ * Returns strlen(src); if retval >= siz, truncation occurred.
+ */
+size_t
+#ifdef _LIBC
+_strlcpy(dst, src, siz)
+#else
+strlcpy(dst, src, siz)
+#endif
+	char *dst;
+	const char *src;
+	size_t siz;
 {
-	if(size) {
-		strncpy(dst, src, size-1);
-		dst[size-1] = '\0';
-	} else {
-		dst[0] = '\0';
+	char *d = dst;
+	const char *s = src;
+	size_t n = siz;
+
+	_DIAGASSERT(dst != NULL);
+	_DIAGASSERT(src != NULL);
+
+	/* Copy as many bytes as will fit */
+	if (n != 0 && --n != 0) {
+		do {
+			if ((*d++ = *s++) == 0)
+				break;
+		} while (--n != 0);
 	}
-	return strlen(src);
-}
 
-size_t strlcat(char *dst, const char *src, size_t size)
-{
-	int dl = strlen(dst);
-	int sz = size-dl-1;
-	
-	if(sz >= 0) {
-		strncat(dst, src, sz);
-		dst[sz] = '\0';
+	/* Not enough room in dst, add NUL and traverse rest of src */
+	if (n == 0) {
+		if (siz != 0)
+			*d = '\0';		/* NUL-terminate dst */
+		while (*s++)
+			;
 	}
 
-	return dl+strlen(src);
+	return(s - src - 1);	/* count does not include NUL */
 }
-
 #endif
diff --git a/cmd-line-utils/libedit/sys.h b/cmd-line-utils/libedit/sys.h
index a7477d2c5ba1a8e21978e97cc579a0d27b0848a6..c8a29dbfb05713297bbe76415d940fd0033d8124 100644
--- a/cmd-line-utils/libedit/sys.h
+++ b/cmd-line-utils/libedit/sys.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: sys.h,v 1.6 2003/03/10 00:57:38 christos Exp $	*/
+/*	$NetBSD: sys.h,v 1.9 2004/01/17 17:57:40 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -48,6 +44,28 @@
 #include <sys/cdefs.h>
 #endif
 
+#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__)  || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
+# define __attribute__(A)
+#endif
+
+#ifndef __P
+# define __P(x) x
+#endif
+
+#ifndef _DIAGASSERT
+# define _DIAGASSERT(x)
+#endif
+
+#ifndef __BEGIN_DECLS
+# ifdef  __cplusplus
+#  define __BEGIN_DECLS  extern "C" {
+#  define __END_DECLS    }
+# else
+#  define __BEGIN_DECLS
+#  define __END_DECLS
+# endif
+#endif
+ 
 #ifndef public
 # define public		/* Externally visible functions/variables */
 #endif
@@ -61,6 +79,10 @@
 			/* When we want to hide everything	*/
 #endif
 
+#ifndef HAVE_U_INT32_T
+typedef unsigned int  u_int32_t;
+#endif
+
 #ifndef _PTR_T
 # define _PTR_T
 typedef void	*ptr_t;
diff --git a/cmd-line-utils/libedit/term.c b/cmd-line-utils/libedit/term.c
index c4ee0d30aab44ad3ae5ea26420d157d27e036232..b516d6753c3245e765efec1c35627360d258cf8b 100644
--- a/cmd-line-utils/libedit/term.c
+++ b/cmd-line-utils/libedit/term.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: term.c,v 1.35 2002/03/18 16:00:59 christos Exp $	*/
+/*	$NetBSD: term.c,v 1.40 2004/05/22 23:21:28 christos Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,14 +32,7 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)term.c	8.2 (Berkeley) 4/30/95";
-#else
-__RCSID("$NetBSD: term.c,v 1.35 2002/03/18 16:00:59 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * term.c: Editor/termcap-curses interface
@@ -55,24 +44,23 @@ __RCSID("$NetBSD: term.c,v 1.35 2002/03/18 16:00:59 christos Exp $");
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
-#ifdef HAVE_TERMCAP_H
-#include <termcap.h>
-#endif
+
 #ifdef HAVE_CURSES_H
-#include <curses.h>
-#endif
-#ifdef HAVE_NCURSES_H
-#include <ncurses.h>
+# include <curses.h>
+#elif HAVE_NCURSES_H
+# include <ncurses.h>
 #endif
 
-#include "el.h"
-
-#if !defined(HAVE_TERMCAP_H) && defined(HAVE_TERM_H)
-#include <term.h>
+/* Solaris's term.h does horrid things. */
+#if (defined(HAVE_TERM_H) && !defined(_SUNOS))
+# include <term.h>
 #endif
+
 #include <sys/types.h>
 #include <sys/ioctl.h>
 
+#include "el.h"
+
 /*
  * IMPORTANT NOTE: these routines are allowed to look at the current screen
  * and the current possition assuming that it is correct.  If this is not
@@ -356,6 +344,7 @@ term_init(EditLine *el)
 	term_init_arrow(el);
 	return (0);
 }
+
 /* term_end():
  *	Clean up the terminal stuff
  */
@@ -372,6 +361,8 @@ term_end(EditLine *el)
 	el->el_term.t_str = NULL;
 	el_free((ptr_t) el->el_term.t_val);
 	el->el_term.t_val = NULL;
+	el_free((ptr_t) el->el_term.t_fkey);
+	el->el_term.t_fkey = NULL;
 	term_free_display(el);
 }
 
@@ -648,7 +639,8 @@ mc_again:
 				 * from col 0
 				 */
 				if (EL_CAN_TAB ?
-				    (((unsigned int)-del) > (((unsigned int) where >> 3) +
+				    ((unsigned int)-del >
+				    (((unsigned int) where >> 3) +
 				     (where & 07)))
 				    : (-del > where)) {
 					term__putc('\r');	/* do a CR */
@@ -876,6 +868,12 @@ term_clear_to_bottom(EditLine *el)
 }
 #endif
 
+protected void
+term_get(EditLine *el, const char **term)
+{
+	*term = el->el_term.t_name;
+}
+
 
 /* term_set():
  *	Read in the terminal capabilities from the requested terminal
@@ -937,8 +935,11 @@ term_set(EditLine *el, const char *term)
 		/* Get the size */
 		Val(T_co) = tgetnum("co");
 		Val(T_li) = tgetnum("li");
-		for (t = tstr; t->name != NULL; t++)
-			term_alloc(el, t, tgetstr(t->name, &area));
+		for (t = tstr; t->name != NULL; t++) {
+			/* XXX: some systems tgetstr needs non const */
+			term_alloc(el, t, tgetstr(strchr(t->name, *t->name),
+			    &area));
+		}
 	}
 
 	if (Val(T_co) < 2)
@@ -957,6 +958,7 @@ term_set(EditLine *el, const char *term)
 		return (-1);
 	(void) sigprocmask(SIG_SETMASK, &oset, NULL);
 	term_bind_arrow(el);
+	el->el_term.t_name = term;
 	return (i <= 0 ? -1 : 0);
 }
 
@@ -1078,32 +1080,32 @@ term_reset_arrow(EditLine *el)
 	static const char stOH[] = {033, 'O', 'H', '\0'};
 	static const char stOF[] = {033, 'O', 'F', '\0'};
 
-	el_key_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
-	el_key_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
-	el_key_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
-	el_key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
-	el_key_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
-	el_key_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
-	el_key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
-	el_key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
-	el_key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
-	el_key_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
-	el_key_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
-	el_key_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
+	key_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+	key_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+	key_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+	key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+	key_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
+	key_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
+	key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+	key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+	key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+	key_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+	key_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type);
+	key_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type);
 
 	if (el->el_map.type == MAP_VI) {
-		el_key_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
-		el_key_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
-		el_key_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
-		el_key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
-		el_key_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
-		el_key_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
-		el_key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
-		el_key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
-		el_key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
-		el_key_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
-		el_key_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
-		el_key_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
+		key_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+		key_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+		key_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+		key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+		key_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
+		key_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
+		key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type);
+		key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type);
+		key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type);
+		key_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type);
+		key_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type);
+		key_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type);
 	}
 }
 
@@ -1157,7 +1159,7 @@ term_print_arrow(EditLine *el, const char *name)
 	for (i = 0; i < A_K_NKEYS; i++)
 		if (*name == '\0' || strcmp(name, arrow[i].name) == 0)
 			if (arrow[i].type != XK_NOD)
-				el_key_kprint(el, arrow[i].name, &arrow[i].fun,
+				key_kprint(el, arrow[i].name, &arrow[i].fun,
 				    arrow[i].type);
 }
 
@@ -1198,20 +1200,20 @@ term_bind_arrow(EditLine *el)
 			 *    unassigned key.
 		         */
 			if (arrow[i].type == XK_NOD)
-				el_key_clear(el, map, p);
+				key_clear(el, map, p);
 			else {
 				if (p[1] && (dmap[j] == map[j] ||
 					map[j] == ED_SEQUENCE_LEAD_IN)) {
-					el_key_add(el, p, &arrow[i].fun,
+					key_add(el, p, &arrow[i].fun,
 					    arrow[i].type);
 					map[j] = ED_SEQUENCE_LEAD_IN;
 				} else if (map[j] == ED_UNASSIGNED) {
-					el_key_clear(el, map, p);
+					key_clear(el, map, p);
 					if (arrow[i].type == XK_CMD)
 						map[j] = arrow[i].fun.cmd;
 					else
-						el_key_add(el, p, &arrow[i].fun,
-						           arrow[i].type);
+						key_add(el, p, &arrow[i].fun,
+						    arrow[i].type);
 				}
 			}
 		}
@@ -1244,12 +1246,10 @@ term__flush(void)
 /* term_telltc():
  *	Print the current termcap characteristics
  */
-char		*el_key__decode_str(const char *, char *, const char *);
-
 protected int
 /*ARGSUSED*/
-term_telltc(EditLine *el, int argc __attribute__((unused)),
-	    const char **argv __attribute__((unused)))
+term_telltc(EditLine *el, int argc __attribute__((__unused__)), 
+    const char **argv __attribute__((__unused__)))
 {
 	const struct termcapstr *t;
 	char **ts;
@@ -1273,7 +1273,7 @@ term_telltc(EditLine *el, int argc __attribute__((unused)),
 		(void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n",
 		    t->long_name,
 		    t->name, *ts && **ts ?
-		    el_key__decode_str(*ts, upbuf, "") : "(empty)");
+		    key__decode_str(*ts, upbuf, "") : "(empty)");
 	(void) fputc('\n', el->el_outfile);
 	return (0);
 }
@@ -1284,8 +1284,8 @@ term_telltc(EditLine *el, int argc __attribute__((unused)),
  */
 protected int
 /*ARGSUSED*/
-term_settc(EditLine *el, int argc __attribute__((unused)), 
-	   const char **argv __attribute__((unused)))
+term_settc(EditLine *el, int argc __attribute__((__unused__)),
+    const char **argv)
 {
 	const struct termcapstr *ts;
 	const struct termcapval *tv;
@@ -1361,9 +1361,8 @@ term_settc(EditLine *el, int argc __attribute__((unused)),
  */
 protected int
 /*ARGSUSED*/
-term_echotc(EditLine *el __attribute__((unused)), 
-	    int argc __attribute__((unused)),
-	    const char **argv __attribute__((unused)))
+term_echotc(EditLine *el, int argc __attribute__((__unused__)),
+    const char **argv)
 {
 	char *cap, *scap, *ep;
 	int arg_need, arg_cols, arg_rows;
@@ -1422,7 +1421,7 @@ term_echotc(EditLine *el __attribute__((unused)),
 			}
 		(void) fprintf(el->el_outfile, fmtd, 0);
 #else
-		(void) fprintf(el->el_outfile, fmtd, el->el_tty.t_speed);
+		(void) fprintf(el->el_outfile, fmtd, (int)el->el_tty.t_speed);
 #endif
 		return (0);
 	} else if (strcmp(*argv, "rows") == 0 || strcmp(*argv, "lines") == 0) {
@@ -1441,8 +1440,10 @@ term_echotc(EditLine *el __attribute__((unused)),
 			scap = el->el_term.t_str[t - tstr];
 			break;
 		}
-	if (t->name == NULL)
-		scap = tgetstr(*argv, &area);
+	if (t->name == NULL) {
+		/* XXX: some systems tgetstr needs non const */
+		scap = tgetstr(strchr(*argv, **argv), &area);
+	}
 	if (!scap || scap[0] == '\0') {
 		if (!silent)
 			(void) fprintf(el->el_errfile,
diff --git a/cmd-line-utils/libedit/tokenizer.c b/cmd-line-utils/libedit/tokenizer.c
index f6892d9954c16dfa82b84507beac380f92a8e730..561b41740f82d1049ba53c8256015b0333367933 100644
--- a/cmd-line-utils/libedit/tokenizer.c
+++ b/cmd-line-utils/libedit/tokenizer.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: tokenizer.c,v 1.11 2002/10/27 20:24:29 christos Exp $	*/
+/*	$NetBSD: tokenizer.c,v 1.14 2003/12/05 13:37:48 lukem Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,21 +32,14 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)tokenizer.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: tokenizer.c,v 1.11 2002/10/27 20:24:29 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * tokenize.c: Bourne shell like tokenizer
  */
 #include <string.h>
 #include <stdlib.h>
-#include "tokenizer.h"
+#include "histedit.h"
 
 typedef enum {
 	Q_none, Q_single, Q_double, Q_one, Q_doubleone
@@ -64,6 +53,7 @@ typedef enum {
 #define	WINCR		20
 #define	AINCR		10
 
+#define	tok_strdup(a)		strdup(a)
 #define	tok_malloc(a)		malloc(a)
 #define	tok_free(a)		free(a)
 #define	tok_realloc(a, b)	realloc(a, b)
@@ -111,7 +101,7 @@ tok_init(const char *ifs)
 
 	if (tok == NULL)
 		return NULL;
-	tok->ifs = strdup(ifs ? ifs : IFS);
+	tok->ifs = tok_strdup(ifs ? ifs : IFS);
 	if (tok->ifs == NULL) {
 		tok_free((ptr_t)tok);
 		return NULL;
@@ -173,21 +163,39 @@ tok_end(Tokenizer *tok)
 
 
 /* tok_line():
- *	Bourne shell like tokenizing
- *	Return:
- *		-1: Internal error
- *		 3: Quoted return
- *		 2: Unmatched double quote
- *		 1: Unmatched single quote
- *		 0: Ok
+ *	Bourne shell (sh(1)) like tokenizing
+ *	Arguments:
+ *		tok	current tokenizer state (setup with tok_init())
+ *		line	line to parse
+ *	Returns:
+ *		-1	Internal error
+ *		 3	Quoted return
+ *		 2	Unmatched double quote
+ *		 1	Unmatched single quote
+ *		 0	Ok
+ *	Modifies (if return value is 0):
+ *		argc	number of arguments
+ *		argv	argument array
+ *		cursorc	if !NULL, argv element containing cursor
+ *		cursorv	if !NULL, offset in argv[cursorc] of cursor
  */
 public int
-tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv)
+tok_line(Tokenizer *tok, const LineInfo *line,
+    int *argc, const char ***argv, int *cursorc, int *cursoro)
 {
 	const char *ptr;
-
-	for (;;) {
-		switch (*(ptr = line++)) {
+	int cc, co;
+
+	cc = co = -1;
+	ptr = line->buffer;
+	for (ptr = line->buffer; ;ptr++) {
+		if (ptr >= line->lastchar)
+			ptr = "";
+		if (ptr == line->cursor) {
+			cc = tok->argc;
+			co = tok->wptr - tok->wstart;
+		}
+		switch (*ptr) {
 		case '\'':
 			tok->flags |= TOK_KEEP;
 			tok->flags &= ~TOK_EAT;
@@ -286,10 +294,7 @@ tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv)
 			tok->flags &= ~TOK_EAT;
 			switch (tok->quote) {
 			case Q_none:
-				tok_finish(tok);
-				*argv = (const char **)tok->argv;
-				*argc = tok->argc;
-				return (0);
+				goto tok_line_outok;
 
 			case Q_single:
 			case Q_double:
@@ -319,10 +324,7 @@ tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv)
 					tok->flags &= ~TOK_EAT;
 					return (3);
 				}
-				tok_finish(tok);
-				*argv = (const char **)tok->argv;
-				*argc = tok->argc;
-				return (0);
+				goto tok_line_outok;
 
 			case Q_single:
 				return (1);
@@ -407,4 +409,32 @@ tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv)
 			tok->argv = p;
 		}
 	}
+ tok_line_outok:
+	if (cc == -1 && co == -1) {
+		cc = tok->argc;
+		co = tok->wptr - tok->wstart;
+	}
+	if (cursorc != NULL)
+		*cursorc = cc;
+	if (cursoro != NULL)
+		*cursoro = co;
+	tok_finish(tok);
+	*argv = (const char **)tok->argv;
+	*argc = tok->argc;
+	return (0);
+}
+
+/* tok_str():
+ *	Simpler version of tok_line, taking a NUL terminated line
+ *	and splitting into words, ignoring cursor state.
+ */
+public int
+tok_str(Tokenizer *tok, const char *line, int *argc, const char ***argv)
+{
+	LineInfo li;
+
+	memset(&li, 0, sizeof(li));
+	li.buffer = line;
+	li.cursor = li.lastchar = strchr(line, '\0');
+	return (tok_line(tok, &li, argc, argv, NULL, NULL));
 }
diff --git a/cmd-line-utils/libedit/tty.c b/cmd-line-utils/libedit/tty.c
index fe81762fb8231555d0adb6dcf443304b5e696b53..6f73fb4f9e77e367d45716c17da55ed85670e0d1 100644
--- a/cmd-line-utils/libedit/tty.c
+++ b/cmd-line-utils/libedit/tty.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: tty.c,v 1.16 2002/03/18 16:01:01 christos Exp $	*/
+/*	$NetBSD: tty.c,v 1.21 2004/08/13 12:10:39 mycroft Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,18 +32,12 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)tty.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: tty.c,v 1.16 2002/03/18 16:01:01 christos Exp $");
-#endif
-#endif /* not lint && not SCCSID */
+#include <config.h>
 
 /*
  * tty.c: tty interface stuff
  */
+#include <assert.h>
 #include "tty.h"
 #include "el.h"
 
@@ -124,11 +114,11 @@ private const ttychar_t ttychar = {
 private const ttymap_t tty_map[] = {
 #ifdef VERASE
 	{C_ERASE, VERASE,
-	{ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
+	{EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
 #endif /* VERASE */
 #ifdef VERASE2
 	{C_ERASE2, VERASE2,
-	{ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
+	{EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
 #endif /* VERASE2 */
 #ifdef VKILL
 	{C_KILL, VKILL,
@@ -455,6 +445,7 @@ private const ttymodes_t ttymodes[] = {
 #define	tty__geteightbit(td)	(((td)->c_cflag & CSIZE) == CS8)
 #define	tty__cooked_mode(td)	((td)->c_lflag & ICANON)
 
+private int	tty__getcharindex(int);
 private void	tty__getchar(struct termios *, unsigned char *);
 private void	tty__setchar(struct termios *, unsigned char *);
 private speed_t	tty__getspeed(struct termios *);
@@ -568,7 +559,7 @@ tty_init(EditLine *el)
  */
 protected void
 /*ARGSUSED*/
-tty_end(EditLine *el __attribute__((unused)))
+tty_end(EditLine *el __attribute__((__unused__)))
 {
 
 	/* XXX: Maybe reset to an initial state? */
@@ -588,6 +579,113 @@ tty__getspeed(struct termios *td)
 	return (spd);
 }
 
+/* tty__getspeed():
+ *	Return the index of the asked char in the c_cc array
+ */
+private int
+tty__getcharindex(int i)
+{
+	switch (i) {
+#ifdef VINTR
+	case C_INTR:
+		return VINTR;
+#endif /* VINTR */
+#ifdef VQUIT
+	case C_QUIT:
+		return VQUIT;
+#endif /* VQUIT */
+#ifdef VERASE
+	case C_ERASE:
+		return VERASE;
+#endif /* VERASE */
+#ifdef VKILL
+	case C_KILL:
+		return VKILL;
+#endif /* VKILL */
+#ifdef VEOF
+	case C_EOF:
+		return VEOF;
+#endif /* VEOF */
+#ifdef VEOL
+	case C_EOL:
+		return VEOL;
+#endif /* VEOL */
+#ifdef VEOL2
+	case C_EOL2:
+		return VEOL2;
+#endif /* VEOL2 */
+#ifdef VSWTCH
+	case C_SWTCH:
+		return VSWTCH;
+#endif /* VSWTCH */
+#ifdef VDSWTCH
+	case C_DSWTCH:
+		return VDSWTCH;
+#endif /* VDSWTCH */
+#ifdef VERASE2
+	case C_ERASE2:
+		return VERASE2;
+#endif /* VERASE2 */
+#ifdef VSTART
+	case C_START:
+		return VSTART;
+#endif /* VSTART */
+#ifdef VSTOP
+	case C_STOP:
+		return VSTOP;
+#endif /* VSTOP */
+#ifdef VWERASE
+	case C_WERASE:
+		return VWERASE;
+#endif /* VWERASE */
+#ifdef VSUSP
+	case C_SUSP:
+		return VSUSP;
+#endif /* VSUSP */
+#ifdef VDSUSP
+	case C_DSUSP:
+		return VDSUSP;
+#endif /* VDSUSP */
+#ifdef VREPRINT
+	case C_REPRINT:
+		return VREPRINT;
+#endif /* VREPRINT */
+#ifdef VDISCARD
+	case C_DISCARD:
+		return VDISCARD;
+#endif /* VDISCARD */
+#ifdef VLNEXT
+	case C_LNEXT:
+		return VLNEXT;
+#endif /* VLNEXT */
+#ifdef VSTATUS
+	case C_STATUS:
+		return VSTATUS;
+#endif /* VSTATUS */
+#ifdef VPAGE
+	case C_PAGE:
+		return VPAGE;
+#endif /* VPAGE */
+#ifdef VPGOFF
+	case C_PGOFF:
+		return VPGOFF;
+#endif /* VPGOFF */
+#ifdef VKILL2
+	case C_KILL2:
+		return VKILL2;
+#endif /* KILL2 */
+#ifdef VMIN
+	case C_MIN:
+		return VMIN;
+#endif /* VMIN */
+#ifdef VTIME
+	case C_TIME:
+		return VTIME;
+#endif /* VTIME */
+	default:
+		return -1;
+	}
+}
 
 /* tty__getchar():
  *	Get the tty characters
@@ -784,15 +882,15 @@ tty_bind_char(EditLine *el, int force)
 		if (new[0] == old[0] && !force)
 			continue;
 		/* Put the old default binding back, and set the new binding */
-		el_key_clear(el, map, (char *)old);
+		key_clear(el, map, (char *)old);
 		map[old[0]] = dmap[old[0]];
-		el_key_clear(el, map, (char *)new);
+		key_clear(el, map, (char *)new);
 		/* MAP_VI == 1, MAP_EMACS == 0... */
 		map[new[0]] = tp->bind[el->el_map.type];
 		if (dalt) {
-			el_key_clear(el, alt, (char *)old);
+			key_clear(el, alt, (char *)old);
 			alt[old[0]] = dalt[old[0]];
-			el_key_clear(el, alt, (char *)new);
+			key_clear(el, alt, (char *)new);
 			alt[new[0]] = tp->bind[el->el_map.type + 1];
 		}
 	}
@@ -1041,13 +1139,14 @@ tty_noquotemode(EditLine *el)
  */
 protected int
 /*ARGSUSED*/
-tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv)
+tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
 {
 	const ttymodes_t *m;
 	char x;
 	int aflag = 0;
 	const char *s, *d;
 	const char *name;
+	struct termios *tios = &el->el_tty.t_ex;
 	int z = EX_IO;
 
 	if (argv == NULL)
@@ -1062,14 +1161,17 @@ tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv)
 			break;
 		case 'd':
 			argv++;
+			tios = &el->el_tty.t_ed;
 			z = ED_IO;
 			break;
 		case 'x':
 			argv++;
+			tios = &el->el_tty.t_ex;
 			z = EX_IO;
 			break;
 		case 'q':
 			argv++;
+			tios = &el->el_tty.t_ts;
 			z = QU_IO;
 			break;
 		default:
@@ -1119,6 +1221,7 @@ tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv)
 		return (0);
 	}
 	while (argv && (s = *argv++)) {
+		char *p;
 		switch (*s) {
 		case '+':
 		case '-':
@@ -1129,8 +1232,11 @@ tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv)
 			break;
 		}
 		d = s;
+		if ((p = strchr(s, '=')) != NULL)
+			*p++ = '\0';
 		for (m = ttymodes; m->m_name; m++)
-			if (strcmp(m->m_name, d) == 0)
+			if (strcmp(m->m_name, d) == 0 &&
+			    (p == NULL || m->m_type == MD_CHAR))
 				break;
 
 		if (!m->m_name) {
@@ -1138,6 +1244,16 @@ tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv)
 			    "%s: Invalid argument `%s'.\n", name, d);
 			return (-1);
 		}
+		if (p) {
+			int c = ffs((int)m->m_value);
+			int v = *p ? parse__escape((const char **const) &p) :
+			    el->el_tty.t_vdisable;
+			assert(c-- != 0);
+			c = tty__getcharindex(c);
+			assert(c != -1);
+			tios->c_cc[c] = v;
+			continue;
+		}
 		switch (x) {
 		case '+':
 			el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;
diff --git a/cmd-line-utils/libedit/tty.h b/cmd-line-utils/libedit/tty.h
index e9597fceb2be8fb289676b3f72d9217cc19c1b48..cc7c4ad8c6676c36aa69934ec6a9a34226017292 100644
--- a/cmd-line-utils/libedit/tty.h
+++ b/cmd-line-utils/libedit/tty.h
@@ -1,4 +1,4 @@
-/*	$NetBSD: tty.h,v 1.9 2002/03/18 16:01:01 christos Exp $	*/
+/*	$NetBSD: tty.h,v 1.10 2003/08/07 16:44:34 agc Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
diff --git a/cmd-line-utils/libedit/unvis.c b/cmd-line-utils/libedit/unvis.c
new file mode 100644
index 0000000000000000000000000000000000000000..ffa8ac4251c4d0cee5c805f672e667f3f44f44f0
--- /dev/null
+++ b/cmd-line-utils/libedit/unvis.c
@@ -0,0 +1,311 @@
+/*	$NetBSD: unvis.c,v 1.24 2003/08/07 16:42:59 agc Exp $	*/
+
+/*-
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * 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. 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.
+ */
+
+#include <config.h>
+
+#define __LIBC12_SOURCE__
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <vis.h>
+
+#ifdef __weak_alias
+__weak_alias(strunvis,_strunvis)
+__weak_alias(unvis,_unvis)
+#endif
+
+#ifdef __warn_references
+__warn_references(unvis,
+    "warning: reference to compatibility unvis(); include <vis.h> for correct reference")
+#endif
+
+#if !HAVE_VIS
+/*
+ * decode driven by state machine
+ */
+#define	S_GROUND	0	/* haven't seen escape char */
+#define	S_START		1	/* start decoding special sequence */
+#define	S_META		2	/* metachar started (M) */
+#define	S_META1		3	/* metachar more, regular char (-) */
+#define	S_CTRL		4	/* control char started (^) */
+#define	S_OCTAL2	5	/* octal digit 2 */
+#define	S_OCTAL3	6	/* octal digit 3 */
+#define S_HEX1		7	/* hex digit */
+#define S_HEX2		8	/* hex digit 2 */
+
+#define	isoctal(c)	(((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
+#define xtod(c)		(isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10))
+
+int
+unvis(cp, c, astate, flag)
+	char *cp;
+	int c;
+	int *astate, flag;
+{
+	return __unvis13(cp, (int)c, astate, flag);
+}
+
+/*
+ * unvis - decode characters previously encoded by vis
+ */
+int
+__unvis13(cp, c, astate, flag)
+	char *cp;
+	int c;
+	int *astate, flag;
+{
+
+	_DIAGASSERT(cp != NULL);
+	_DIAGASSERT(astate != NULL);
+
+	if (flag & UNVIS_END) {
+		if (*astate == S_OCTAL2 || *astate == S_OCTAL3
+		    || *astate == S_HEX2) {
+			*astate = S_GROUND;
+			return (UNVIS_VALID);
+		} 
+		return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
+	}
+
+	switch (*astate) {
+
+	case S_GROUND:
+		*cp = 0;
+		if (c == '\\') {
+			*astate = S_START;
+			return (0);
+		} 
+		if ((flag & VIS_HTTPSTYLE) && c == '%') {
+			*astate = S_HEX1;
+			return (0);
+		}
+		*cp = c;
+		return (UNVIS_VALID);
+
+	case S_START:
+		switch(c) {
+		case '\\':
+			*cp = c;
+			*astate = S_GROUND;
+			return (UNVIS_VALID);
+		case '0': case '1': case '2': case '3':
+		case '4': case '5': case '6': case '7':
+			*cp = (c - '0');
+			*astate = S_OCTAL2;
+			return (0);
+		case 'M':
+			*cp = (char)0200;
+			*astate = S_META;
+			return (0);
+		case '^':
+			*astate = S_CTRL;
+			return (0);
+		case 'n':
+			*cp = '\n';
+			*astate = S_GROUND;
+			return (UNVIS_VALID);
+		case 'r':
+			*cp = '\r';
+			*astate = S_GROUND;
+			return (UNVIS_VALID);
+		case 'b':
+			*cp = '\b';
+			*astate = S_GROUND;
+			return (UNVIS_VALID);
+		case 'a':
+			*cp = '\007';
+			*astate = S_GROUND;
+			return (UNVIS_VALID);
+		case 'v':
+			*cp = '\v';
+			*astate = S_GROUND;
+			return (UNVIS_VALID);
+		case 't':
+			*cp = '\t';
+			*astate = S_GROUND;
+			return (UNVIS_VALID);
+		case 'f':
+			*cp = '\f';
+			*astate = S_GROUND;
+			return (UNVIS_VALID);
+		case 's':
+			*cp = ' ';
+			*astate = S_GROUND;
+			return (UNVIS_VALID);
+		case 'E':
+			*cp = '\033';
+			*astate = S_GROUND;
+			return (UNVIS_VALID);
+		case '\n':
+			/*
+			 * hidden newline
+			 */
+			*astate = S_GROUND;
+			return (UNVIS_NOCHAR);
+		case '$':
+			/*
+			 * hidden marker
+			 */
+			*astate = S_GROUND;
+			return (UNVIS_NOCHAR);
+		}
+		*astate = S_GROUND;
+		return (UNVIS_SYNBAD);
+		 
+	case S_META:
+		if (c == '-')
+			*astate = S_META1;
+		else if (c == '^')
+			*astate = S_CTRL;
+		else {
+			*astate = S_GROUND;
+			return (UNVIS_SYNBAD);
+		}
+		return (0);
+		 
+	case S_META1:
+		*astate = S_GROUND;
+		*cp |= c;
+		return (UNVIS_VALID);
+		 
+	case S_CTRL:
+		if (c == '?')
+			*cp |= 0177;
+		else
+			*cp |= c & 037;
+		*astate = S_GROUND;
+		return (UNVIS_VALID);
+
+	case S_OCTAL2:	/* second possible octal digit */
+		if (isoctal(c)) {
+			/* 
+			 * yes - and maybe a third 
+			 */
+			*cp = (*cp << 3) + (c - '0');
+			*astate = S_OCTAL3;	
+			return (0);
+		} 
+		/* 
+		 * no - done with current sequence, push back passed char 
+		 */
+		*astate = S_GROUND;
+		return (UNVIS_VALIDPUSH);
+
+	case S_OCTAL3:	/* third possible octal digit */
+		*astate = S_GROUND;
+		if (isoctal(c)) {
+			*cp = (*cp << 3) + (c - '0');
+			return (UNVIS_VALID);
+		}
+		/*
+		 * we were done, push back passed char
+		 */
+		return (UNVIS_VALIDPUSH);
+	case S_HEX1:
+		if (isxdigit(c)) {
+			*cp = xtod(c);
+			*astate = S_HEX2;
+			return (0);
+		}
+		/* 
+		 * no - done with current sequence, push back passed char 
+		 */
+		*astate = S_GROUND;
+		return (UNVIS_VALIDPUSH);
+	case S_HEX2:
+                *astate = S_GROUND;
+                if (isxdigit(c)) {
+                        *cp = xtod(c) | (*cp << 4);
+			return (UNVIS_VALID);
+		}
+                return (UNVIS_VALIDPUSH);
+	default:	
+		/* 
+		 * decoder in unknown state - (probably uninitialized) 
+		 */
+		*astate = S_GROUND;
+		return (UNVIS_SYNBAD);
+	}
+}
+
+/*
+ * strunvis - decode src into dst 
+ *
+ *	Number of chars decoded into dst is returned, -1 on error.
+ *	Dst is null terminated.
+ */
+
+int
+strunvisx(dst, src, flag)
+	char *dst;
+	const char *src;
+	int flag;
+{
+	char c;
+	char *start = dst;
+	int state = 0;
+
+	_DIAGASSERT(src != NULL);
+	_DIAGASSERT(dst != NULL);
+
+	while ((c = *src++) != '\0') {
+	again:
+		switch (__unvis13(dst, c, &state, flag)) {
+		case UNVIS_VALID:
+			dst++;
+			break;
+		case UNVIS_VALIDPUSH:
+			dst++;
+			goto again;
+		case 0:
+		case UNVIS_NOCHAR:
+			break;
+		default:
+			return (-1);
+		}
+	}
+	if (__unvis13(dst, c, &state, UNVIS_END) == UNVIS_VALID)
+		dst++;
+	*dst = '\0';
+	return (dst - start);
+}
+
+int
+strunvis(dst, src)
+	char *dst;
+	const char *src;
+{
+	return strunvisx(dst, src, 0);
+}
+#endif
diff --git a/cmd-line-utils/libedit/vi.c b/cmd-line-utils/libedit/vi.c
index 5380872cf65315f7aef8e6d01b8535a95396622d..4a0352859ddc6afacecf0c55d074423311a8e3f6 100644
--- a/cmd-line-utils/libedit/vi.c
+++ b/cmd-line-utils/libedit/vi.c
@@ -1,4 +1,4 @@
-/*	$NetBSD: vi.c,v 1.16 2003/03/10 11:09:25 dsl Exp $	*/
+/*	$NetBSD: vi.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -15,11 +15,7 @@
  * 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. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by the University of
- *	California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
+ * 3. 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.
  *
@@ -36,18 +32,11 @@
  * SUCH DAMAGE.
  */
 
-#include "config.h"
+#include <config.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/wait.h>
 
-#if !defined(lint) && !defined(SCCSID)
-#if 0
-static char sccsid[] = "@(#)vi.c	8.1 (Berkeley) 6/4/93";
-#else
-__RCSID("$NetBSD: vi.c,v 1.16 2003/03/10 11:09:25 dsl Exp $");
-#endif
-#endif /* not lint && not SCCSID */
 
 /*
  * vi.c: Vi mode commands.
@@ -123,7 +112,7 @@ cv_paste(EditLine *el, int c)
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_paste_next(EditLine *el, int c __attribute__((unused)))
+vi_paste_next(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	return (cv_paste(el, 0));
@@ -136,7 +125,7 @@ vi_paste_next(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_paste_prev(EditLine *el, int c __attribute__((unused)))
+vi_paste_prev(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	return (cv_paste(el, 1));
@@ -149,7 +138,7 @@ vi_paste_prev(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_prev_big_word(EditLine *el, int c __attribute__((unused)))
+vi_prev_big_word(EditLine *el, int c)
 {
 
 	if (el->el_line.cursor == el->el_line.buffer)
@@ -174,7 +163,7 @@ vi_prev_big_word(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_prev_word(EditLine *el, int c __attribute__((unused)))
+vi_prev_word(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_line.cursor == el->el_line.buffer)
@@ -199,7 +188,7 @@ vi_prev_word(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_next_big_word(EditLine *el, int c __attribute__((unused)))
+vi_next_big_word(EditLine *el, int c)
 {
 
 	if (el->el_line.cursor >= el->el_line.lastchar - 1)
@@ -223,7 +212,7 @@ vi_next_big_word(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_next_word(EditLine *el, int c __attribute__((unused)))
+vi_next_word(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_line.cursor >= el->el_line.lastchar - 1)
@@ -278,7 +267,7 @@ vi_change_case(EditLine *el, int c)
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_change_meta(EditLine *el, int c __attribute__((unused)))
+vi_change_meta(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	/*
@@ -295,7 +284,7 @@ vi_change_meta(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_insert_at_bol(EditLine *el, int c __attribute__((unused)))
+vi_insert_at_bol(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_line.cursor = el->el_line.buffer;
@@ -311,7 +300,7 @@ vi_insert_at_bol(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_replace_char(EditLine *el, int c __attribute__((unused)))
+vi_replace_char(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_line.cursor >= el->el_line.lastchar)
@@ -330,7 +319,7 @@ vi_replace_char(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_replace_mode(EditLine *el, int c __attribute__((unused)))
+vi_replace_mode(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_map.current = el->el_map.key;
@@ -346,7 +335,7 @@ vi_replace_mode(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_substitute_char(EditLine *el, int c __attribute__((unused)))
+vi_substitute_char(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	c_delafter(el, el->el_state.argument);
@@ -361,7 +350,7 @@ vi_substitute_char(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_substitute_line(EditLine *el, int c __attribute__((unused)))
+vi_substitute_line(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	cv_undo(el);
@@ -379,7 +368,7 @@ vi_substitute_line(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_change_to_eol(EditLine *el, int c __attribute__((unused)))
+vi_change_to_eol(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	cv_undo(el);
@@ -397,7 +386,7 @@ vi_change_to_eol(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_insert(EditLine *el, int c __attribute__((unused)))
+vi_insert(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_map.current = el->el_map.key;
@@ -412,7 +401,7 @@ vi_insert(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_add(EditLine *el, int c __attribute__((unused)))
+vi_add(EditLine *el, int c __attribute__((__unused__)))
 {
 	int ret;
 
@@ -437,7 +426,7 @@ vi_add(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_add_at_eol(EditLine *el, int c __attribute__((unused)))
+vi_add_at_eol(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	el->el_map.current = el->el_map.key;
@@ -453,7 +442,7 @@ vi_add_at_eol(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_delete_meta(EditLine *el, int c __attribute__((unused)))
+vi_delete_meta(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	return (cv_action(el, DELETE));
@@ -466,7 +455,7 @@ vi_delete_meta(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_end_big_word(EditLine *el, int c __attribute__((unused)))
+vi_end_big_word(EditLine *el, int c)
 {
 
 	if (el->el_line.cursor == el->el_line.lastchar)
@@ -490,7 +479,7 @@ vi_end_big_word(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_end_word(EditLine *el, int c __attribute__((unused)))
+vi_end_word(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_line.cursor == el->el_line.lastchar)
@@ -514,7 +503,7 @@ vi_end_word(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_undo(EditLine *el, int c __attribute__((unused)))
+vi_undo(EditLine *el, int c __attribute__((__unused__)))
 {
 	c_undo_t un = el->el_chared.c_undo;
 
@@ -540,7 +529,7 @@ vi_undo(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_command_mode(EditLine *el, int c __attribute__((unused)))
+vi_command_mode(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	/* [Esc] cancels pending action */
@@ -585,20 +574,14 @@ vi_zero(EditLine *el, int c)
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_delete_prev_char(EditLine *el, int c __attribute__((unused)))
+vi_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
 {
-	char *cp;
 
-	cp = el->el_line.cursor;
-	if (cp <= el->el_line.buffer)
+	if (el->el_line.cursor <= el->el_line.buffer)
 		return (CC_ERROR);
 
-	/* do the delete here so we dont mess up the undo and paste buffers */
-	el->el_line.cursor = --cp;
-	for (; cp < el->el_line.lastchar; cp++)
-		cp[0] = cp[1];
-	el->el_line.lastchar = cp - 1;
-
+	c_delbefore1(el);
+	el->el_line.cursor--;
 	return (CC_REFRESH);
 }
 
@@ -609,23 +592,35 @@ vi_delete_prev_char(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_list_or_eof(EditLine *el, int c __attribute__((unused)))
+vi_list_or_eof(EditLine *el, int c __attribute__((__unused__)))
 {
 
-#ifdef notyet
-	if (el->el_line.cursor == el->el_line.lastchar &&
-	    el->el_line.cursor == el->el_line.buffer) {
-#endif
-		term_overwrite(el, STReof, 4);	/* then do a EOF */
-		term__flush();
-		return (CC_EOF);
-#ifdef notyet
+	if (el->el_line.cursor == el->el_line.lastchar) {
+		if (el->el_line.cursor == el->el_line.buffer) {
+			term_overwrite(el, STReof, 4);	/* then do a EOF */
+			term__flush();
+			return (CC_EOF);
+		} else {
+			/*
+			 * Here we could list completions, but it is an
+			 * error right now
+			 */
+			term_beep(el);
+			return (CC_ERROR);
+		}
 	} else {
+#ifdef notyet
 		re_goto_bottom(el);
 		*el->el_line.lastchar = '\0';	/* just in case */
 		return (CC_LIST_CHOICES);
-	}
+#else
+		/*
+		 * Just complain for now.
+		 */
+		term_beep(el);
+		return (CC_ERROR);
 #endif
+	}
 }
 
 
@@ -635,7 +630,7 @@ vi_list_or_eof(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_kill_line_prev(EditLine *el, int c __attribute__((unused)))
+vi_kill_line_prev(EditLine *el, int c __attribute__((__unused__)))
 {
 	char *kp, *cp;
 
@@ -656,7 +651,7 @@ vi_kill_line_prev(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_search_prev(EditLine *el, int c __attribute__((unused)))
+vi_search_prev(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	return (cv_search(el, ED_SEARCH_PREV_HISTORY));
@@ -669,7 +664,7 @@ vi_search_prev(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_search_next(EditLine *el, int c __attribute__((unused)))
+vi_search_next(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	return (cv_search(el, ED_SEARCH_NEXT_HISTORY));
@@ -682,7 +677,7 @@ vi_search_next(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_repeat_search_next(EditLine *el, int c __attribute__((unused)))
+vi_repeat_search_next(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_search.patlen == 0)
@@ -698,7 +693,7 @@ vi_repeat_search_next(EditLine *el, int c __attribute__((unused)))
  */
 /*ARGSUSED*/
 protected el_action_t
-vi_repeat_search_prev(EditLine *el, int c __attribute__((unused)))
+vi_repeat_search_prev(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	if (el->el_search.patlen == 0)
@@ -716,7 +711,7 @@ vi_repeat_search_prev(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_next_char(EditLine *el, int c __attribute__((unused)))
+vi_next_char(EditLine *el, int c __attribute__((__unused__)))
 {
 	return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0);
 }
@@ -728,7 +723,7 @@ vi_next_char(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_prev_char(EditLine *el, int c __attribute__((unused)))
+vi_prev_char(EditLine *el, int c __attribute__((__unused__)))
 {
 	return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0);
 }
@@ -740,7 +735,7 @@ vi_prev_char(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_to_next_char(EditLine *el, int c __attribute__((unused)))
+vi_to_next_char(EditLine *el, int c __attribute__((__unused__)))
 {
 	return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1);
 }
@@ -752,7 +747,7 @@ vi_to_next_char(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_to_prev_char(EditLine *el, int c __attribute__((unused)))
+vi_to_prev_char(EditLine *el, int c __attribute__((__unused__)))
 {
 	return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1);
 }
@@ -764,7 +759,7 @@ vi_to_prev_char(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_repeat_next_char(EditLine *el, int c __attribute__((unused)))
+vi_repeat_next_char(EditLine *el, int c __attribute__((__unused__)))
 {
 
 	return cv_csearch(el, el->el_search.chadir, el->el_search.chacha,
@@ -778,7 +773,7 @@ vi_repeat_next_char(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_repeat_prev_char(EditLine *el, int c __attribute__((unused)))
+vi_repeat_prev_char(EditLine *el, int c __attribute__((__unused__)))
 {
 	el_action_t r;
 	int dir = el->el_search.chadir;
@@ -796,7 +791,7 @@ vi_repeat_prev_char(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_match(EditLine *el, int c __attribute__((unused)))
+vi_match(EditLine *el, int c)
 {
 	const char match_chars[] = "()[]{}";
 	char *cp;
@@ -843,7 +838,7 @@ vi_match(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_undo_line(EditLine *el, int c __attribute__((unused)))
+vi_undo_line(EditLine *el, int c)
 {
 
 	cv_undo(el);
@@ -857,7 +852,7 @@ vi_undo_line(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_to_column(EditLine *el, int c __attribute__((unused)))
+vi_to_column(EditLine *el, int c)
 {
 
 	el->el_line.cursor = el->el_line.buffer;
@@ -871,7 +866,7 @@ vi_to_column(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_yank_end(EditLine *el, int c __attribute__((unused)))
+vi_yank_end(EditLine *el, int c)
 {
 
 	cv_yank(el, el->el_line.cursor,
@@ -885,7 +880,7 @@ vi_yank_end(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_yank(EditLine *el, int c __attribute__((unused)))
+vi_yank(EditLine *el, int c)
 {
 
 	return cv_action(el, YANK);
@@ -897,7 +892,7 @@ vi_yank(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_comment_out(EditLine *el, int c __attribute__((unused)))
+vi_comment_out(EditLine *el, int c)
 {
 
 	el->el_line.cursor = el->el_line.buffer;
@@ -915,7 +910,7 @@ vi_comment_out(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_alias(EditLine *el __attribute__((unused)), int c __attribute__((unused)))
+vi_alias(EditLine *el, int c)
 {
 #ifdef __weak_extern
 	char alias_name[3];
@@ -947,7 +942,7 @@ vi_alias(EditLine *el __attribute__((unused)), int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_to_history_line(EditLine *el, int c __attribute__((unused)))
+vi_to_history_line(EditLine *el, int c)
 {
 	int sv_event_no = el->el_history.eventno;
 	el_action_t rval;
@@ -992,7 +987,7 @@ vi_to_history_line(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_histedit(EditLine *el, int c __attribute__((unused)))
+vi_histedit(EditLine *el, int c)
 {
 	int fd;
 	pid_t pid;
@@ -1048,7 +1043,7 @@ vi_histedit(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_history_word(EditLine *el, int c __attribute__((unused)))
+vi_history_word(EditLine *el, int c)
 {
 	const char *wp = HIST_FIRST(el);
 	const char *wep, *wsp;
@@ -1097,7 +1092,7 @@ vi_history_word(EditLine *el, int c __attribute__((unused)))
  */
 protected el_action_t
 /*ARGSUSED*/
-vi_redo(EditLine *el, int c __attribute__((unused)))
+vi_redo(EditLine *el, int c)
 {
 	c_redo_t *r = &el->el_chared.c_redo;
 
diff --git a/cmd-line-utils/libedit/vis.c b/cmd-line-utils/libedit/vis.c
new file mode 100644
index 0000000000000000000000000000000000000000..127d28733a8a5908333be869769d218c0bbfd43a
--- /dev/null
+++ b/cmd-line-utils/libedit/vis.c
@@ -0,0 +1,392 @@
+/*	$NetBSD: vis.c,v 1.27 2004/02/26 23:01:15 enami Exp $	*/
+
+/*-
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 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.
+ */
+
+/*-
+ * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ *
+ * 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. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 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.
+ */
+
+/* AIX requires this to be the first thing in the file.  */
+#if defined (_AIX) && !defined (__GNUC__)
+ #pragma alloca
+#endif
+
+#include <config.h>
+
+#ifdef __GNUC__
+# undef alloca
+# define alloca(n) __builtin_alloca (n)
+#else
+# ifdef HAVE_ALLOCA_H
+#  include <alloca.h>
+# else
+#  ifndef _AIX
+extern char *alloca ();
+#  endif
+# endif
+#endif
+
+#include <sys/types.h>
+
+#include <assert.h>
+#include <vis.h>
+#include <stdlib.h>
+
+#ifdef __weak_alias
+__weak_alias(strsvis,_strsvis)
+__weak_alias(strsvisx,_strsvisx)
+__weak_alias(strvis,_strvis)
+__weak_alias(strvisx,_strvisx)
+__weak_alias(svis,_svis)
+__weak_alias(vis,_vis)
+#endif
+
+#if !HAVE_VIS || !HAVE_SVIS
+#include <ctype.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#undef BELL
+#define BELL '\a'
+
+#define isoctal(c)	(((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
+#define iswhite(c)	(c == ' ' || c == '\t' || c == '\n')
+#define issafe(c)	(c == '\b' || c == BELL || c == '\r')
+#define xtoa(c)		"0123456789abcdef"[c]
+
+#define MAXEXTRAS	5
+
+
+#define MAKEEXTRALIST(flag, extra, orig)				      \
+do {									      \
+	const char *o = orig;						      \
+	char *e;							      \
+	while (*o++)							      \
+		continue;						      \
+	extra = alloca((size_t)((o - orig) + MAXEXTRAS));		      \
+	for (o = orig, e = extra; (*e++ = *o++) != '\0';)		      \
+		continue;						      \
+	e--;								      \
+	if (flag & VIS_SP) *e++ = ' ';					      \
+	if (flag & VIS_TAB) *e++ = '\t';				      \
+	if (flag & VIS_NL) *e++ = '\n';					      \
+	if ((flag & VIS_NOSLASH) == 0) *e++ = '\\';			      \
+	*e = '\0';							      \
+} while (/*CONSTCOND*/0)
+
+
+/*
+ * This is HVIS, the macro of vis used to HTTP style (RFC 1808)
+ */
+#define HVIS(dst, c, flag, nextc, extra)				      \
+do									      \
+	if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { \
+		*dst++ = '%';						      \
+		*dst++ = xtoa(((unsigned int)c >> 4) & 0xf);		      \
+		*dst++ = xtoa((unsigned int)c & 0xf);			      \
+	} else {							      \
+		SVIS(dst, c, flag, nextc, extra);			      \
+	}								      \
+while (/*CONSTCOND*/0)
+
+/*
+ * This is SVIS, the central macro of vis.
+ * dst:	      Pointer to the destination buffer
+ * c:	      Character to encode
+ * flag:      Flag word
+ * nextc:     The character following 'c'
+ * extra:     Pointer to the list of extra characters to be
+ *	      backslash-protected.
+ */
+#define SVIS(dst, c, flag, nextc, extra)				      \
+do {									      \
+	int isextra;							      \
+	isextra = strchr(extra, c) != NULL;				      \
+	if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) ||	      \
+	    ((flag & VIS_SAFE) && issafe(c)))) {			      \
+		*dst++ = c;						      \
+		break;							      \
+	}								      \
+	if (flag & VIS_CSTYLE) {					      \
+		switch (c) {						      \
+		case '\n':						      \
+			*dst++ = '\\'; *dst++ = 'n';			      \
+			continue;					      \
+		case '\r':						      \
+			*dst++ = '\\'; *dst++ = 'r';			      \
+			continue;					      \
+		case '\b':						      \
+			*dst++ = '\\'; *dst++ = 'b';			      \
+			continue;					      \
+		case BELL:						      \
+			*dst++ = '\\'; *dst++ = 'a';			      \
+			continue;					      \
+		case '\v':						      \
+			*dst++ = '\\'; *dst++ = 'v';			      \
+			continue;					      \
+		case '\t':						      \
+			*dst++ = '\\'; *dst++ = 't';			      \
+			continue;					      \
+		case '\f':						      \
+			*dst++ = '\\'; *dst++ = 'f';			      \
+			continue;					      \
+		case ' ':						      \
+			*dst++ = '\\'; *dst++ = 's';			      \
+			continue;					      \
+		case '\0':						      \
+			*dst++ = '\\'; *dst++ = '0';			      \
+			if (isoctal(nextc)) {				      \
+				*dst++ = '0';				      \
+				*dst++ = '0';				      \
+			}						      \
+			continue;					      \
+		default:						      \
+			if (isgraph(c)) {				      \
+				*dst++ = '\\'; *dst++ = c;		      \
+				continue;				      \
+			}						      \
+		}							      \
+	}								      \
+	if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) {	      \
+		*dst++ = '\\';						      \
+		*dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0';    \
+		*dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0';    \
+		*dst++ =			     (c	      & 07) + '0';    \
+	} else {							      \
+		if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\';		      \
+		if (c & 0200) {						      \
+			c &= 0177; *dst++ = 'M';			      \
+		}							      \
+		if (iscntrl(c)) {					      \
+			*dst++ = '^';					      \
+			if (c == 0177)					      \
+				*dst++ = '?';				      \
+			else						      \
+				*dst++ = c + '@';			      \
+		} else {						      \
+			*dst++ = '-'; *dst++ = c;			      \
+		}							      \
+	}								      \
+} while (/*CONSTCOND*/0)
+
+
+/*
+ * svis - visually encode characters, also encoding the characters
+ * 	  pointed to by `extra'
+ */
+char *
+svis(dst, c, flag, nextc, extra)
+	char *dst;
+	int c, flag, nextc;
+	const char *extra;
+{
+	char *nextra;
+	_DIAGASSERT(dst != NULL);
+	_DIAGASSERT(extra != NULL);
+	MAKEEXTRALIST(flag, nextra, extra);
+	if (flag & VIS_HTTPSTYLE)
+		HVIS(dst, c, flag, nextc, nextra);
+	else
+		SVIS(dst, c, flag, nextc, nextra);
+	*dst = '\0';
+	return(dst);
+}
+
+
+/*
+ * strsvis, strsvisx - visually encode characters from src into dst
+ *
+ *	Extra is a pointer to a \0-terminated list of characters to
+ *	be encoded, too. These functions are useful e. g. to
+ *	encode strings in such a way so that they are not interpreted
+ *	by a shell.
+ *
+ *	Dst must be 4 times the size of src to account for possible
+ *	expansion.  The length of dst, not including the trailing NULL,
+ *	is returned.
+ *
+ *	Strsvisx encodes exactly len bytes from src into dst.
+ *	This is useful for encoding a block of data.
+ */
+int
+strsvis(dst, csrc, flag, extra)
+	char *dst;
+	const char *csrc;
+	int flag;
+	const char *extra;
+{
+	int c;
+	char *start;
+	char *nextra;
+	const unsigned char *src = (const unsigned char *)csrc;
+
+	_DIAGASSERT(dst != NULL);
+	_DIAGASSERT(src != NULL);
+	_DIAGASSERT(extra != NULL);
+	MAKEEXTRALIST(flag, nextra, extra);
+	if (flag & VIS_HTTPSTYLE) {
+		for (start = dst; (c = *src++) != '\0'; /* empty */)
+			HVIS(dst, c, flag, *src, nextra);
+	} else {
+		for (start = dst; (c = *src++) != '\0'; /* empty */)
+			SVIS(dst, c, flag, *src, nextra);
+	}
+	*dst = '\0';
+	return (dst - start);
+}
+
+
+int
+strsvisx(dst, csrc, len, flag, extra)
+	char *dst;
+	const char *csrc;
+	size_t len;
+	int flag;
+	const char *extra;
+{
+	int c;
+	char *start;
+	char *nextra;
+	const unsigned char *src = (const unsigned char *)csrc;
+
+	_DIAGASSERT(dst != NULL);
+	_DIAGASSERT(src != NULL);
+	_DIAGASSERT(extra != NULL);
+	MAKEEXTRALIST(flag, nextra, extra);
+
+	if (flag & VIS_HTTPSTYLE) {
+		for (start = dst; len > 0; len--) {
+			c = *src++;
+			HVIS(dst, c, flag, len ? *src : '\0', nextra);
+		}
+	} else {
+		for (start = dst; len > 0; len--) {
+			c = *src++;
+			SVIS(dst, c, flag, len ? *src : '\0', nextra);
+		}
+	}
+	*dst = '\0';
+	return (dst - start);
+}
+#endif
+
+#if !HAVE_VIS
+/*
+ * vis - visually encode characters
+ */
+char *
+vis(dst, c, flag, nextc)
+	char *dst;
+	int c, flag, nextc;
+
+{
+	char *extra;
+
+	_DIAGASSERT(dst != NULL);
+
+	MAKEEXTRALIST(flag, extra, "");
+	if (flag & VIS_HTTPSTYLE)
+		HVIS(dst, c, flag, nextc, extra);
+	else
+		SVIS(dst, c, flag, nextc, extra);
+	*dst = '\0';
+	return (dst);
+}
+
+
+/*
+ * strvis, strvisx - visually encode characters from src into dst
+ *
+ *	Dst must be 4 times the size of src to account for possible
+ *	expansion.  The length of dst, not including the trailing NULL,
+ *	is returned.
+ *
+ *	Strvisx encodes exactly len bytes from src into dst.
+ *	This is useful for encoding a block of data.
+ */
+int
+strvis(dst, src, flag)
+	char *dst;
+	const char *src;
+	int flag;
+{
+	char *extra;
+
+	MAKEEXTRALIST(flag, extra, "");
+	return (strsvis(dst, src, flag, extra));
+}
+
+
+int
+strvisx(dst, src, len, flag)
+	char *dst;
+	const char *src;
+	size_t len;
+	int flag;
+{
+	char *extra;
+
+	MAKEEXTRALIST(flag, extra, "");
+	return (strsvisx(dst, src, len, flag, extra));
+}
+#endif
diff --git a/cmd-line-utils/libedit/vis.h b/cmd-line-utils/libedit/vis.h
new file mode 100644
index 0000000000000000000000000000000000000000..44f6fc7d785b63ef733fec501f13167acf610aff
--- /dev/null
+++ b/cmd-line-utils/libedit/vis.h
@@ -0,0 +1,92 @@
+/*	$NetBSD: vis.h,v 1.15 2005/02/03 04:39:32 perry Exp $	*/
+
+/*-
+ * Copyright (c) 1990, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * 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. 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.
+ *
+ *	@(#)vis.h	8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _VIS_H_
+#define	_VIS_H_
+
+#include <config.h>
+
+/*
+ * to select alternate encoding format
+ */
+#define	VIS_OCTAL	0x01	/* use octal \ddd format */
+#define	VIS_CSTYLE	0x02	/* use \[nrft0..] where appropiate */
+
+/*
+ * to alter set of characters encoded (default is to encode all
+ * non-graphic except space, tab, and newline).
+ */
+#define	VIS_SP		0x04	/* also encode space */
+#define	VIS_TAB		0x08	/* also encode tab */
+#define	VIS_NL		0x10	/* also encode newline */
+#define	VIS_WHITE	(VIS_SP | VIS_TAB | VIS_NL)
+#define	VIS_SAFE	0x20	/* only encode "unsafe" characters */
+
+/*
+ * other
+ */
+#define	VIS_NOSLASH	0x40	/* inhibit printing '\' */
+#define	VIS_HTTPSTYLE	0x80	/* http-style escape % HEX HEX */
+
+/*
+ * unvis return codes
+ */
+#define	UNVIS_VALID	 1	/* character valid */
+#define	UNVIS_VALIDPUSH	 2	/* character valid, push back passed char */
+#define	UNVIS_NOCHAR	 3	/* valid sequence, no character produced */
+#define	UNVIS_SYNBAD	-1	/* unrecognized escape sequence */
+#define	UNVIS_ERROR	-2	/* decoder in unknown state (unrecoverable) */
+
+/*
+ * unvis flags
+ */
+#define	UNVIS_END	1	/* no more characters */
+
+__BEGIN_DECLS
+char	*vis(char *, int, int, int);
+char	*svis(char *, int, int, int, const char *);
+int	strvis(char *, const char *, int);
+int	strsvis(char *, const char *, int, const char *);
+int	strvisx(char *, const char *, size_t, int);
+int	strsvisx(char *, const char *, size_t, int, const char *);
+int	strunvis(char *, const char *);
+int	strunvisx(char *, const char *, int);
+#ifdef __LIBC12_SOURCE__
+int	unvis(char *, int, int *, int);
+int	__unvis13(char *, int, int *, int);
+#else
+int	unvis(char *, int, int *, int);
+#endif
+__END_DECLS
+
+#endif /* !_VIS_H_ */
diff --git a/configure.in b/configure.in
index 5b1ceaabdbb1b8e41df21b795f033a9852f739c6..41f92788d7ec7d033ebb372f6b3e417c80fefea0 100644
--- a/configure.in
+++ b/configure.in
@@ -117,7 +117,6 @@ AC_SUBST(SAVE_LDFLAGS)
 AC_SUBST(SAVE_CXXLDFLAGS)
 AC_SUBST(CXXLDFLAGS)
 
-
 #AC_ARG_PROGRAM			# Automaticly invoked by AM_INIT_AUTOMAKE
 
 AM_SANITY_CHECK
@@ -337,7 +336,7 @@ AC_SUBST(LD)
 AC_SUBST(INSTALL_SCRIPT)
 
 export CC CXX CFLAGS LD LDFLAGS AR
-
+echo "GXX: $GXX"
 if test "$GXX" = "yes"
 then
   # mysqld requires -fno-implicit-templates.
@@ -345,36 +344,16 @@ then
   # mysqld doesn't use run-time-type-checking, so we disable it.
   CXXFLAGS="$CXXFLAGS -fno-implicit-templates -fno-exceptions -fno-rtti"
 
-  # If you are using 'gcc' 3.0 (not g++) to compile C++ programs on Linux,
-  # we will gets some problems when linking static programs.
-  # The following code is used to fix this problem.
-
+  #CXX_VERNO=`echo $CXX_VERSION | sed -e 's/[[^0-9. ]]//g; s/^ *//g; s/ .*//g'`
+  echo "CXX: $CXX"
   if echo $CXX | grep gcc > /dev/null 2>&1
   then
-    GCC_VERSION=`gcc -v 2>&1 | grep version | sed -e 's/[[^0-9. ]]//g; s/^ *//g; s/ .*//g'`
-    case $SYSTEM_TYPE in
-      *freebsd*)
-        # The libsupc++ library on freebsd with gcc 3.4.2 is dependent on 
-        # libstdc++, disable it  since other solution works fine
-        GCC_VERSION="NOSUPCPP_$GCC_VERSION"
-      ;;
-      *) 
-      ;;
-    esac
-    echo "Using gcc version '$GCC_VERSION'"
-    case "$GCC_VERSION" in
-      3.4.*|3.5.*)
-        # Statically link the language support function's found in libsupc++.a
-        LIBS="$LIBS -lsupc++"
-	echo "Using -libsupc++ for static linking with gcc"
-      ;;
-      *)
-        # Using -lsupc++ doesn't work in gcc 3.3 on SuSE 9.2
-        # (causes link failures when linking things staticly)
-        CXXFLAGS="$CXXFLAGS -DUSE_MYSYS_NEW -DDEFINE_CXA_PURE_VIRTUAL"
-	echo "Using MYSYS_NEW for static linking with gcc"
-      ;;
-    esac
+    echo "Setting CXXFLAGS"
+    # If you are using 'gcc' 3.0 (not g++) to compile C++ programs on Linux,
+    # we will gets some problems when linking static programs.
+    # The following code is used to fix this problem.
+    CXXFLAGS="$CXXFLAGS -DUSE_MYSYS_NEW -DDEFINE_CXA_PURE_VIRTUAL"
+    echo "Using MYSYS_NEW for static linking with gcc"
   fi
 fi
 
@@ -2408,17 +2387,24 @@ then
     compile_readline=yes
     AC_DEFINE_UNQUOTED(USE_NEW_READLINE_INTERFACE, 1)
 else
+    # Use system readline library
     AC_LANG_SAVE
     AC_LANG_CPLUSPLUS
     MYSQL_CHECK_LIBEDIT_INTERFACE
     MYSQL_CHECK_NEW_RL_INTERFACE
     MYSQL_CHECK_READLINE_DECLARES_HIST_ENTRY
     AC_LANG_RESTORE
-    if [test "$mysql_cv_new_rl_interface" = "yes"] || [test "$mysql_cv_libedit_interface" = "no"]
+    if [test "$mysql_cv_new_rl_interface" = "yes"]
     then
+        # Use the new readline interface
         readline_link="-lreadline"
-    else
+    elif [test "$mysql_cv_libedit_interface" = "yes"]; then
+        # Use libedit
         readline_link="-ledit"
+    else
+       AC_MSG_ERROR([Could not find system readline or libedit libraries
+          Use --with-readline or --with-libedit to use the bundled
+          versions of libedit or readline])
     fi
 fi
 fi
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 670a4ccf63e537dbe8d761ba9484a4f472aef429..47a38d1a64214d573a6126a79cca1b448f601be6 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -604,19 +604,19 @@ extern int my_rw_trywrlock(my_rw_lock_t *);
 #define pthread_attr_setstacksize(A,B) pthread_dummy(0)
 #endif
 
-/* Define mutex types */
+/* Define mutex types, see my_thr_init.c */
 #define MY_MUTEX_INIT_SLOW   NULL
-#define MY_MUTEX_INIT_FAST   NULL
-#define MY_MUTEX_INIT_ERRCHK NULL
 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
 extern pthread_mutexattr_t my_fast_mutexattr;
-#undef  MY_MUTEX_INIT_FAST
 #define MY_MUTEX_INIT_FAST &my_fast_mutexattr
+#else
+#define MY_MUTEX_INIT_FAST   NULL
 #endif
 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
-extern pthread_mutexattr_t my_errchk_mutexattr;
-#undef MY_INIT_MUTEX_ERRCHK
-#define MY_INIT_MUTEX_ERRCHK &my_errchk_mutexattr
+extern pthread_mutexattr_t my_errorcheck_mutexattr;
+#define MY_MUTEX_INIT_ERRCHK &my_errorcheck_mutexattr
+#else
+#define MY_MUTEX_INIT_ERRCHK   NULL
 #endif
 
 extern my_bool my_thread_global_init(void);
diff --git a/include/my_sys.h b/include/my_sys.h
index f63743a4c6cf93f34ba453136309bf82d2f95108..e2f9444c52a72da8a1f584deb8d80ac7e91b2f6a 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -638,6 +638,7 @@ extern uint dirname_part(my_string to,const char *name);
 extern uint dirname_length(const char *name);
 #define base_name(A) (A+dirname_length(A))
 extern int test_if_hard_path(const char *dir_name);
+extern my_bool has_path(const char *name);
 extern char *convert_dirname(char *to, const char *from, const char *from_end);
 extern void to_unix_path(my_string name);
 extern my_string fn_ext(const char *name);
diff --git a/myisam/myisampack.c b/myisam/myisampack.c
index 352c7954d72bceb50b8cb777688bef29a4104372..74bb541b220407b83b287a3fa71b7d2022528730 100644
--- a/myisam/myisampack.c
+++ b/myisam/myisampack.c
@@ -31,6 +31,7 @@
 #define __GNU_LIBRARY__			/* Skip warnings in getopt.h */
 #endif
 #include <my_getopt.h>
+#include <assert.h>
 
 #if INT_MAX > 32767
 #define BITS_SAVED 32
@@ -1996,7 +1997,9 @@ static void write_bits (register ulong value, register uint bits)
   {
     reg3 uint byte_buff;
     bits= (uint) -file_buffer.bits;
-    byte_buff=file_buffer.current_byte | (uint) (value >> bits);
+    DBUG_ASSERT(bits <= 8 * sizeof(value));
+    byte_buff= (file_buffer.current_byte |
+               ((bits != 8 * sizeof(value)) ? (uint) (value >> bits) : 0));
 #if BITS_SAVED == 32
     *file_buffer.pos++= (byte) (byte_buff >> 24) ;
     *file_buffer.pos++= (byte) (byte_buff >> 16) ;
@@ -2004,7 +2007,9 @@ static void write_bits (register ulong value, register uint bits)
     *file_buffer.pos++= (byte) (byte_buff >> 8) ;
     *file_buffer.pos++= (byte) byte_buff;
 
-    value&=(1 << bits)-1;
+    DBUG_ASSERT(bits <= 8 * sizeof(ulong));
+    if (bits != 8 * sizeof(value))
+      value&= (((ulong) 1) << bits) - 1;
 #if BITS_SAVED == 16
     if (bits >= sizeof(uint))
     {
diff --git a/myisammrg/myrg_open.c b/myisammrg/myrg_open.c
index a59ccb7d966119139bb977bd5f4945f6383660a5..0dc2f4f9768b98fbc17b949269af937d2db2d251 100644
--- a/myisammrg/myrg_open.c
+++ b/myisammrg/myrg_open.c
@@ -80,7 +80,7 @@ MYRG_INFO *myrg_open(const char *name, int mode, int handle_locking)
       continue;		/* Skip comments */
     }
 
-    if (!test_if_hard_path(buff))
+    if (!has_path(buff))
     {
       VOID(strmake(name_buff+dir_length,buff,
                    sizeof(name_buff)-1-dir_length));
diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result
index ce5917db4bc1e75bd4e6ea2f0a61be4008b42daf..793e50cf653c5149f3fd6cf41602665b23ba8e1d 100644
--- a/mysql-test/r/archive.result
+++ b/mysql-test/r/archive.result
@@ -184,6 +184,22 @@ fld1	fld3
 250503	heaving
 250504	population
 250505	bomb
+create table t3 engine=archive select * from t2;
+select * from t3 where fld3='bonfire';
+auto	fld1	companynr	fld3	fld4	fld5	fld6
+1191	068504	00	bonfire	corresponds	positively	
+select count(*) from t3;
+count(*)
+1199
+rename table t3 to t4;
+Warnings:
+Error	7	Error on rename of './test/t3.ARN' to './test/t4.ARN' (Errcode: 2)
+select * from t4 where fld3='bonfire';
+auto	fld1	companynr	fld3	fld4	fld5	fld6
+1191	068504	00	bonfire	corresponds	positively	
+select count(*) from t4;
+count(*)
+1199
 INSERT INTO t2 VALUES (1,000001,00,'Omaha','teethe','neat','');
 INSERT INTO t2 VALUES (2,011401,37,'breaking','dreaded','Steinberg','W');
 INSERT INTO t2 VALUES (3,011402,37,'Romans','scholastics','jarring','');
@@ -5020,4 +5036,4 @@ auto	fld1	companynr	fld3	fld4	fld5	fld6
 3	011402	37	Romans	scholastics	jarring	
 4	011403	37	intercepted	audiology	tinily	
 INSERT DELAYED INTO t2 VALUES (4,011403,37,'intercepted','audiology','tinily','');
-drop table t1, t2;
+drop table t1, t2, t4;
diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result
index 3a28cccfac5cde52161d7feebe71ffd843a3f705..005f41f70631e49b208ae50cd4258dbe25e43dcc 100644
--- a/mysql-test/r/func_math.result
+++ b/mysql-test/r/func_math.result
@@ -1,3 +1,4 @@
+drop table if exists t1;
 select floor(5.5),floor(-5.5);
 floor(5.5)	floor(-5.5)
 5	-6
diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result
index 0e558e475944e8d62a63bd24b7a88315d4e5f935..73cde35993ea5f77ef63e4d4fbdcbfce33e88ab4 100644
--- a/mysql-test/r/gis-rtree.result
+++ b/mysql-test/r/gis-rtree.result
@@ -801,5 +801,5 @@ CREATE TABLE t1 (st varchar(100));
 INSERT INTO t1 VALUES ("Fake string");
 CREATE TABLE t2 (geom GEOMETRY NOT NULL, SPATIAL KEY gk(geom));
 INSERT INTO t2 SELECT GeomFromText(st) FROM t1;
-ERROR HY000: Unknown error
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
 drop table t1, t2;
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index 3b196a60d688919f56c66e35fb6d1413d98fb5fa..93216fe2003f40f413e7ed52bb71b892aa44f80f 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -461,9 +461,9 @@ Note	1003	select issimple(multipoint(point(3,6),point(4,10))) AS `issimple(Multi
 create table t1 (a geometry not null);
 insert into t1 values (GeomFromText('Point(1 2)'));
 insert into t1 values ('Garbage');
-ERROR HY000: Unknown error
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
 insert IGNORE into t1 values ('Garbage');
-ERROR HY000: Unknown error
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
 alter table t1 add spatial index(a);
 drop table t1;
 create table t1(a geometry not null, spatial index(a));
@@ -655,3 +655,13 @@ t1 where object_id=85984;
 object_id	geometrytype(geo)	ISSIMPLE(GEO)	ASTEXT(centroid(geo))
 85984	MULTIPOLYGON	0	POINT(-114.87787186923 36.33101763469)
 drop table t1;
+create table t1 (fl geometry);
+insert into t1 values (1);
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+insert into t1 values (1.11);
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+insert into t1 values ("qwerty");
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+insert into t1 values (pointfromtext('point(1,1)'));
+ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field
+drop table t1;
diff --git a/mysql-test/r/group_by.result b/mysql-test/r/group_by.result
index af69cc83e83804cc99ca5ffb4af3938b5361ff3f..5cee9b15dcd37942d188da8a2df992d202f89516 100644
--- a/mysql-test/r/group_by.result
+++ b/mysql-test/r/group_by.result
@@ -702,3 +702,12 @@ c
 val-74
 val-98
 drop table t1,t2;
+create table t1 (b int4 unsigned not null);
+insert into t1 values(3000000000);
+select * from t1;
+b
+3000000000
+select min(b) from t1;
+min(b)
+3000000000
+drop table t1;
diff --git a/mysql-test/r/ndb_multi.result b/mysql-test/r/ndb_multi.result
index 5696fda1c077826c280e2b70fea3ca31d92ed223..2080be241e8a3052af96f748c8af2aef1a84c284 100644
--- a/mysql-test/r/ndb_multi.result
+++ b/mysql-test/r/ndb_multi.result
@@ -13,6 +13,26 @@ a
 show status like 'handler_discover%';
 Variable_name	Value
 Handler_discover	0
+select * from t1;
+a
+2
+drop table t1;
+create table t1 (a int) engine=ndbcluster;
+insert into t1 value (2);
+select * from t1;
+a
+2
+show status like 'handler_discover%';
+Variable_name	Value
+Handler_discover	0
+drop table t1;
+create table t1 (a int) engine=ndbcluster;
+insert into t1 value (2);
+select * from t1;
+ERROR HY000: Got error 241 'Invalid schema object version' from ndbcluster
+select * from t1;
+a
+2
 flush status;
 select * from t1;
 a
@@ -20,7 +40,7 @@ a
 update t1 set a=3 where a=2;
 show status like 'handler_discover%';
 Variable_name	Value
-Handler_discover	1
+Handler_discover	0
 create table t3 (a int not null primary key, b varchar(22),
 c int, last_col text) engine=ndb;
 insert into t3 values(1, 'Hi!', 89, 'Longtext column');
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index 5ee1d46f3c97da6b8df17d1722cd48eb4c6c2a4d..683f3e12091b607e586e9b38a355b98108fbfc94 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -594,4 +594,52 @@ alter function bug7047;
 return 0;
 end|
 ERROR HY000: Can't drop or alter a FUNCTION from within another stored routine
+create function bug8408() returns int
+begin
+select * from t1;
+return 0;
+end|
+ERROR 0A000: Not allowed to return a result set from a function
+create function bug8408() returns int
+begin
+show warnings;
+return 0;
+end|
+ERROR 0A000: Not allowed to return a result set from a function
+create function bug8408(a int) returns int
+begin
+declare b int;
+select b;
+return b;
+end|
+ERROR 0A000: Not allowed to return a result set from a function
+drop function if exists bug8408_f|
+drop procedure if exists bug8408_p|
+create function bug8408_f() returns int
+begin
+call bug8408_p();
+return 0;
+end|
+create procedure bug8408_p()
+select * from t1|
+call bug8408_p()|
+val	x
+select bug8408_f()|
+ERROR 0A000: PROCEDURE test.bug8408_p can't return a result set in the given context
+drop procedure bug8408_p|
+drop function bug8408_f|
+create function bug8408() returns int
+begin
+declare n int default 0;
+select count(*) into n from t1;
+return n;
+end|
+insert into t1 value (2, 2.7), (3, 3.14), (7, 7.0)|
+select *,bug8408() from t1|
+val	x	bug8408()
+2	2.7	3
+3	3.14	3
+7	7	3
+drop function bug8408|
+delete from t1|
 drop table t1|
diff --git a/mysql-test/r/temp_table.result b/mysql-test/r/temp_table.result
index 2dd58f543271cc1f576259dde2d750c9f2df6b46..f43fd09982ad28f66808f0dd482892885d2954e8 100644
--- a/mysql-test/r/temp_table.result
+++ b/mysql-test/r/temp_table.result
@@ -97,3 +97,29 @@ Variable_name	Value
 Created_tmp_disk_tables	0
 Created_tmp_tables	2
 drop table t1;
+create temporary table t1 as select 'This is temp. table' A;
+create view t1 as select 'This is view' A;
+select * from t1;
+A
+This is temp. table
+show create table t1;
+Table	Create Table
+t1	CREATE TEMPORARY TABLE `t1` (
+  `A` varchar(19) NOT NULL default ''
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+show create view t1;
+View	Create View
+t1	CREATE ALGORITHM=UNDEFINED VIEW `test`.`t1` AS select _latin1'This is view' AS `A`
+drop view t1;
+select * from t1;
+A
+This is temp. table
+create view t1 as select 'This is view again' A;
+select * from t1;
+A
+This is temp. table
+drop table t1;
+select * from t1;
+A
+This is view again
+drop view t1;
diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
index a01f8ee08a182389ab6af87cf26571c870aad1f8..a7b6fa1b376d11d852b57a96f3aee71de10c27a4 100644
--- a/mysql-test/r/type_decimal.result
+++ b/mysql-test/r/type_decimal.result
@@ -764,3 +764,23 @@ non PS, 1.0 in parameter	1.0
 PS, 1.0 in parameter    	1.0
 deallocate prepare stmt;
 drop table t1;
+create table t1 (
+strippedproductid char(15) not null default '',
+zlevelprice decimal(10,2) default null,
+primary key (strippedproductid)
+);
+create table t2 (
+productid char(15) not null default '',
+zlevelprice char(21) default null,
+primary key (productid)
+);
+insert into t1 values ('002trans','49.99');
+insert into t1 values ('003trans','39.98');
+insert into t1 values ('004trans','31.18');
+insert INTO t2 SELECT * FROM t1;
+select * from t2;
+productid	zlevelprice
+002trans	49.99
+003trans	39.98
+004trans	31.18
+drop table t1, t2;
diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test
index f7ec603ca79d2f55e52ceee851e1067eb0267876..9d25524da5f36106a812683c286b68b983c75b82 100644
--- a/mysql-test/t/archive.test
+++ b/mysql-test/t/archive.test
@@ -1289,6 +1289,18 @@ select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly");
 select fld1,fld3 from t2 where fld1 like "25050%";
 select fld1,fld3 from t2 where fld1 like "25050_";
 
+
+#
+# Test rename of table
+#
+create table t3 engine=archive select * from t2;
+select * from t3 where fld3='bonfire';
+select count(*) from t3;
+rename table t3 to t4;
+select * from t4 where fld3='bonfire';
+select count(*) from t4;
+
+
 #
 # Test for insert after select
 #
@@ -1308,8 +1320,9 @@ INSERT INTO t2 VALUES (1,000001,00,'Omaha','teethe','neat','') , (2,011401,37,'b
 SELECT * FROM t2;
 
 # Just test syntax, we will never know if the out put is right or wrong
+# Must be the last test
 INSERT DELAYED INTO t2 VALUES (4,011403,37,'intercepted','audiology','tinily','');
 # 
 # Cleanup, test is over
 #
-drop table t1, t2;
+drop table t1, t2, t4;
diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test
index 668aefc2d8d58f0eda398dbdc9b843c9d160fe56..33b672e42b5f3f1e4145ad854ca1255f44a81804 100644
--- a/mysql-test/t/func_math.test
+++ b/mysql-test/t/func_math.test
@@ -2,6 +2,10 @@
 # Test of math functions
 #
 
+--disable_warnings                                                              
+drop table if exists t1;                                                        
+--enable_warnings                                                               
+
 select floor(5.5),floor(-5.5);
 explain extended select floor(5.5),floor(-5.5);
 select ceiling(5.5),ceiling(-5.5);
diff --git a/mysql-test/t/gis-rtree.test b/mysql-test/t/gis-rtree.test
index da59c6ae5e4d8b7c4c7ab2f1d84f9349120899bc..522f7a6f63717770531bdd6b0e5508c606de88d7 100644
--- a/mysql-test/t/gis-rtree.test
+++ b/mysql-test/t/gis-rtree.test
@@ -168,6 +168,6 @@ drop table t1;
 CREATE TABLE t1 (st varchar(100));
 INSERT INTO t1 VALUES ("Fake string");
 CREATE TABLE t2 (geom GEOMETRY NOT NULL, SPATIAL KEY gk(geom));
---error 1105
+--error 1416
 INSERT INTO t2 SELECT GeomFromText(st) FROM t1;
 drop table t1, t2;
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index 86c34eacbc53b177a9c3d2841598b212e6a1419c..b7071019e9dbba60a0fe0e83b8b200a14eb6f0c8 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -165,9 +165,9 @@ explain extended select issimple(MultiPoint(Point(3, 6), Point(4, 10))), issimpl
 
 create table t1 (a geometry not null);
 insert into t1 values (GeomFromText('Point(1 2)'));
--- error 1105
+-- error 1416
 insert into t1 values ('Garbage');
--- error 1105
+-- error 1416
 insert IGNORE into t1 values ('Garbage');
 alter table t1 add spatial index(a);
 
@@ -359,3 +359,15 @@ select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from
 t1 where object_id=85984;
 
 drop table t1;
+
+create table t1 (fl geometry);
+--error 1416
+insert into t1 values (1);
+--error 1416
+insert into t1 values (1.11);
+--error 1416
+insert into t1 values ("qwerty");
+--error 1416
+insert into t1 values (pointfromtext('point(1,1)'));
+
+drop table t1;
diff --git a/mysql-test/t/group_by.test b/mysql-test/t/group_by.test
index 46e58cd00fd40ec1379a6d998b0e5aef404dcc63..fbd39019e6d0e4980fd70ebf811350fa5dc42dac 100644
--- a/mysql-test/t/group_by.test
+++ b/mysql-test/t/group_by.test
@@ -515,3 +515,10 @@ explain select c from t2 where a = 2 and b = 'val-2' group by c;
 select c from t2 where a = 2 and b = 'val-2' group by c;
 drop table t1,t2;
 
+# Test for BUG#9298 "Wrong handling of int4 unsigned columns in GROUP functions"
+# (the actual problem was with protocol code, not GROUP BY)
+create table t1 (b int4 unsigned not null);
+insert into t1 values(3000000000);
+select * from t1;
+select min(b) from t1;
+drop table t1;
diff --git a/mysql-test/t/ndb_multi.test b/mysql-test/t/ndb_multi.test
index 24651913a79be643dd53e7963a174ae3fea4c94c..85950c72cf97f5d682fe6bd5da992f274788e2a5 100644
--- a/mysql-test/t/ndb_multi.test
+++ b/mysql-test/t/ndb_multi.test
@@ -18,6 +18,30 @@ select * from t1;
 select * from t2;
 show status like 'handler_discover%';
 
+# Check dropping and recreating table on same server
+connect (con1,localhost,,,test);
+connect (con2,localhost,,,test);
+connection con1;
+select * from t1;
+connection con2;
+drop table t1;
+create table t1 (a int) engine=ndbcluster;
+insert into t1 value (2);
+connection con1;
+select * from t1;
+
+# Check dropping and recreating table on different server
+connection server2;
+show status like 'handler_discover%';
+drop table t1;
+create table t1 (a int) engine=ndbcluster;
+insert into t1 value (2);
+connection server1;
+# Currently a retry is required remotely
+--error 1296
+select * from t1;
+select * from t1;
+
 # Connect to server2 and use the tables from there
 connection server2;
 flush status;
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index cb4ebf080f4cf1d0ec61ac7c0b5c7bc467e808ac..ff317b4ac282620ef1271d5ec52ba6982daf7718 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -831,6 +831,68 @@ begin
 end|
 
 
+#
+# BUG#8408: Stored procedure crash if function contains SHOW
+# BUG#9058: Stored Procedures: Crash if function included SELECT
+#
+
+# Some things are caught when parsing
+--error ER_SP_NO_RETSET_IN_FUNC
+create function bug8408() returns int
+begin
+  select * from t1;
+  return 0;
+end|
+--error ER_SP_NO_RETSET_IN_FUNC
+create function bug8408() returns int
+begin
+  show warnings;
+  return 0;
+end|
+--error ER_SP_NO_RETSET_IN_FUNC
+create function bug8408(a int) returns int
+begin
+  declare b int;
+  select b;
+  return b;
+end|
+
+--disable_warnings
+drop function if exists bug8408_f|
+drop procedure if exists bug8408_p|
+--enable_warnings
+
+# Some things must be caught at invokation time
+create function bug8408_f() returns int
+begin
+  call bug8408_p();
+  return 0;
+end|
+create procedure bug8408_p()
+  select * from t1|
+
+call bug8408_p()|
+--error ER_SP_BADSELECT
+select bug8408_f()|
+
+drop procedure bug8408_p|
+drop function bug8408_f|
+
+# But this is ok
+create function bug8408() returns int
+begin
+  declare n int default 0;
+  select count(*) into n from t1;
+  return n;
+end|
+
+insert into t1 value (2, 2.7), (3, 3.14), (7, 7.0)|
+select *,bug8408() from t1|
+
+drop function bug8408|
+delete from t1|
+
+
 #
 # BUG#NNNN: New bug synopsis
 #
diff --git a/mysql-test/t/temp_table.test b/mysql-test/t/temp_table.test
index 74276c7668c2be4c6f78c96458c84ca3e95525c3..eeb33515570643b171e5b8eaec52eddc152dbb59 100644
--- a/mysql-test/t/temp_table.test
+++ b/mysql-test/t/temp_table.test
@@ -89,3 +89,18 @@ flush status;
 select * from t1 group by d;
 show status like "created_tmp%tables";
 drop table t1;
+
+# Fix for BUG#8921: Check that temporary table is ingored by view commands.
+create temporary table t1 as select 'This is temp. table' A;
+create view t1 as select 'This is view' A;
+select * from t1;
+show create table t1;
+show create view t1;
+drop view t1;
+select * from t1;
+create view t1 as select 'This is view again' A;
+select * from t1;
+drop table t1;
+select * from t1;
+drop view t1;
+
diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test
index 107f4a06ec5abd5be84d86569944374886ed73e9..f86113ac66b24b3543f6f517eda699693d77e8df 100644
--- a/mysql-test/t/type_decimal.test
+++ b/mysql-test/t/type_decimal.test
@@ -343,3 +343,31 @@ execute stmt using @a;
 select * from t1;
 deallocate prepare stmt;
 drop table t1;
+
+#
+# A test case for Bug#5673 "Rounding problem in 4.0.21 inserting decimal
+# value into a char field": this is a regression bug in 4.0 tree caused by
+# a fix for some other decimal conversion issue. The patch never was
+# approved to get into 4.0 (maybe because it was considered too intrusive)
+#
+
+create table t1 (
+  strippedproductid char(15) not null default '',
+  zlevelprice decimal(10,2) default null,
+  primary key (strippedproductid)
+);
+
+create table t2 (
+  productid char(15) not null default '',
+  zlevelprice char(21) default null,
+  primary key (productid)
+);
+
+insert into t1 values ('002trans','49.99');
+insert into t1 values ('003trans','39.98');
+insert into t1 values ('004trans','31.18');
+
+insert INTO t2 SELECT * FROM t1;
+
+select * from t2; 
+drop table t1, t2;
diff --git a/mysys/my_getwd.c b/mysys/my_getwd.c
index d6f647254e801309eb21029b082be6f9556de77d..89f949eca277b66a513f77e3e16b7417c9aaa7c9 100644
--- a/mysys/my_getwd.c
+++ b/mysys/my_getwd.c
@@ -192,3 +192,25 @@ int test_if_hard_path(register const char *dir_name)
   return FALSE;
 #endif
 } /* test_if_hard_path */
+
+
+/*
+  Test if a name contains an (absolute or relative) path.
+
+  SYNOPSIS
+    has_path()
+    name                The name to test.
+
+  RETURN
+    TRUE        name contains a path.
+    FALSE       name does not contain a path.
+*/
+
+my_bool has_path(const char *name)
+{
+  return test(strchr(name, FN_LIBCHAR))
+#ifdef FN_DEVCHAR
+    || test(strchr(name, FN_DEVCHAR))
+#endif
+    ;
+}
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c
index 36b37f68b46f423dd5262438059ac12e583eac89..878e1f6bfc6c48956a01c70a7af358766365d72f 100644
--- a/mysys/my_thr_init.c
+++ b/mysys/my_thr_init.c
@@ -41,7 +41,7 @@ pthread_mutex_t LOCK_gethostbyname_r;
 pthread_mutexattr_t my_fast_mutexattr;
 #endif
 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
-pthread_mutexattr_t my_errchk_mutexattr;
+pthread_mutexattr_t my_errorcheck_mutexattr;
 #endif
 
 /*
@@ -62,19 +62,29 @@ my_bool my_thread_global_init(void)
     fprintf(stderr,"Can't initialize threads: error %d\n",errno);
     return 1;
   }
+
 #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
-  pthread_mutexattr_init(&my_fast_mutexattr);
   /*
-    Note that the following statement may give a compiler warning under
-    some configurations, but there isn't anything we can do about this as
-    this is a bug in the header files for the thread implementation
+    Set mutex type to "fast" a.k.a "adaptive"
+
+    The mutex kind determines what happens if a thread attempts to lock
+    a mutex it already owns with pthread_mutex_lock(3). If the mutex
+    is of the ``fast'' kind, pthread_mutex_lock(3) simply suspends
+    the calling thread forever. If the mutex is of the ``error checking''
+    kind, pthread_mutex_lock(3) returns immediately with the error
+    code EDEADLK.
   */
-  pthread_mutexattr_setkind_np(&my_fast_mutexattr,PTHREAD_MUTEX_ADAPTIVE_NP);
+  pthread_mutexattr_init(&my_fast_mutexattr);
+  pthread_mutexattr_settype(&my_fast_mutexattr,
+                            PTHREAD_MUTEX_ADAPTIVE_NP);
 #endif
 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
-  pthread_mutexattr_init(&my_errchk_mutexattr);
-  pthread_mutexattr_setkind_np(&my_errchk_mutexattr,
-			       PTHREAD_MUTEX_ERRORCHECK_NP);
+  /*
+    Set mutex type to "errorcheck" a.k.a "adaptive"
+  */
+  pthread_mutexattr_init(&my_errorcheck_mutexattr);
+  pthread_mutexattr_settype(&my_errorcheck_mutexattr,
+                            PTHREAD_MUTEX_ERRORCHECK);
 #endif
 
   pthread_mutex_init(&THR_LOCK_malloc,MY_MUTEX_INIT_FAST);
@@ -110,7 +120,7 @@ void my_thread_global_end(void)
   pthread_mutexattr_destroy(&my_fast_mutexattr);
 #endif
 #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP
-  pthread_mutexattr_destroy(&my_errchk_mutexattr);
+  pthread_mutexattr_destroy(&my_errorcheck_mutexattr);
 #endif
   pthread_mutex_destroy(&THR_LOCK_malloc);
   pthread_mutex_destroy(&THR_LOCK_open);
diff --git a/ndb/include/ndbapi/NdbDictionary.hpp b/ndb/include/ndbapi/NdbDictionary.hpp
index 7a945c1c22e4d2736b58c2e09cbef9e1a488af88..86130be4c4be97e37b90af9fb506f91bdff59787 100644
--- a/ndb/include/ndbapi/NdbDictionary.hpp
+++ b/ndb/include/ndbapi/NdbDictionary.hpp
@@ -76,8 +76,11 @@ public:
       Changed,                ///< The object has been modified in memory 
                               ///< and has to be commited in NDB Kernel for 
                               ///< changes to take effect
-      Retrieved               ///< The object exist and has been read 
+      Retrieved,              ///< The object exist and has been read 
                               ///< into main memory from NDB Kernel
+      Invalid                 ///< The object has been invalidated
+                              ///< and should not be used
+      
     };
 
     /**
diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index ff87a72f636a345760c7a0380b25c14943534292..96c8f6020e58c1e4973a2a161e0ca4cb6034a350 100644
--- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -1526,6 +1526,7 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl)
       // If in local cache it must be in global
       if (!cachedImpl)
 	abort();
+      cachedImpl->m_status = NdbDictionary::Object::Invalid;
       m_globalHash->drop(cachedImpl);
       m_globalHash->unlock();
     }
@@ -1830,8 +1831,8 @@ NdbDictionaryImpl::dropTable(const char * name)
 
     DBUG_PRINT("info",("INCOMPATIBLE_VERSION internal_name: %s", internalTableName));
     m_localHash.drop(internalTableName);
-    
     m_globalHash->lock();
+    tab->m_status = NdbDictionary::Object::Invalid;
     m_globalHash->drop(tab);
     m_globalHash->unlock();   
     DBUG_RETURN(dropTable(name));
@@ -1875,10 +1876,11 @@ NdbDictionaryImpl::dropTable(NdbTableImpl & impl)
   int ret = m_receiver.dropTable(impl);  
   if(ret == 0 || m_error.code == 709){
     const char * internalTableName = impl.m_internalName.c_str();
+
     
     m_localHash.drop(internalTableName);
-    
     m_globalHash->lock();
+    impl.m_status = NdbDictionary::Object::Invalid;
     m_globalHash->drop(&impl);
     m_globalHash->unlock();
 
@@ -1976,6 +1978,7 @@ NdbDictionaryImpl::invalidateObject(NdbTableImpl & impl)
 
   m_localHash.drop(internalTableName);  
   m_globalHash->lock();
+  impl.m_status = NdbDictionary::Object::Invalid;
   m_globalHash->drop(&impl);
   m_globalHash->unlock();
   return 0;
@@ -2242,8 +2245,8 @@ NdbDictionaryImpl::dropIndex(const char * indexName,
       m_ndb.internalizeTableName(indexName); // Index is also a table
     
     m_localHash.drop(internalIndexName);
-    
     m_globalHash->lock();
+    idx->m_table->m_status = NdbDictionary::Object::Invalid;
     m_globalHash->drop(idx->m_table);
     m_globalHash->unlock();   
     return dropIndex(indexName, tableName);
@@ -2277,8 +2280,8 @@ NdbDictionaryImpl::dropIndex(NdbIndexImpl & impl, const char * tableName)
     int ret = m_receiver.dropIndex(impl, *timpl);
     if(ret == 0){
       m_localHash.drop(internalIndexName);
-      
       m_globalHash->lock();
+      impl.m_table->m_status = NdbDictionary::Object::Invalid;
       m_globalHash->drop(impl.m_table);
       m_globalHash->unlock();
     }
diff --git a/sql/examples/ha_archive.cc b/sql/examples/ha_archive.cc
index a88bfc0391b5d8318ad01d6746b71cfa8f66e417..231031c983451b0c42cf908e034039be24824f96 100644
--- a/sql/examples/ha_archive.cc
+++ b/sql/examples/ha_archive.cc
@@ -431,11 +431,20 @@ int ha_archive::free_share(ARCHIVE_SHARE *share)
 }
 
 
-/* 
+/*
   We just implement one additional file extension.
 */
+static const char *ha_archive_exts[] = {
+  ARZ,
+  ARN,
+  ARM,
+  NullS
+};
+
 const char **ha_archive::bas_ext() const
-{ static const char *ext[]= { ARZ, ARN, ARM, NullS }; return ext; }
+{
+  return ha_archive_exts;
+}
 
 
 /* 
diff --git a/sql/examples/ha_example.cc b/sql/examples/ha_example.cc
index d043a66e71a43eb740bf65d7365c326028ea4bf7..562b51878bfa4a38330709e506cd29df8a4dd2a7 100644
--- a/sql/examples/ha_example.cc
+++ b/sql/examples/ha_example.cc
@@ -186,8 +186,14 @@ static int free_share(EXAMPLE_SHARE *share)
   exist for the storage engine. This is also used by the default rename_table and
   delete_table method in handler.cc.
 */
+static const char *ha_example_exts[] = {
+  NullS
+};
+
 const char **ha_example::bas_ext() const
-{ static const char *ext[]= { NullS }; return ext; }
+{
+  return ha_example_exts;
+}
 
 
 /*
diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc
index b515932d25f56428703f1674b7a36872cd20df35..9ac446587eccc4e43faa6f97e16eae013999ad42 100644
--- a/sql/examples/ha_tina.cc
+++ b/sql/examples/ha_tina.cc
@@ -384,8 +384,15 @@ int ha_tina::find_current_row(byte *buf)
   If frm_error() is called in table.cc this is called to find out what file
   extensions exist for this handler.
 */
+static const char *ha_tina_exts[] = {
+  ".CSV",
+  NullS
+};
+
 const char **ha_tina::bas_ext() const
-{ static const char *ext[]= { ".CSV", NullS }; return ext; }
+{
+  return ha_tina_exts;
+}
 
 
 /* 
diff --git a/sql/field.cc b/sql/field.cc
index 00f729d5b071316d129937dc1852030f9a1371b9..c59d9b63fca0287ef625e8f4256305b113214ecd 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -7267,12 +7267,38 @@ void Field_geom::sql_type(String &res) const
 }
 
 
+int Field_geom::store(double nr)
+{
+  my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
+             ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
+  return -1;
+}
+
+
+int Field_geom::store(longlong nr)
+{
+  my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
+             ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
+  return -1;
+}
+
+
+int Field_geom::store_decimal(const my_decimal *)
+{
+  my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
+             ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
+  return -1;
+}
+
+
 int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
 {
   if (!length)
     bzero(ptr, Field_blob::pack_length());
   else
   {
+    if (from == Geometry::bad_geometry_data.ptr())
+      goto err;
     // Check given WKB
     uint32 wkb_type;
     if (length < SRID_SIZE + WKB_HEADER_SIZE + SIZEOF_STORED_DOUBLE*2)
@@ -7280,7 +7306,7 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
     wkb_type= uint4korr(from + WKB_HEADER_SIZE);
     if (wkb_type < (uint32) Geometry::wkb_point ||
 	wkb_type > (uint32) Geometry::wkb_end)
-      return -1;
+      goto err;
     Field_blob::store_length(length);
     if (table->copy_blobs || length <= MAX_FIELD_WIDTH)
     {						// Must make a copy
@@ -7293,6 +7319,8 @@ int Field_geom::store(const char *from, uint length, CHARSET_INFO *cs)
 
 err:
   bzero(ptr, Field_blob::pack_length());  
+  my_message(ER_CANT_CREATE_GEOMETRY_OBJECT,
+             ER(ER_CANT_CREATE_GEOMETRY_OBJECT), MYF(0));
   return -1;
 }
 
diff --git a/sql/field.h b/sql/field.h
index 227878504426cfe6aea76d5744141e27403409fe..0f1cc0b95aadcd5b8861b7be91410e9a1e597096 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1189,9 +1189,9 @@ public:
   enum_field_types type() const { return FIELD_TYPE_GEOMETRY; }
   void sql_type(String &str) const;
   int  store(const char *to, uint length, CHARSET_INFO *charset);
-  int  store(double nr) { return 1; }
-  int  store(longlong nr) { return 1; }
-  int  store_decimal(const my_decimal *) { return 1; }
+  int  store(double nr);
+  int  store(longlong nr);
+  int  store_decimal(const my_decimal *);
   void get_key_image(char *buff,uint length,imagetype type);
 };
 #endif /*HAVE_SPATIAL*/
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 54d9865ddd5ec7246b74a96c364280d97c8ce9bf..04d81b2f95afb7555b26e741bf64494a6ee617a8 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -371,10 +371,15 @@ void berkeley_cleanup_log_files(void)
 /*****************************************************************************
 ** Berkeley DB tables
 *****************************************************************************/
+static const char *ha_berkeley_exts[] = {
+  ha_berkeley_ext,
+  NullS
+};
 
 const char **ha_berkeley::bas_ext() const
-{ static const char *ext[]= { ha_berkeley_ext, NullS }; return ext; }
-
+{
+  return ha_berkeley_exts;
+}
 
 ulong ha_berkeley::index_flags(uint idx, uint part, bool all_parts) const
 {
diff --git a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc
index e34d5d723a46003ac698a6ff985d96926a2fbd17..d9aedbe751d09e0b534c15a797d06edae42efaa8 100644
--- a/sql/ha_blackhole.cc
+++ b/sql/ha_blackhole.cc
@@ -25,10 +25,13 @@
 #include "ha_blackhole.h"
 
 
+static const char *ha_black_hole_exts[] = {
+  NullS
+};
+
 const char **ha_blackhole::bas_ext() const
-{ 
-  static const char *ext[]= { NullS }; 
-  return ext; 
+{
+  return ha_blackhole_exts;
 }
 
 int ha_blackhole::open(const char *name, int mode, uint test_if_locked)
diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc
index 33acc9cad0b97fe1a838824930b2c45a2f883963..0ac209d82e08258375e2516a276ca5cc9cd3421d 100644
--- a/sql/ha_federated.cc
+++ b/sql/ha_federated.cc
@@ -941,14 +941,13 @@ static int free_share(FEDERATED_SHARE *share)
   also used by the default rename_table and delete_table method
   in handler.cc.
 */
+static const char *ha_federated_exts[] = {
+  NullS
+};
 
 const char **ha_federated::bas_ext() const
 {
-  static const char *ext[]=
-  {
-    NullS
-  };
-  return ext;
+  return ha_federated_exts;
 }
 
 
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index 0d700f6c9a54714ebae94512f459fbf14bed1454..52ff776c5d64b26b084c7113a2fa37cb2cac60fd 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -26,9 +26,14 @@
 /*****************************************************************************
 ** HEAP tables
 *****************************************************************************/
+static const char *ha_heap_exts[] = {
+  NullS
+};
 
 const char **ha_heap::bas_ext() const
-{ static const char *ext[1]= { NullS }; return ext; }
+{
+  return ha_heap_exts;
+}
 
 /*
   Hash index statistics is updated (copied from HP_KEYDEF::hash_buckets to 
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index e68a85bdac97a60f560ca00373f928e5b23f6438..4217b694f06e74dda1ef0fdc95ad8b33685ccb30 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -1611,6 +1611,7 @@ innobase_report_binlog_offset_and_commit(
 	trx->mysql_log_file_name = log_file_name;
 	trx->mysql_log_offset = (ib_longlong)end_offset;
 
+#ifdef HAVE_REPLICATION
         if (thd->variables.sync_replication) {
                 /* Let us store the binlog file name and the position, so that
                 we know how long to wait for the binlog to the replicated to
@@ -1619,19 +1620,19 @@ innobase_report_binlog_offset_and_commit(
                 if (trx->repl_wait_binlog_name == NULL) {
 
                         trx->repl_wait_binlog_name =
-                                        (char*)mem_alloc(FN_REFLEN + 100);
+                                  (char*)mem_alloc_noninline(FN_REFLEN + 100);
                 }
 
-                ut_a(strlen(log_file_name) <= FN_REFLEN + 100);
+                ut_a(strlen(log_file_name) < FN_REFLEN + 100);
 
                 strcpy(trx->repl_wait_binlog_name, log_file_name);
 
                 trx->repl_wait_binlog_pos = (ib_longlong)end_offset;
         }
-
+#endif /* HAVE_REPLICATION */
 	trx->flush_log_later = TRUE;
 
-	innobase_commit(thd, trx_handle);
+	innobase_commit(thd, TRUE);
 
 	trx->flush_log_later = FALSE;
 
@@ -1681,10 +1682,7 @@ innobase_commit_complete(
                                 /* out: 0 */
         THD*    thd)            /* in: user thread */
 {
-	struct timespec abstime;
 	trx_t*	trx;
-	int	cmp;
-	int	ret;
 
         trx = (trx_t*) thd->ha_data[innobase_hton.slot];
 
@@ -1700,21 +1698,19 @@ innobase_commit_complete(
                 trx_commit_complete_for_mysql(trx);
         }
 
-        printf("Wait binlog name %s, repl state %lu\n",
-                        trx->repl_wait_binlog_name,
-                        (uint)innobase_repl_state);
-
+#ifdef HAVE_REPLICATION
         if (thd->variables.sync_replication
             && trx->repl_wait_binlog_name
             && innobase_repl_state != 0) {
 
+		struct timespec abstime;
+		int	cmp;
+		int	ret;
+
                 /* In synchronous replication, let us wait until the MySQL
                 replication has sent the relevant binlog segment to the
                 replication slave. */
 
-/* TODO: Make sure MySQL uses some way (TCP_NODELAY?) to ensure that the data
-has been received in the slave! */
-
                 pthread_mutex_lock(&innobase_repl_cond_mutex);
 try_again:
                 if (innobase_repl_state == 0) {
@@ -1809,10 +1805,11 @@ try_again:
 
                 goto try_again;
         }
-
+#endif HAVE_REPLICATION
 	return(0);
 }
 
+#ifdef HAVE_REPLICATION
 /*********************************************************************
 In synchronous replication, reports to InnoDB up to which binlog position
 we have sent the binlog to the slave. Note that replication is synchronous
@@ -1908,6 +1905,7 @@ innobase_repl_report_sent_binlog(
                 pthread_cond_broadcast(&innobase_repl_cond);
         }
 }
+#endif /* HAVE_REPLICATION */
 
 /*********************************************************************
 Rolls back a transaction or the latest SQL statement. */
@@ -2138,17 +2136,20 @@ ha_innobase::get_row_type() const
 
 /********************************************************************
 Gives the file extension of an InnoDB single-table tablespace. */
+static const char* ha_innobase_exts[] = {
+  ".ibd",
+  NullS
+};
 
 const char**
 ha_innobase::bas_ext() const
 /*========================*/
 				/* out: file extension string */
 {
-	static const char* ext[] = {".ibd", NullS};
-
-	return(ext);
+  return ha_innobase_exts;
 }
 
+
 /*********************************************************************
 Normalizes a table name string. A normalized name consists of the
 database name catenated to '/' and table name. An example:
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 2179eaa7f8f839d480e2be702b9df7f7b53ca4a8..2049efb73db02686074db1e89d221aac922855ad 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -123,8 +123,16 @@ void mi_check_print_warning(MI_CHECK *param, const char *fmt,...)
 
 }
 
+static const char *ha_myisam_exts[] = {
+  ".MYI",
+  ".MYD",
+  NullS
+};
+
 const char **ha_myisam::bas_ext() const
-{ static const char *ext[]= { ".MYI",".MYD", NullS }; return ext; }
+{
+  return ha_myisam_exts;
+}
 
 
 const char *ha_myisam::index_type(uint key_number)
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index 4cd39660728c25afa4c046a2081a653ec4080815..f7c0abf98106f61038aea43ec55b36c09d108bd5 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -32,8 +32,16 @@
 ** MyISAM MERGE tables
 *****************************************************************************/
 
+static const char *ha_myisammrg_exts[] = {
+  ".MRG",
+  NullS
+};
+
 const char **ha_myisammrg::bas_ext() const
-{ static const char *ext[]= { ".MRG", NullS }; return ext; }
+{
+  return ha_myisammrg_exts;
+}
+
 
 const char *ha_myisammrg::index_type(uint key_number)
 {
@@ -392,6 +400,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
   const char **table_names, **pos;
   TABLE_LIST *tables= (TABLE_LIST*) create_info->merge_list.first;
   THD *thd= current_thd;
+  uint dirlgt= dirname_length(name);
   DBUG_ENTER("ha_myisammrg::create");
 
   if (!(table_names= (const char**)
@@ -405,11 +414,30 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
       tbl= find_temporary_table(thd, tables->db, tables->table_name);
     if (!tbl)
     {
-      uint length= my_snprintf(buff,FN_REFLEN,"%s%s/%s",
-			       mysql_real_data_home,
+      /*
+        Construct the path to the MyISAM table. Try to meet two conditions:
+        1.) Allow to include MyISAM tables from different databases, and
+        2.) allow for moving DATADIR around in the file system.
+        The first means that we need paths in the .MRG file. The second
+        means that we should not have absolute paths in the .MRG file.
+        The best, we can do, is to use 'mysql_data_home', which is '.'
+        in mysqld and may be an absolute path in an embedded server.
+        This means that it might not be possible to move the DATADIR of
+        an embedded server without changing the paths in the .MRG file.
+      */
+      uint length= my_snprintf(buff, FN_REFLEN, "%s/%s/%s", mysql_data_home,
 			       tables->db, tables->table_name);
-      if (!(table_name= thd->strmake(buff, length)))
-	DBUG_RETURN(HA_ERR_OUT_OF_MEM);
+      /*
+        If a MyISAM table is in the same directory as the MERGE table,
+        we use the table name without a path. This means that the
+        DATADIR can easily be moved even for an embedded server as long
+        as the MyISAM tables are from the same database as the MERGE table.
+      */
+      if ((dirname_length(buff) == dirlgt) && ! memcmp(buff, name, dirlgt))
+        table_name= tables->table_name;
+      else
+        if (! (table_name= thd->strmake(buff, length)))
+          DBUG_RETURN(HA_ERR_OUT_OF_MEM);
     }
     else
       table_name= (*tbl)->s->path;
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index e2d954b1928032655b1f51758bf681068a01ebd7..b61dbd1792c1923cdaae009720ddb3f821402001 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -418,11 +418,28 @@ void ha_ndbcluster::no_uncommitted_rows_reset(THD *thd)
     #   The mapped error code
 */
 
-void ha_ndbcluster::invalidateDictionaryCache()
+void ha_ndbcluster::invalidate_dictionary_cache(bool global)
 {
   NDBDICT *dict= get_ndb()->getDictionary();
+  DBUG_ENTER("invalidate_dictionary_cache");
   DBUG_PRINT("info", ("invalidating %s", m_tabname));
-  dict->invalidateTable(m_tabname);
+
+  if (global)
+  {
+    const NDBTAB *tab= dict->getTable(m_tabname);
+    if (!tab)
+      DBUG_VOID_RETURN;
+    if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
+    {
+      // Global cache has already been invalidated
+      dict->removeCachedTable(m_tabname);
+      global= FALSE;
+    }
+    else
+      dict->invalidateTable(m_tabname);
+  }
+  else
+    dict->removeCachedTable(m_tabname);
   table->s->version=0L;			/* Free when thread is ready */
   /* Invalidate indexes */
   for (uint i= 0; i < table->s->keys; i++)
@@ -434,18 +451,28 @@ void ha_ndbcluster::invalidateDictionaryCache()
     switch(idx_type) {
     case(PRIMARY_KEY_ORDERED_INDEX):
     case(ORDERED_INDEX):
-      dict->invalidateIndex(index->getName(), m_tabname);
+      if (global)
+        dict->invalidateIndex(index->getName(), m_tabname);
+      else
+        dict->removeCachedIndex(index->getName(), m_tabname);
       break;
     case(UNIQUE_ORDERED_INDEX):
-      dict->invalidateIndex(index->getName(), m_tabname);
+      if (global)
+        dict->invalidateIndex(index->getName(), m_tabname);
+      else
+        dict->removeCachedIndex(index->getName(), m_tabname);
     case(UNIQUE_INDEX):
-      dict->invalidateIndex(unique_index->getName(), m_tabname);
+      if (global)
+        dict->invalidateIndex(unique_index->getName(), m_tabname);
+      else
+        dict->removeCachedIndex(unique_index->getName(), m_tabname);
       break;
     case(PRIMARY_KEY_INDEX):
     case(UNDEFINED_INDEX):
       break;
     }
   }
+  DBUG_VOID_RETURN;
 }
 
 int ha_ndbcluster::ndb_err(NdbTransaction *trans)
@@ -457,7 +484,7 @@ int ha_ndbcluster::ndb_err(NdbTransaction *trans)
   ERR_PRINT(err);
   switch (err.classification) {
   case NdbError::SchemaError:
-    invalidateDictionaryCache();
+    invalidate_dictionary_cache(TRUE);
 
     if (err.code==284)
     {
@@ -882,7 +909,14 @@ int ha_ndbcluster::get_metadata(const char *path)
 
     if (!(tab= dict->getTable(m_tabname)))
       ERR_RETURN(dict->getNdbError());
-    DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
+    // Check if thread has stale local cache
+    if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
+    {
+      invalidate_dictionary_cache(FALSE);
+      if (!(tab= dict->getTable(m_tabname)))
+         ERR_RETURN(dict->getNdbError());
+      DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
+    }
     /*
       Compare FrmData in NDB with frm file from disk.
     */
@@ -901,7 +935,7 @@ int ha_ndbcluster::get_metadata(const char *path)
       if (!invalidating_ndb_table)
       {
         DBUG_PRINT("info", ("Invalidating table"));
-        invalidateDictionaryCache();
+        invalidate_dictionary_cache(TRUE);
         invalidating_ndb_table= TRUE;
       }
       else
@@ -927,7 +961,7 @@ int ha_ndbcluster::get_metadata(const char *path)
   if (error)
     DBUG_RETURN(error);
   
-  m_tableVersion= tab->getObjectVersion();
+  m_table_version= tab->getObjectVersion();
   m_table= (void *)tab; 
   m_table_info= NULL; // Set in external lock
   
@@ -3074,10 +3108,15 @@ int ha_ndbcluster::extra_opt(enum ha_extra_function operation, ulong cache_size)
   DBUG_RETURN(extra(operation));
 }
 
+static const char *ha_ndbcluster_exts[] = {
+ ha_ndb_ext,
+ NullS
+};
 
 const char** ha_ndbcluster::bas_ext() const
-{ static const char *ext[]= { ha_ndb_ext, NullS }; return ext; }
-
+{
+  return ha_ndbcluster_exts;
+}
 
 /*
   How many seeks it will take to read through the table
@@ -3264,15 +3303,25 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
       void *tab_info;
       if (!(tab= dict->getTable(m_tabname, &tab_info)))
         ERR_RETURN(dict->getNdbError());
-      DBUG_PRINT("info", ("Table schema version: %d", tab->getObjectVersion()));
-      if (m_table != (void *)tab || m_tableVersion != tab->getObjectVersion())
+      DBUG_PRINT("info", ("Table schema version: %d", 
+                          tab->getObjectVersion()));
+      // Check if thread has stale local cache
+      if (tab->getObjectStatus() == NdbDictionary::Object::Invalid)
+      {
+        invalidate_dictionary_cache(FALSE);
+        if (!(tab= dict->getTable(m_tabname, &tab_info)))
+          ERR_RETURN(dict->getNdbError());
+        DBUG_PRINT("info", ("Table schema version: %d", 
+                            tab->getObjectVersion()));
+      }
+      if (m_table != (void *)tab || m_table_version < tab->getObjectVersion())
       {
         /*
           The table has been altered, refresh the index list
         */
         build_index_list(ndb, table, ILBP_OPEN);  
         m_table= (void *)tab;
-        m_tableVersion = tab->getObjectVersion();
+        m_table_version = tab->getObjectVersion();
       }
       m_table_info= tab_info;
     }
@@ -3316,7 +3365,6 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
         thd_ndb->stmt= NULL;
       }
     }
-    m_table= NULL;
     m_table_info= NULL;
 
     /*
@@ -4031,7 +4079,13 @@ int ha_ndbcluster::rename_table(const char *from, const char *to)
   dict= ndb->getDictionary();
   if (!(orig_tab= dict->getTable(m_tabname)))
     ERR_RETURN(dict->getNdbError());
-
+  // Check if thread has stale local cache
+  if (orig_tab->getObjectStatus() == NdbDictionary::Object::Invalid)
+  {
+    dict->removeCachedTable(m_tabname);
+    if (!(orig_tab= dict->getTable(m_tabname)))
+      ERR_RETURN(dict->getNdbError());
+  }
   m_table= (void *)orig_tab;
   // Change current database to that of target table
   set_dbname(to);
@@ -4154,7 +4208,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
   m_active_trans(NULL),
   m_active_cursor(NULL),
   m_table(NULL),
-  m_tableVersion(-1),
+  m_table_version(-1),
   m_table_info(NULL),
   m_table_flags(HA_REC_NOT_IN_SEQ |
                 HA_NULL_IN_KEY |
@@ -4404,7 +4458,6 @@ int ndbcluster_discover(THD* thd, const char *db, const char *name,
       DBUG_RETURN(1);
     ERR_RETURN(err);
   }
-  
   DBUG_PRINT("info", ("Found table %s", tab->getName()));
   
   len= tab->getFrmLength();  
diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h
index 4dbab18b82899ba30c3ef15ec745f699450d1755..81b2873d9dd12be5b6b103737edda17550acaa6f 100644
--- a/sql/ha_ndbcluster.h
+++ b/sql/ha_ndbcluster.h
@@ -558,7 +558,7 @@ private:
   void print_results();
 
   ulonglong get_auto_increment();
-  void invalidateDictionaryCache();
+  void invalidate_dictionary_cache(bool global);
   int ndb_err(NdbTransaction*);
   bool uses_blob_value(bool all_fields);
 
@@ -596,7 +596,7 @@ private:
   NdbTransaction *m_active_trans;
   NdbScanOperation *m_active_cursor;
   void *m_table;
-  int m_tableVersion;
+  int m_table_version;
   void *m_table_info;
   char m_dbname[FN_HEADLEN];
   //char m_schemaname[FN_HEADLEN];
diff --git a/sql/handler.cc b/sql/handler.cc
index 95fd4d976163b3b889504dbaf6b1a78dd3ba0c07..d2501afe97a1465a8de50e0d1f32d3105cfec776 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1772,13 +1772,17 @@ int handler::delete_table(const char *name)
 
 int handler::rename_table(const char * from, const char * to)
 {
-  DBUG_ENTER("handler::rename_table");
-  for (const char **ext=bas_ext(); *ext ; ext++)
+  int error= 0;
+  for (const char **ext= bas_ext(); *ext ; ext++)
   {
-    if (rename_file_ext(from,to,*ext))
-      DBUG_RETURN(my_errno);
+    if (rename_file_ext(from, to, *ext))
+    {
+      if ((error=my_errno) != ENOENT)
+	break;
+      error= 0;
+    }
   }
-  DBUG_RETURN(0);
+  return error;
 }
 
 /*
@@ -2412,6 +2416,7 @@ TYPELIB *ha_known_exts(void)
   return &known_extensions;
 }
 
+#ifdef HAVE_REPLICATION
 /*
   Reports to table handlers up to which position we have sent the binlog
   to a slave in replication
@@ -2468,3 +2473,4 @@ int ha_repl_report_replication_stop(THD *thd)
 
   return 0;
 }
+#endif /* HAVE_REPLICATION */
diff --git a/sql/item.cc b/sql/item.cc
index 541fbf7b178b981e7b26fe64ed7677972d6fcf64..7264f8b2d6859562306867bd91306ba0f954c08b 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -43,11 +43,11 @@ void Hybrid_type_traits::fix_length_and_dec(Item *item, Item *arg) const
   item->max_length= item->float_length(arg->decimals);
 }
 
+static const Hybrid_type_traits real_traits_instance;
 
 const Hybrid_type_traits *Hybrid_type_traits::instance()
 {
-  static const Hybrid_type_traits real_traits;
-  return &real_traits;
+  return &real_traits_instance;
 }
 
 
@@ -67,11 +67,11 @@ Hybrid_type_traits::val_str(Hybrid_type *val, String *to, uint8 decimals) const
 }
 
 /* Hybrid_type_traits_decimal */
+static const Hybrid_type_traits_decimal decimal_traits_instance;
 
 const Hybrid_type_traits_decimal *Hybrid_type_traits_decimal::instance()
 {
-  static const Hybrid_type_traits_decimal decimal_traits;
-  return &decimal_traits;
+  return &decimal_traits_instance;
 }
 
 
@@ -143,11 +143,11 @@ Hybrid_type_traits_decimal::val_str(Hybrid_type *val, String *to,
 }
 
 /* Hybrid_type_traits_integer */
+static const Hybrid_type_traits_integer integer_traits_instance;
 
 const Hybrid_type_traits_integer *Hybrid_type_traits_integer::instance()
 {
-  static const Hybrid_type_traits_integer integer_traits;
-  return &integer_traits;
+  return &integer_traits_instance;
 }
 
 void
diff --git a/sql/item_func.cc b/sql/item_func.cc
index fb21551e22f882c0af1578dcdb1443116d17d2b4..24a3f7927ae1d312d18159e17d5df6e903e501d8 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -4554,6 +4554,7 @@ Item_func_sp::execute(Item **itp)
 {
   DBUG_ENTER("Item_func_sp::execute");
   THD *thd= current_thd;
+  ulong old_client_capabilites;
   int res;
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   st_sp_security_context save_ctx;
@@ -4567,6 +4568,9 @@ Item_func_sp::execute(Item **itp)
     DBUG_RETURN(-1);
   }
 
+  old_client_capabilites= thd->client_capabilities;
+  thd->client_capabilities &= ~CLIENT_MULTI_RESULTS;
+
 #ifndef EMBEDDED_LIBRARY
   my_bool nsok= thd->net.no_send_ok;
   thd->net.no_send_ok= TRUE;
@@ -4582,6 +4586,7 @@ Item_func_sp::execute(Item **itp)
 			     m_sp->m_db.str, m_sp->m_name.str, 0))
   {
     sp_restore_security_context(thd, m_sp, &save_ctx);
+    thd->client_capabilities|= old_client_capabilites &  CLIENT_MULTI_RESULTS;
     DBUG_RETURN(-1);
   }
 #endif
@@ -4595,6 +4600,9 @@ Item_func_sp::execute(Item **itp)
 #ifndef EMBEDDED_LIBRARY
   thd->net.no_send_ok= nsok;
 #endif
+
+  thd->client_capabilities|= old_client_capabilites &  CLIENT_MULTI_RESULTS;
+
   DBUG_RETURN(res);
 }
 
diff --git a/sql/item_func.h b/sql/item_func.h
index ba5a6101e4c56bb5c6771d9a57920c3d8929fcb7..cb0b7dc02a4ce232f073be69783635887b515a66 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1301,6 +1301,8 @@ public:
 
   void cleanup()
   {
+    if (result_field)
+      delete result_field;
     Item_func::cleanup();
     result_field= NULL;
   }
@@ -1318,7 +1320,7 @@ public:
   longlong val_int()
   {
     if (execute(&result_field))
-      return 0LL;
+      return (longlong) 0;
     return result_field->val_int();   
   }
 
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index 1a8cb50081b4d4d7c177306f117c283a1045540e..b9f2ec8a6ca2e25caeffbc4b07cdf8e0a77b2fff 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -55,8 +55,11 @@ String *Item_func_geometry_from_text::val_str(String *str)
     return 0;
   str->length(0);
   str->q_append(srid);
-  if ((null_value= !Geometry::create_from_wkt(&buffer, &trs, str, 0)))
-    return 0;
+  if (!Geometry::create_from_wkt(&buffer, &trs, str, 0))
+    /* We shouldn't return NULL here as NULL is a legal spatial object     */
+    /*  Geometry::bad_spatial_data will produce error message beeing stored*/
+    /*  in GEOMETRY field                                                  */
+    return &Geometry::bad_geometry_data;
   return str;
 }
 
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 64f23c3fc087bac1191e0a1c38c760e9f5092389..3dd4b6618a210dc0aaba058e294dc3b09d738aa2 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -506,7 +506,6 @@ Item_sum_distinct::Item_sum_distinct(THD *thd, Item_sum_distinct *original)
   This is to speedup SUM/AVG(DISTINCT) evaluation for 8-32 bit integer
   values.
 */
-
 struct Hybrid_type_traits_fast_decimal: public
        Hybrid_type_traits_integer
 {
@@ -521,13 +520,16 @@ struct Hybrid_type_traits_fast_decimal: public
     val->traits= Hybrid_type_traits_decimal::instance();
     val->traits->div(val, u);
   }
-  static const Hybrid_type_traits_fast_decimal *instance()
-  {
-    static const Hybrid_type_traits_fast_decimal fast_decimal_traits;
-    return &fast_decimal_traits;
-  }
+  static const Hybrid_type_traits_fast_decimal *instance();
 };
 
+static const Hybrid_type_traits_fast_decimal fast_decimal_traits_instance;
+
+const Hybrid_type_traits_fast_decimal
+  *Hybrid_type_traits_fast_decimal::instance()
+{
+  return &fast_decimal_traits_instance;
+}
 
 void Item_sum_distinct::fix_length_and_dec()
 {
diff --git a/sql/lock.cc b/sql/lock.cc
index a8ccba32d4fa89374504a2c4f23e89e167d11d77..83a39005cd8a08087c8593945b6f0620739a419c 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -82,7 +82,8 @@ static int unlock_external(THD *thd, TABLE **table,uint count);
 static void print_lock_error(int error, const char *);
 
 
-MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
+MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
+                              bool ignore_global_read_lock)
 {
   MYSQL_LOCK *sql_lock;
   TABLE *write_lock_used;
@@ -93,7 +94,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count)
     if (!(sql_lock = get_lock_data(thd,tables,count, 0,&write_lock_used)))
       break;
 
-    if (global_read_lock && write_lock_used)
+    if (global_read_lock && write_lock_used && ! ignore_global_read_lock)
     {
       /*
 	Someone has issued LOCK ALL TABLES FOR READ and we want a write lock
@@ -949,3 +950,49 @@ bool make_global_read_lock_block_commit(THD *thd)
   DBUG_RETURN(error);
 }
 
+
+
+/*
+  Set protection against global read lock.
+
+  SYNOPSIS
+    set_protect_against_global_read_lock()
+    void
+
+  RETURN
+    FALSE       OK, no global read lock exists.
+    TRUE        Error, global read lock exists already.
+*/
+
+bool set_protect_against_global_read_lock(void)
+{
+  bool       global_read_lock_exists;
+
+  pthread_mutex_lock(&LOCK_open);
+  if (! (global_read_lock_exists= test(global_read_lock)))
+    protect_against_global_read_lock++;
+  pthread_mutex_unlock(&LOCK_open);
+  return global_read_lock_exists;
+}
+
+
+/*
+  Unset protection against global read lock.
+
+  SYNOPSIS
+    unset_protect_against_global_read_lock()
+    void
+
+  RETURN
+    void
+*/
+
+void unset_protect_against_global_read_lock(void)
+{
+  pthread_mutex_lock(&LOCK_open);
+  protect_against_global_read_lock--;
+  pthread_mutex_unlock(&LOCK_open);
+  pthread_cond_broadcast(&COND_refresh);
+}
+
+
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 56fbd993aed571ff9580d50b538eca47705eedc3..06c946114ebd8a773201323dfce5f23fed74df1c 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -1151,7 +1151,8 @@ extern pthread_t signal_thread;
 extern struct st_VioSSLAcceptorFd * ssl_acceptor_fd;
 #endif /* HAVE_OPENSSL */
 
-MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **table,uint count);
+MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
+                              bool ignore_global_read_lock= FALSE);
 void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
 void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
 void mysql_unlock_some_tables(THD *thd, TABLE **table,uint count);
@@ -1165,6 +1166,8 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh,
                               bool is_not_commit);
 void start_waiting_global_read_lock(THD *thd);
 bool make_global_read_lock_block_commit(THD *thd);
+bool set_protect_against_global_read_lock(void);
+void unset_protect_against_global_read_lock(void);
 
 /* Lock based on name */
 int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index f1efe0330db2578838d4aa044da29970ab5ff122..169c9e057b5783c76c2e025762645f4fb85e4ad3 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -5495,6 +5495,7 @@ The minimum value for this variable is 4096.",
   {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.",
    (gptr*) &opt_sync_frm, (gptr*) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0,
    0, 0, 0, 0},
+#ifdef HAVE_REPLICATION
   {"sync-replication", OPT_SYNC_REPLICATION,
    "Enable synchronous replication.",
    (gptr*) &global_system_variables.sync_replication,
@@ -5510,6 +5511,7 @@ The minimum value for this variable is 4096.",
    (gptr*) &global_system_variables.sync_replication_timeout,
    (gptr*) &global_system_variables.sync_replication_timeout,
    0, GET_ULONG, REQUIRED_ARG, 10, 0, ~0L, 0, 1, 0},
+#endif /* HAVE_REPLICATION */
   {"table_cache", OPT_TABLE_CACHE,
    "The number of open tables for all threads.", (gptr*) &table_cache_size,
    (gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG, 64, 1, 512*1024L,
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 22f1249ca28b8381eb034dc22e32802a6a7d8d18..2ea435d84effca3ca12da54c09a8b7765624b178 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -820,7 +820,7 @@ bool Protocol_simple::store_long(longlong from)
 #endif
   char buff[20];
   return net_store_data((char*) buff,
-			(uint) (int10_to_str((int) from,buff, -10)-buff));
+			(uint) (int10_to_str((int)from,buff, (from <0)?-10:10)-buff));
 }
 
 
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 8d7a1fe0093896699c793fe92fe46119363763fa..050bbe8694823d5f33f9f528b694f937ec3eb60b 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5090,7 +5090,7 @@ ER_SP_LABEL_MISMATCH 42000
 ER_SP_UNINIT_VAR 01000 
 	eng "Referring to uninitialized variable %s"
 ER_SP_BADSELECT 0A000 
-	eng "SELECT in a stored procedure must have INTO"
+	eng "PROCEDURE %s can't return a result set in the given context"
 ER_SP_BADRETURN 42000 
 	eng "RETURN is only allowed in a FUNCTION"
 ER_SP_BADSTATEMENT 0A000 
@@ -5342,3 +5342,7 @@ ER_SP_DUP_HANDLER 42000
 	eng "Duplicate handler declared in the same block"
 ER_SP_NOT_VAR_ARG 42000
 	eng "OUT or INOUT argument %d for routine %s is not a variable"
+ER_SP_NO_RETSET_IN_FUNC 0A000
+	eng "Not allowed to return a result set from a function"
+ER_CANT_CREATE_GEOMETRY_OBJECT 22003 
+	eng "Cannot get geometry object from data you send to the GEOMETRY field"
diff --git a/sql/spatial.cc b/sql/spatial.cc
index bcfefd9dde84446457d7873b5a1ee76c6b58b82b..427648850e4d3365c2ad845796b389f8cbe968a8 100644
--- a/sql/spatial.cc
+++ b/sql/spatial.cc
@@ -22,6 +22,8 @@
 
 /***************************** Gis_class_info *******************************/
 
+String Geometry::bad_geometry_data("Bad object", &my_charset_bin);
+
 Geometry::Class_info *Geometry::ci_collection[Geometry::wkb_end+1]=
 {
   NULL, NULL, NULL, NULL, NULL, NULL, NULL
diff --git a/sql/spatial.h b/sql/spatial.h
index b96434831a1e017353d9576695b8e7b29eb7c4bf..438ec171a72f7eddf52e73902fd72e154245bcfa 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -173,6 +173,8 @@ public:
   static void operator delete(void *ptr, void *buffer)
   {}
 
+  static String bad_geometry_data;
+
   enum wkbType
   {
     wkb_point= 1,
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index d79811aa4e2ffa6781e280e86216912ab15a2366..ade1fb96b9645de35b02d5dd0771e4489e92946a 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -3858,11 +3858,8 @@ fill_record(THD *thd, Field **ptr, List<Item> &values, bool ignore_errors)
     TABLE *table= field->table;
     if (field == table->next_number_field)
       table->auto_increment_field_not_null= TRUE;
-    if ((value->save_in_field(field, 0) < 0) && !ignore_errors)
-    {
-      my_message(ER_UNKNOWN_ERROR, ER(ER_UNKNOWN_ERROR), MYF(0));
+    if (value->save_in_field(field, 0) == -1)
       DBUG_RETURN(TRUE);
-    }
   }
   DBUG_RETURN(thd->net.report_error);
 }
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 9a7a3d64de508097a1e3f3430ef6d6ba5b9e133e..ac8f5a067459732473a8fe35f38ac8777ca0e866 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1117,27 +1117,42 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
 {
   int error;
   delayed_insert *tmp;
+  TABLE *table;
   DBUG_ENTER("delayed_get_table");
 
   if (!table_list->db)
     table_list->db=thd->db;
 
-  /* no match; create a new thread to handle the table */
+  /* Find the thread which handles this table. */
   if (!(tmp=find_handler(thd,table_list)))
   {
-    /* Don't create more than max_insert_delayed_threads */
+    /*
+      No match. Create a new thread to handle the table, but
+      no more than max_insert_delayed_threads.
+    */
     if (delayed_insert_threads >= thd->variables.max_insert_delayed_threads)
       DBUG_RETURN(0);
     thd->proc_info="Creating delayed handler";
     pthread_mutex_lock(&LOCK_delayed_create);
-    if (!(tmp=find_handler(thd,table_list)))	// Was just created
+    /*
+      The first search above was done without LOCK_delayed_create.
+      Another thread might have created the handler in between. Search again.
+    */
+    if (! (tmp= find_handler(thd, table_list)))
     {
+      /*
+        Avoid that a global read lock steps in while we are creating the
+        new thread. It would block trying to open the table. Hence, the
+        DI thread and this thread would wait until after the global
+        readlock is gone. If the read lock exists already, we leave with
+        no table and then switch to non-delayed insert.
+      */
+      if (set_protect_against_global_read_lock())
+        goto err;
       if (!(tmp=new delayed_insert()))
       {
-	thd->fatal_error();
 	my_error(ER_OUTOFMEMORY,MYF(0),sizeof(delayed_insert));
-	pthread_mutex_unlock(&LOCK_delayed_create);
-	DBUG_RETURN(0);
+	goto err1;
       }
       pthread_mutex_lock(&LOCK_thread_count);
       thread_count++;
@@ -1146,10 +1161,8 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
 	  !(tmp->thd.query=my_strdup(table_list->table_name,MYF(MY_WME))))
       {
 	delete tmp;
-	thd->fatal_error();
 	my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
-	pthread_mutex_unlock(&LOCK_delayed_create);
-	DBUG_RETURN(0);
+	goto err1;
       }
       tmp->table_list= *table_list;			// Needed to open table
       tmp->table_list.db= tmp->thd.db;
@@ -1165,10 +1178,8 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
 	pthread_mutex_unlock(&tmp->mutex);
 	tmp->unlock();
 	delete tmp;
-	thd->fatal_error();
-	pthread_mutex_unlock(&LOCK_delayed_create);
 	my_error(ER_CANT_CREATE_THREAD, MYF(0), error);
-	DBUG_RETURN(0);
+	goto err1;
       }
 
       /* Wait until table is open */
@@ -1178,6 +1189,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
 	pthread_cond_wait(&tmp->cond_client,&tmp->mutex);
       }
       pthread_mutex_unlock(&tmp->mutex);
+      unset_protect_against_global_read_lock();
       thd->proc_info="got old table";
       if (tmp->thd.killed)
       {
@@ -1189,28 +1201,34 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
 	  thd->net.last_errno=tmp->thd.net.last_errno;
 	}
 	tmp->unlock();
-	pthread_mutex_unlock(&LOCK_delayed_create);
-	DBUG_RETURN(0);				// Continue with normal insert
+	goto err;
       }
       if (thd->killed)
       {
 	tmp->unlock();
-	pthread_mutex_unlock(&LOCK_delayed_create);
-	DBUG_RETURN(0);
+	goto err;
       }
     }
     pthread_mutex_unlock(&LOCK_delayed_create);
   }
 
   pthread_mutex_lock(&tmp->mutex);
-  TABLE *table=tmp->get_local_table(thd);
+  table= tmp->get_local_table(thd);
   pthread_mutex_unlock(&tmp->mutex);
-  tmp->unlock();
   if (table)
     thd->di=tmp;
   else if (tmp->thd.is_fatal_error)
     thd->fatal_error();
+  /* Unlock the delayed insert object after its last access. */
+  tmp->unlock();
   DBUG_RETURN((table_list->table=table));
+
+ err1:
+  thd->fatal_error();
+  unset_protect_against_global_read_lock();
+ err:
+  pthread_mutex_unlock(&LOCK_delayed_create);
+  DBUG_RETURN(0); // Continue with normal insert
 }
 
 
@@ -1433,6 +1451,14 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg)
   thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED;
   pthread_mutex_unlock(&LOCK_thread_count);
 
+  /*
+    Wait until the client runs into pthread_cond_wait(),
+    where we free it after the table is opened and di linked in the list.
+    If we did not wait here, the client might detect the opened table
+    before it is linked to the list. It would release LOCK_delayed_create
+    and allow another thread to create another handler for the same table,
+    since it does not find one in the list.
+  */
   pthread_mutex_lock(&di->mutex);
 #if !defined( __WIN__) && !defined(OS2)	/* Win32 calls this in pthread_create */
   if (my_thread_init())
@@ -1547,8 +1573,17 @@ extern "C" pthread_handler_decl(handle_delayed_insert,arg)
 
     if (di->tables_in_use && ! thd->lock)
     {
-      /* request for new delayed insert */
-      if (!(thd->lock=mysql_lock_tables(thd,&di->table,1)))
+      /*
+        Request for new delayed insert.
+        Lock the table, but avoid to be blocked by a global read lock.
+        If we got here while a global read lock exists, then one or more
+        inserts started before the lock was requested. These are allowed
+        to complete their work before the server returns control to the
+        client which requested the global read lock. The delayed insert
+        handler will close the table and finish when the outstanding
+        inserts are done.
+      */
+      if (! (thd->lock= mysql_lock_tables(thd, &di->table, 1, TRUE)))
       {
 	/* Fatal error */
 	di->dead= 1;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index c5ef9f4e713a7cb400b79a8fd2ef8a57b4932b80..0cb3a1cbc11f2e2b999c0e0e1ffaa24cb9249cc1 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3010,6 +3010,10 @@ unsent_create_error:
     goto error;
 #else
     {
+      /* Ignore temporary tables if this is "SHOW CREATE VIEW" */
+      if (lex->only_view)
+        first_table->skip_temporary= 1;
+
       if (check_db_used(thd, all_tables) ||
 	  check_access(thd, SELECT_ACL | EXTRA_ACL, first_table->db,
 		       &first_table->grant.privilege, 0, 0))
@@ -4052,7 +4056,7 @@ unsent_create_error:
 	{
 	  if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
 	  {
-	    my_message(ER_SP_BADSELECT, ER(ER_SP_BADSELECT), MYF(0));
+	    my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
 #ifndef EMBEDDED_LIBRARY
 	    thd->net.no_send_ok= nsok;
 #endif
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 27e75fd99408c9912b2b6fdacd14d5789738cd8c..80bf409f7a4a6de2de47c34b48ec51dea19268d7 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1442,6 +1442,12 @@ create_function_tail:
 	    LEX *lex= Lex;
 	    sp_head *sp= lex->sphead;
 
+	    if (sp->m_multi_results)
+	    {
+	      my_message(ER_SP_NO_RETSET_IN_FUNC, ER(ER_SP_NO_RETSET_IN_FUNC),
+	                 MYF(0));
+	      YYABORT;
+	    }
 	    if (sp->check_backpatch(YYTHD))
 	      YYABORT;
 	    lex->sql_command= SQLCOM_CREATE_SPFUNCTION;