diff --git a/ChangeLog b/ChangeLog
index 75202c115610ea62a68873124a9913bb9d5d045b..90124431afb6fadc3644f72c85bf3a9ceb98b5f0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -251,3 +251,5 @@
 	* Correct socket close logic -- needs to disconnect TCP socket on close
 	* uIP webserver now seems to be fully functional
 	* fs/ and lib/ subystem debug can not be selectively enabled/disabled
+	* Added vsnprintf
+	* Integrated uIP telnetd
diff --git a/Documentation/NuttX.html b/Documentation/NuttX.html
index 954ee19eed52f89ce05c0c82f9651132b0df2dce..17ec1169d40fae1cc894bf8818111ab5ce8ad943 100644
--- a/Documentation/NuttX.html
+++ b/Documentation/NuttX.html
@@ -731,6 +731,8 @@ Other memory:
 	* Correct socket close logic -- needs to disconnect TCP socket on close
 	* uIP webserver now seems to be fully functional
 	* fs/ and lib/ subystem debug can not be selectively enabled/disabled
+	* Added vsnprintf
+	* Integrated uIP telnetd
 </pre></ul>
 
 <table width ="100%">
diff --git a/TODO b/TODO
index 197a966b00d0861782c1de5b3dd01fd689bb6926..4484be424cf87d0e42d2608b79f7241706b4ed15 100644
--- a/TODO
+++ b/TODO
@@ -31,8 +31,6 @@ o C++ Support
 o Network
 - Did not implement send() and sendto() timeouts.  Option is setable via setsockopt,
   but is not implemented.
-- uIP's netutils/telnetd (and maybe others) are seriously broken.
-  Need to be re-written to use listen() and accept()
 - uIP's netutils/smtp, dpcpc, resolv, webclient -- untested
 - Should implement SOCK_RAW
 - Performance Improvements (uIP is not very fast):
diff --git a/include/net/uip/telnetd.h b/include/net/uip/telnetd.h
new file mode 100644
index 0000000000000000000000000000000000000000..32247c206b0d53acb762ebd141540ce8a554e5af
--- /dev/null
+++ b/include/net/uip/telnetd.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+ * include/net/uip/telnetd.h
+ *
+ *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * This is a leverage of similar logic from uIP:
+ *
+ *   Author: Adam Dunkels <adam@sics.se>
+ *   Copyright (c) 2003, Adam Dunkels.
+ *   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 Institute 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 INSTITUTE 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 INSTITUTE 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.
+ ****************************************************************************/
+
+#ifndef __NET_UIP_TELNETD_H
+#define __NET_UIP_TELNETD_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef __cplusplus
+#define EXTERN extern "C"
+extern "C" {
+#else
+#define EXTERN extern
+#endif
+
+/* Start the telnet server -- does not return unless an error occurs */
+
+EXTERN void telnetd_init(void);
+
+#undef EXTERN
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __NET_UIP_TELNETD_H */
diff --git a/netutils/telnetd/shell.c b/netutils/telnetd/shell.c
index 3c68350e0949ba463c230e0c3b0c2344a895e191..93fd116012a244676f4d84f4b98b432bc52bc07e 100644
--- a/netutils/telnetd/shell.c
+++ b/netutils/telnetd/shell.c
@@ -1,94 +1,139 @@
- /*
- * Copyright (c) 2003, Adam Dunkels.
- * All rights reserved.
+/****************************************************************************
+ * netutils/telnetd/telnetd.c
+ *
+ *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * This is a leverage of similar logic from uIP:
+ *
+ *   Author: Adam Dunkels <adam@sics.se>
+ *   Copyright (c) 2003, Adam Dunkels.
+ *   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. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
+ * 3. Neither the name of the Institute 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 AUTHOR ``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 AUTHOR 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.
- */
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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 "shell.h"
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
 
 #include <string.h>
+#include "shell.h"
 
-struct ptentry {
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+#define SHELL_PROMPT "uIP 1.0> "
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct ptentry_s
+{
   char *commandstr;
-  void (* pfunc)(char *str);
+  void (* pfunc)(void *handle, char *str);
 };
 
-#define SHELL_PROMPT "uIP 1.0> "
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void parse(void *handle, register char *str, struct ptentry_s *t);
+static void help(void *handle, char *str);
+static void unknown(void *handle, char *str);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct ptentry_s g_parsetab[] =
+{
+  {"stats", help},
+  {"conn",  help},
+  {"help",  help},
+  {"exit",  shell_quit},
+  {"?",     help},
+  {NULL,    unknown}
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
 
-static void parse(register char *str, struct ptentry *t)
+static void parse(void *handle, char *str, struct ptentry_s *t)
 {
-  struct ptentry *p;
-  for(p = t; p->commandstr != NULL; ++p) {
-    if(strncmp(p->commandstr, str, strlen(p->commandstr)) == 0) {
-      break;
+  struct ptentry_s *p;
+
+  for (p = t; p->commandstr != NULL; ++p)
+    {
+      if (strncmp(p->commandstr, str, strlen(p->commandstr)) == 0)
+        {
+          break;
+        }
     }
-  }
 
-  p->pfunc(str);
+  p->pfunc(handle, str);
 }
 
-static void help(char *str)
+static void help(void *handle, char *str)
 {
-  shell_output("Available commands:", "");
-  shell_output("stats   - show network statistics", "");
-  shell_output("conn    - show TCP connections", "");
-  shell_output("help, ? - show help", "");
-  shell_output("exit    - exit shell", "");
+  shell_output(handle, "Available commands:");
+  shell_output(handle, "stats   - show network statistics");
+  shell_output(handle, "conn    - show TCP connections");
+  shell_output(handle, "help, ? - show help");
+  shell_output(handle, "exit    - exit shell");
 }
 
-static void unknown(char *str)
+static void unknown(void *handle, char *str)
 {
-  if(strlen(str) > 0) {
-    shell_output("Unknown command: ", str);
-  }
+  if (strlen(str) > 0)
+    {
+      shell_output(handle, "Unknown command: ", str);
+    }
 }
 
-static struct ptentry parsetab[] =
-  {{"stats", help},
-   {"conn", help},
-   {"help", help},
-   {"exit", shell_quit},
-   {"?", help},
-
-   /* Default action */
-   {NULL, unknown}};
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
 
-void shell_init(void)
+void shell_init(void *handle)
 {
 }
 
-void shell_start(void)
+void shell_start(void *handle)
 {
-  shell_output("uIP command shell", "");
-  shell_output("Type '?' and return for help", "");
-  shell_prompt(SHELL_PROMPT);
+  shell_output(handle, "uIP command shell");
+  shell_output(handle, "Type '?' and return for help");
+  shell_prompt(handle, SHELL_PROMPT);
 }
 
-void shell_input(char *cmd)
+void shell_input(void *handle, char *cmd)
 {
-  parse(cmd, parsetab);
-  shell_prompt(SHELL_PROMPT);
+  parse(handle, cmd, g_parsetab);
+  shell_prompt(handle, SHELL_PROMPT);
 }
diff --git a/netutils/telnetd/shell.h b/netutils/telnetd/shell.h
index 8f89b2119cc1b487565473fe662090de2efaf0df..32325fe17f4ae06d88a6b8fe94ed1c3081b615eb 100644
--- a/netutils/telnetd/shell.h
+++ b/netutils/telnetd/shell.h
@@ -52,14 +52,14 @@
  * be used to start listening for signals.
  */
 
-void shell_init(void);
+void shell_init(void *handle);
 
 /* Start the shell back-end.
  *
  * Called by the front-end when a new shell is started.
  */
 
-void shell_start(void);
+void shell_start(void *handle);
 
 /* Process a shell command.
  *
@@ -70,34 +70,28 @@ void shell_start(void);
  * command The command to be processed.
  */
 
-void shell_input(char *command);
+void shell_input(void *handle, char *command);
 
 /* Quit the shell. */
 
-void shell_quit(char *);
-
+void shell_quit(void *handle, char *);
 
 /* Print a string to the shell window.
  *
  * This function is implemented by the shell GUI / telnet server and
  * can be called by the shell back-end to output a string in the
  * shell window. The string is automatically appended with a linebreak.
- *
- * str1 The first half of the string to be output.
- * str2 The second half of the string to be output.
  */
 
-void shell_output(char *str1, char *str2);
+void shell_output(void *handle, const char *fmt, ...);
 
 /* Print a prompt to the shell window.
  *
  * This function can be used by the shell back-end to print out a
  * prompt to the shell window.
  *
- * prompt The prompt to be printed.
- *
  */
 
-void shell_prompt(char *prompt);
+void shell_prompt(void *handle, char *prompt);
 
 #endif /* __SHELL_H__ */
diff --git a/netutils/telnetd/telnetd.c b/netutils/telnetd/telnetd.c
index bf39826f501e11b2e9220f3cb750d64c96e04d02..64d14842d9781cd7685d925bb5f9e259934186dd 100644
--- a/netutils/telnetd/telnetd.c
+++ b/netutils/telnetd/telnetd.c
@@ -1,43 +1,67 @@
-/* netutils/telnetd/telnetd.c
+/****************************************************************************
+ * netutils/telnetd/telnetd.c
  *
- * Copyright (c) 2003, Adam Dunkels.
- * All rights reserved.
+ *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * This is a leverage of similar logic from uIP:
+ *
+ *   Author: Adam Dunkels <adam@sics.se>
+ *   Copyright (c) 2003, Adam Dunkels.
+ *   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. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
+ * 3. Neither the name of the Institute 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 AUTHOR ``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 AUTHOR 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.
- */
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
 
 #include <sys/types.h>
+#include <sys/socket.h>
+
+#include <stdio.h>
+#include <unistd.h>
 #include <stdlib.h>
+#include <stdarg.h>
 #include <string.h>
+#include <pthread.h>
+#include <debug.h>
 
-#include <net/uip/uip.h>
-#include <net/uip/uip-arch.h>
+#include <net/uip/telnetd.h>
+#include <net/uip/uip-lib.h>
 
-#include "telnetd.h"
 #include "shell.h"
 
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
 #define ISO_nl       0x0a
 #define ISO_cr       0x0d
 
@@ -49,302 +73,417 @@
 #define STATE_DONT   5
 #define STATE_CLOSE  6
 
-static struct telnetd_state s;
-
 #define TELNET_IAC   255
 #define TELNET_WILL  251
 #define TELNET_WONT  252
 #define TELNET_DO    253
 #define TELNET_DONT  254
 
-void shell_quit(char *str)
-{
-  s.state = STATE_CLOSE;
-}
+/* Configurable settings */
 
-static void sendline(char *line)
-{
-  unsigned int i;
+#ifndef CONFIG_NETUTILS_IOBUFFER_SIZE
+# define CONFIG_NETUTILS_IOBUFFER_SIZE 512
+#endif
 
-  for (i = 0; i < TELNETD_CONF_NUMLINES; ++i)
-    {
-      if (s.lines[i] == NULL)
-        {
-          s.lines[i] = line;
-          break;
-        }
-    }
-  if (i == TELNETD_CONF_NUMLINES)
-    {
-      free(line);
-    }
-}
+#ifndef CONFIG_NETUTILS_CMD_SIZE
+# define CONFIG_NETUTILS_CMD_SIZE 40
+#endif
 
-void shell_prompt(char *str)
-{
-  char *line;
-  line = (char*)malloc(TELNETD_CONF_LINELEN);
-  if (line != NULL)
-    {
-      strncpy(line, str, TELNETD_CONF_LINELEN);
-      sendline(line);
-    }
-}
+/* As threads are created to handle each request, a stack must be allocated
+ * for the thread.  Use a default if the user provided no stacksize.
+ */
 
-void shell_output(char *str1, char *str2)
-{
-  unsigned len;
-  char *line;
+#ifndef CONFIG_NETUTILS_TELNETDSTACKSIZE
+# define CONFIG_NETUTILS_TELNETDSTACKSIZE 4096
+#endif
 
-  line = (char*)malloc(TELNETD_CONF_LINELEN);
-  if (line != NULL)
-    {
-      len = strlen(str1);
-      strncpy(line, str1, TELNETD_CONF_LINELEN);
-      if (len < TELNETD_CONF_LINELEN)
-        {
-          strncpy(line + len, str2, TELNETD_CONF_LINELEN - len);
-        }
-      len = strlen(line);
-      if (len < TELNETD_CONF_LINELEN - 2)
-        {
-          line[len] = ISO_cr;
-          line[len+1] = ISO_nl;
-          line[len+2] = 0;
-        }
-      sendline(line);
-    }
-}
+/* Enabled dumping of all input/output buffers */
 
-void telnetd_init(void)
-{
-  uip_listen(HTONS(23));
-  shell_init();
-}
+#undef CONFIG_NETUTILS_TELNETD_DUMPBUFFER
 
-static void acked(void)
-{
-  unsigned int i;
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
 
-  while(s.numsent > 0)
-    {
-      free(s.lines[0]);
-      for (i = 1; i < TELNETD_CONF_NUMLINES; ++i)
-        {
-          s.lines[i - 1] = s.lines[i];
-        }
-      s.lines[TELNETD_CONF_NUMLINES - 1] = NULL;
-      --s.numsent;
-    }
-}
+struct telnetd_s
+{
+  int   tn_sockfd;
+  char  tn_iobuffer[CONFIG_NETUTILS_IOBUFFER_SIZE];
+  char  tn_cmd[CONFIG_NETUTILS_CMD_SIZE];
+  uint8 tn_bufndx;
+  uint8 tn_state;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: telnetd_dumpbuffer
+ *
+ * Description:
+ *   Dump a buffer of data (debug only)
+ *
+ ****************************************************************************/
 
-static void senddata(struct uip_driver_s *dev, struct uip_conn *conn)
+#ifdef CONFIG_NETUTILS_TELNETD_DUMPBUFFER
+static void telnetd_dumpbuffer(const char *msg, const char *buffer, ssize_t nbytes)
 {
-  char *bufptr, *lineptr;
-  int buflen, linelen;
-
-  bufptr = (char*)dev->d_appdata;
-  buflen = 0;
-  for (s.numsent = 0;
-        s.numsent < TELNETD_CONF_NUMLINES && s.lines[s.numsent] != NULL;
-        ++s.numsent)
+#ifdef CONFIG_DEBUG
+  char line[128];
+  int ch;
+  int i;
+  int j;
+
+  dbg("%s:\n", msg);
+  for (i = 0; i < nbytes; i += 16)
     {
-      lineptr = s.lines[s.numsent];
-      linelen = strlen(lineptr);
-      if (linelen > TELNETD_CONF_LINELEN)
-        {
-          linelen = TELNETD_CONF_LINELEN;
-        }
-      if (buflen + linelen < uip_mss(conn))
-        {
-          memcpy(bufptr, lineptr, linelen);
-          bufptr += linelen;
-          buflen += linelen;
-        }
-      else
+      sprintf(line, "%04x: ", i);
+
+      for ( j = 0; j < 16; j++)
         {
-          break;
+          if (i + j < nbytes)
+            {
+              sprintf(&line[strlen(line)], "%02x ", buffer[i+j] );
+            }
+          else
+            {
+              strcpy(&line[strlen(line)], "   ");
+            }
         }
-    }
-  uip_send(dev, dev->d_appdata, buflen);
-}
-
-static void closed(void)
-{
-  unsigned int i;
 
-  for (i = 0; i < TELNETD_CONF_NUMLINES; ++i)
-    {
-      if (s.lines[i] != NULL)
+      for ( j = 0; j < 16; j++)
         {
-          free(s.lines[i]);
+          if (i + j < nbytes)
+            {
+              ch = buffer[i+j];
+              sprintf(&line[strlen(line)], "%c", ch >= 0x20 && ch <= 0x7e ? ch : '.');
+            }
         }
+      dbg("%s\n", line);
     }
+#endif
 }
+#else
+# define telnetd_dumpbuffer(msg,buffer,nbytes)
+#endif
+
+/****************************************************************************
+ * Name: telnetd_putchar
+ *
+ * Description:
+ *   Add another parsed character to the TELNET command string
+ *
+ ****************************************************************************/
 
-static void get_char(uint8 c)
+static void telnetd_putchar(struct telnetd_s *pstate, uint8 ch)
 {
-  if (c == ISO_cr)
+  /* Ignore carriage returns */
+
+  if (ch == ISO_cr)
   {
     return;
   }
 
-  s.buf[(int)s.bufptr] = c;
-  if (s.buf[(int)s.bufptr] == ISO_nl || s.bufptr == sizeof(s.buf) - 1)
+  /* Add all other characters to the cmd buffer */
+
+  pstate->tn_cmd[pstate->tn_bufndx] = ch;
+
+  /* If a newline was added or if the buffer is full, then process it now */
+
+  if (ch == ISO_nl || pstate->tn_bufndx == (CONFIG_NETUTILS_CMD_SIZE - 1))
     {
-      if (s.bufptr > 0)
+      if (pstate->tn_bufndx > 0)
         {
-          s.buf[(int)s.bufptr] = 0;
+          pstate->tn_cmd[pstate->tn_bufndx] = '\0';
         }
-      shell_input(s.buf);
-      s.bufptr = 0;
+
+      telnetd_dumpbuffer("TELNET CMD", pstate->tn_cmd, strlen(pstate->tn_cmd));
+      shell_input(pstate, pstate->tn_cmd);
+      pstate->tn_bufndx = 0;
     }
   else
     {
-      ++s.bufptr;
+      pstate->tn_bufndx++;
+      vdbg("Add '%c', bufndx=%d\n", ch, pstate->tn_bufndx);
     }
 }
 
-static void sendopt(uint8 option, uint8 value)
+/****************************************************************************
+ * Name: telnetd_sendopt
+ *
+ * Description:
+ *
+ ****************************************************************************/
+
+static void telnetd_sendopt(struct telnetd_s *pstate, uint8 option, uint8 value)
 {
-  char *line;
-  line = (char*)malloc(TELNETD_CONF_LINELEN);
-  if (line != NULL)
+  uint8 optbuf[4];
+  optbuf[0] = TELNET_IAC;
+  optbuf[1] = option;
+  optbuf[2] = value;
+  optbuf[3] = 0;
+
+  telnetd_dumpbuffer("Send optbuf", optbuf, 4);
+  if (send(pstate->tn_sockfd, optbuf, 4, 0) < 0)
     {
-      line[0] = TELNET_IAC;
-      line[1] = option;
-      line[2] = value;
-      line[3] = 0;
-      sendline(line);
+      dbg("[%d] Failed to send TELNET_IAC\n", pstate->tn_sockfd);
     }
 }
 
-static void newdata(struct uip_driver_s *dev)
-{
-  uint16 len;
-  uint8 c;
-  char *dataptr;
+/****************************************************************************
+ * Name: telnetd_receive
+ *
+ * Description:
+ *   Process a received TELENET buffer
+ *
+ ****************************************************************************/
 
-  len = uip_datalen(dev);
-  dataptr = (char *)dev->d_appdata;
+static int telnetd_receive(struct telnetd_s *pstate, size_t len)
+{
+  char *ptr = pstate->tn_iobuffer;
+  uint8 ch;
 
-  while(len > 0 && s.bufptr < sizeof(s.buf))\
+  while (len > 0)
     {
-      c = *dataptr;
-      ++dataptr;
-      --len;
-      switch(s.state)
+      ch = *ptr++;
+      len--;
+
+      vdbg("ch=%02x state=%d\n", ch, pstate->tn_state);
+      switch (pstate->tn_state)
         {
           case STATE_IAC:
-            if (c == TELNET_IAC)
+            if (ch == TELNET_IAC)
               {
-                get_char(c);
-                s.state = STATE_NORMAL;
+                telnetd_putchar(pstate, ch);
+                pstate->tn_state = STATE_NORMAL;
              }
             else
               {
-                switch (c)
+                switch (ch)
                   {
                     case TELNET_WILL:
-                      s.state = STATE_WILL;
+                      pstate->tn_state = STATE_WILL;
                       break;
+
                     case TELNET_WONT:
-                      s.state = STATE_WONT;
+                      pstate->tn_state = STATE_WONT;
                       break;
+
                     case TELNET_DO:
-                      s.state = STATE_DO;
+                      pstate->tn_state = STATE_DO;
                       break;
+
                     case TELNET_DONT:
-                      s.state = STATE_DONT;
+                      pstate->tn_state = STATE_DONT;
                       break;
+
                     default:
-                      s.state = STATE_NORMAL;
+                      pstate->tn_state = STATE_NORMAL;
                       break;
                   }
               }
             break;
+
           case STATE_WILL:
             /* Reply with a DONT */
-            sendopt(TELNET_DONT, c);
-            s.state = STATE_NORMAL;
+
+            telnetd_sendopt(pstate, TELNET_DONT, ch);
+            pstate->tn_state = STATE_NORMAL;
             break;
 
           case STATE_WONT:
             /* Reply with a DONT */
-            sendopt(TELNET_DONT, c);
-            s.state = STATE_NORMAL;
+
+            telnetd_sendopt(pstate, TELNET_DONT, ch);
+            pstate->tn_state = STATE_NORMAL;
             break;
+
           case STATE_DO:
             /* Reply with a WONT */
-            sendopt(TELNET_WONT, c);
-            s.state = STATE_NORMAL;
+
+            telnetd_sendopt(pstate, TELNET_WONT, ch);
+            pstate->tn_state = STATE_NORMAL;
             break;
+
           case STATE_DONT:
             /* Reply with a WONT */
-            sendopt(TELNET_WONT, c);
-            s.state = STATE_NORMAL;
+
+            telnetd_sendopt(pstate, TELNET_WONT, ch);
+            pstate->tn_state = STATE_NORMAL;
             break;
+
           case STATE_NORMAL:
-            if (c == TELNET_IAC)
+            if (ch == TELNET_IAC)
               {
-                s.state = STATE_IAC;
+                pstate->tn_state = STATE_IAC;
               }
             else
               {
-                get_char(c);
+                telnetd_putchar(pstate, ch);
               }
             break;
         }
     }
+  return OK;
 }
 
-/* This function is called by the UIP interrupt handling logic whenevent an
- * event of interest occurs.
- */
+/****************************************************************************
+ * Name: telnetd_handler
+ *
+ * Description:
+ *   Each time a new connection to port 23 is made, a new thread is created
+ *   that begins at this entry point.  There should be exactly one argument
+ *   and it should be the socket descriptor (+1).
+ *
+ ****************************************************************************/
 
-uint8 uip_interrupt_event(struct uip_driver_s *dev, struct uip_conn *conn, uint8 flags)
+static void *telnetd_handler(void *arg)
 {
-#warning OBSOLETE -- needs to be redesigned
-  unsigned int i;
+  struct telnetd_s *pstate = (struct telnetd_s *)malloc(sizeof(struct telnetd_s));
+  int               sockfd = (int)arg;
+  int               ret    = ERROR;
 
-  if (uip_connected_event(flags))
+  dbg("[%d] Started\n", sockfd);
+
+  /* Verify that the state structure was successfully allocated */
+
+  if (pstate)
     {
-      for (i = 0; i < TELNETD_CONF_NUMLINES; ++i)
-      {
-        s.lines[i] = NULL;
-      }
-      s.bufptr = 0;
-      s.state = STATE_NORMAL;
-
-      shell_start();
-  }
 
-  if (s.state == STATE_CLOSE)
-  {
-    s.state = STATE_NORMAL;
-    return UIP_CLOSE;
-  }
+      /* Initialize the thread state structure */
 
-  if (uip_close_event(flags) || uip_abort_event(flags) || uip_timeout_event(flags))
-  {
-    closed();
-  }
+      memset(pstate, 0, sizeof(struct telnetd_s));
+      pstate->tn_sockfd = sockfd;
+      pstate->tn_state  = STATE_NORMAL;
 
-  if (uip_ack_event(flags))
-  {
-    acked();
-  }
+      /* Start up the shell */
 
-  if (uip_newdata_event(flags))
-  {
-    newdata(dev);
-  }
+      shell_init(pstate);
+      shell_start(pstate);
 
-  if (uip_rexmit_event(flags) || uip_newdata_event(flags) || uip_ack_event(flags) ||
-      uip_connected_event(flags) || uip_poll_event(flags))
-  {
-    senddata(dev, conn);
-  }
+      /* Loop processing each TELNET command */
+      do
+        {
+          /* Read a buffer of data from the TELNET client */
+
+          ret = recv(pstate->tn_sockfd, pstate->tn_iobuffer, CONFIG_NETUTILS_IOBUFFER_SIZE, 0);
+          if (ret > 0)
+            {
+
+              /* Process the received TELNET data */
+
+              telnetd_dumpbuffer("Received buffer", pstate->tn_iobuffer, ret);
+              ret = telnetd_receive(pstate, ret);
+            }
+        }
+      while (ret >= 0 && pstate->tn_state != STATE_CLOSE);
+      dbg("[%d] ret=%d tn_state=%d\n", sockfd, ret, pstate->tn_state);
 
-  return flags;
+      /* End of command processing -- Clean up and exit */
+
+      free(pstate);
+    }
+
+  /* Exit the task */
+
+  dbg("[%d] Exitting\n", sockfd);
+  close(sockfd);
+  pthread_exit(NULL);
 }
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: telnetd_init
+ *
+ * Description:
+ *   This is the main processing thread for telnetd.  It never returns
+ *   unless an error occurs
+ *
+ ****************************************************************************/
+
+void telnetd_init(void)
+{
+  /* Execute telnetd_handler on each connection to port 23 */
+
+  uip_server(HTONS(23), telnetd_handler, CONFIG_NETUTILS_TELNETDSTACKSIZE);
+}
+
+/****************************************************************************
+ * Name: shell_prompt
+ *
+ * Description:
+ *   Print a prompt to the shell window.
+ *
+ *   This function can be used by the shell back-end to print out a prompt
+ *   to the shell window.
+ *
+ ****************************************************************************/
+
+void shell_prompt(void *handle, char *str)
+{
+  struct telnetd_s *pstate = (struct telnetd_s *)handle;
+  int len = strlen(str);
+
+  strncpy(pstate->tn_iobuffer, str, len);
+  telnetd_dumpbuffer("Shell prompt", pstate->tn_iobuffer, len);
+  if (send(pstate->tn_sockfd, pstate->tn_iobuffer, len, 0) < 0)
+    {
+      dbg("[%d] Failed to send prompt\n", pstate->tn_sockfd);
+    }
+}
+
+/****************************************************************************
+ * Name: shell_output
+ *
+ * Description:
+ *   Print a string to the shell window.
+ *
+ *   This function is implemented by the shell GUI / telnet server and
+ *   can be called by the shell back-end to output a string in the
+ *   shell window. The string is automatically appended with a linebreak.
+ *
+ ****************************************************************************/
+
+void shell_output(void *handle, const char *fmt, ...)
+{
+  struct telnetd_s *pstate = (struct telnetd_s *)handle;
+  unsigned len;
+  va_list ap;
+
+  va_start(ap, fmt);
+  vsnprintf(pstate->tn_iobuffer, CONFIG_NETUTILS_IOBUFFER_SIZE, fmt, ap);
+  va_end(ap);
+
+  len = strlen(pstate->tn_iobuffer);
+  if (len < CONFIG_NETUTILS_IOBUFFER_SIZE - 2)
+    {
+      pstate->tn_iobuffer[len]   = ISO_cr;
+      pstate->tn_iobuffer[len+1] = ISO_nl;
+      pstate->tn_iobuffer[len+2] = '\0';
+    }
+
+  telnetd_dumpbuffer("Shell output", pstate->tn_iobuffer, len+2);
+  if (send(pstate->tn_sockfd, pstate->tn_iobuffer, len+2, 0) < 0)
+    {
+      dbg("[%d] Failed to send prompt\n", pstate->tn_sockfd);
+    }
+}
+
+/****************************************************************************
+ * Name: shell_quit
+ *
+ * Description:
+ *   Quit the shell
+ *
+ ****************************************************************************/
+
+void shell_quit(void *handle, char *str)
+{
+  struct telnetd_s *pstate = (struct telnetd_s *)handle;
+  pstate->tn_state = STATE_CLOSE;
+}
+
diff --git a/netutils/telnetd/telnetd.h b/netutils/telnetd/telnetd.h
deleted file mode 100644
index 4eef0b72696d2d186e06c0e74de1fdf4bd8ef25b..0000000000000000000000000000000000000000
--- a/netutils/telnetd/telnetd.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2003, Adam Dunkels.
- * 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. The name of the author may not be used to endorse or promote
- *    products derived from this software without specific prior
- *    written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
- */
-
-#ifndef __TELNETD_H__
-#define __TELNETD_H__
-
-#include <sys/types.h>
-#include <net/uip/uipopt.h>
-
-#ifndef TELNETD_CONF_LINELEN
-#define TELNETD_CONF_LINELEN 40
-#endif
-#ifndef TELNETD_CONF_NUMLINES
-#define TELNETD_CONF_NUMLINES 16
-#endif
-
-struct telnetd_state
-{
-  char *lines[TELNETD_CONF_NUMLINES];
-  char buf[TELNETD_CONF_LINELEN];
-  char bufptr;
-  uint8 numsent;
-  uint8 state;
-};
-
-#endif /* __TELNETD_H__ */
diff --git a/netutils/webserver/httpd.c b/netutils/webserver/httpd.c
index 08ec2a29573d91ca9f42242a8e274a1d3b42a253..755d118926373a0e39fe30b168dd75559f7196ff 100644
--- a/netutils/webserver/httpd.c
+++ b/netutils/webserver/httpd.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * httpd
+ * netutils/webserver/httpd.c
  * httpd Web server
  *
  *   Copyright (C) 2007 Gregory Nutt. All rights reserved.
@@ -510,7 +510,7 @@ int httpd_listen(void)
 {
   /* Execute httpd_handler on each connection to port 80 */
 
-  uip_server(HTONS(80), httpd_handler, CONFIG_EXAMPLES_UIP_HTTPDSTACKSIZE);
+  uip_server(HTONS(80), httpd_handler, CONFIG_NETUTILS_HTTPDSTACKSIZE);
 
   /* uip_server only returns on errors */
 
diff --git a/netutils/webserver/httpd.h b/netutils/webserver/httpd.h
index 7e70ccd41aa98aeff0570f68e9303f91a4a72334..9b5ba58d54b4527aea441ecb004ad31575b20f7a 100644
--- a/netutils/webserver/httpd.h
+++ b/netutils/webserver/httpd.h
@@ -70,8 +70,8 @@
  * for the thread.  Use a default if the user provided no stacksize.
  */
 
-#ifndef CONFIG_EXAMPLES_UIP_HTTPDSTACKSIZE
-# define CONFIG_EXAMPLES_UIP_HTTPDSTACKSIZE 4096
+#ifndef CONFIG_NETUTILS_HTTPDSTACKSIZE
+# define CONFIG_NETUTILS_HTTPDSTACKSIZE 4096
 #endif
 
 /****************************************************************************