Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.1210
diff -u -r1.1210 Makefile.in
--- gdb/Makefile.in	2 Jul 2012 15:29:33 -0000	1.1210
+++ gdb/Makefile.in	12 Jul 2012 10:35:11 -0000
@@ -216,6 +216,15 @@
 SUBDIR_MI_CFLAGS=
 
 #
+# MI telnet definitions
+#
+SUBDIR_MITEL_OBS = mi-telnet.o
+SUBDIR_MITEL_SRCS = mi/mi-telnet.c
+SUBDIR_MITEL_DEPS=
+SUBDIR_MITEL_LDFLAGS=
+SUBDIR_MITEL_CFLAGS= -DENABLE_GDBMITEL
+
+#
 # TUI sub directory definitions
 #
 
@@ -1894,6 +1903,10 @@
 	$(COMPILE) $(srcdir)/mi/mi-common.c
 	$(POSTCOMPILE)
 
+mi-telnet.o: $(srcdir)/mi/mi-telnet.c
+	$(COMPILE) $(srcdir)/mi/mi-telnet.c
+	$(POSTCOMPILE)
+
 # gdb/common/ dependencies
 #
 # Need to explicitly specify the compile rule as make will do nothing
Index: gdb/configure
===================================================================
RCS file: /cvs/src/src/gdb/configure,v
retrieving revision 1.370
diff -u -r1.370 configure
--- gdb/configure	2 Jul 2012 20:31:07 -0000	1.370
+++ gdb/configure	12 Jul 2012 10:35:13 -0000
@@ -784,6 +784,7 @@
 enable_64_bit_bfd
 enable_gdbcli
 enable_gdbmi
+enable_gdbmitel
 enable_tui
 enable_gdbtk
 with_libunwind_ia64
@@ -1462,6 +1463,7 @@
   --enable-64-bit-bfd     64-bit support (on hosts with narrower word sizes)
   --disable-gdbcli        disable command-line interface (CLI)
   --disable-gdbmi         disable machine-interface (MI)
+  --enable-gdbmitel       enable remote interface over telnet
   --enable-tui            enable full-screen terminal user interface (TUI)
   --enable-gdbtk          enable gdbtk graphical user interface (GUI)
   --enable-profiling      enable profiling of GDB
@@ -5237,6 +5239,28 @@
   fi
 fi
 
+# Enable MI telnet.
+# Check whether --enable-gdbmitel was given.
+if test "${enable_gdbmitel+set}" = set; then :
+  enableval=$enable_gdbmitel; case $enableval in
+    yes | no)
+      ;;
+    *)
+      as_fn_error "bad value $enableval for --enable-gdbmitel" "$LINENO" 5 ;;
+  esac
+else
+  enable_gdbmitel=no
+fi
+
+if test x"$enable_gdbmitel" = xyes; then
+  if test -d $srcdir/mi; then
+    CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_MITEL_OBS)"
+    CONFIG_DEPS="$CONFIG_DEPS \$(SUBDIR_MITEL_DEPS)"
+    CONFIG_SRCS="$CONFIG_SRCS \$(SUBDIR_MITEL_SRCS)"
+    ENABLE_CFLAGS="$ENABLE_CFLAGS \$(SUBDIR_MITEL_CFLAGS)"
+  fi
+fi
+
 # Enable TUI.
 # Check whether --enable-tui was given.
 if test "${enable_tui+set}" = set; then :
Index: gdb/configure.ac
===================================================================
RCS file: /cvs/src/src/gdb/configure.ac,v
retrieving revision 1.181
diff -u -r1.181 configure.ac
--- gdb/configure.ac	2 Jul 2012 20:31:09 -0000	1.181
+++ gdb/configure.ac	12 Jul 2012 10:35:13 -0000
@@ -329,6 +329,25 @@
   fi
 fi
 
+# Enable MI telnet.
+AC_ARG_ENABLE(gdbmitel,
+AS_HELP_STRING([--enable-gdbmitel], [enable remote interface over telnet]),
+  [case $enableval in
+    yes | no)
+      ;;
+    *)
+      AC_MSG_ERROR([bad value $enableval for --enable-gdbmitel]) ;;
+  esac],
+  [enable_gdbmitel=no])
+if test x"$enable_gdbmitel" = xyes; then
+  if test -d $srcdir/mi; then
+    CONFIG_OBS="$CONFIG_OBS \$(SUBDIR_MITEL_OBS)"
+    CONFIG_DEPS="$CONFIG_DEPS \$(SUBDIR_MITEL_DEPS)"
+    CONFIG_SRCS="$CONFIG_SRCS \$(SUBDIR_MITEL_SRCS)"
+    ENABLE_CFLAGS="$ENABLE_CFLAGS \$(SUBDIR_MITEL_CFLAGS)"
+  fi
+fi
+
 # Enable TUI.
 AC_ARG_ENABLE(tui,
 AS_HELP_STRING([--enable-tui], [enable full-screen terminal user interface (TUI)]),
Index: gdb/doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.990
diff -u -r1.990 gdb.texinfo
--- gdb/doc/gdb.texinfo	5 Jul 2012 01:08:24 -0000	1.990
+++ gdb/doc/gdb.texinfo	12 Jul 2012 10:35:16 -0000
@@ -32892,6 +32892,61 @@
 (gdb)
 @end smallexample
 
+@subheading The @code{-start-telnet-service} Command
+@findex -start-telnet-service
+
+@subheading Synopsis
+
+@smallexample
+-start-telnet-service [port]
+@end smallexample
+
+Start a telnet service on the given port. After the service is started, 
+user can connect to the gdb via telnet and execute CLI commands in 
+parallel with existing MI interface. If no @samp{port} argument is given
+then default port 9950 is used. Only one service is allowed at one time.
+So user will have to stop the already running service before starting a
+new one. For telnet service to work, @value{GDBN}
+should be configured with --enable-gdbmitel=yes.   
+
+@subheading @value{GDBN} Command
+
+No equivalent.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-start-telnet-service 8002
+^done
+(gdb)
+@end smallexample
+
+@subheading The @code{-stop-telnet-service} Command
+@findex -stop-telnet-service
+
+@subheading Synopsis
+
+@smallexample
+-stop-telnet-service
+@end smallexample
+
+Stop the telnet service if it is already started. Otherwise this 
+command has no effect.   
+
+@subheading @value{GDBN} Command
+
+No equivalent.
+
+@subheading Example
+
+@smallexample
+(gdb)
+-stop-telnet-service
+^done
+(gdb)
+@end smallexample
+
 @node Annotations
 @chapter @value{GDBN} Annotations
 
Index: gdb/mi/mi-cmds.c
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmds.c,v
retrieving revision 1.60
diff -u -r1.60 mi-cmds.c
--- gdb/mi/mi-cmds.c	24 May 2012 00:33:46 -0000	1.60
+++ gdb/mi/mi-cmds.c	12 Jul 2012 10:35:16 -0000
@@ -137,6 +137,10 @@
   { "var-show-attributes", { NULL, 0 }, mi_cmd_var_show_attributes},
   { "var-show-format", { NULL, 0 }, mi_cmd_var_show_format},
   { "var-update", { NULL, 0 }, mi_cmd_var_update},
+#ifdef ENABLE_GDBMITEL
+  { "start-telnet-service", { NULL, 0 }, mi_cmd_start_telnet_service},
+  { "stop-telnet-service", { NULL, 0 }, mi_cmd_stop_telnet_service},
+#endif
   { NULL, }
 };
 
Index: gdb/mi/mi-cmds.h
===================================================================
RCS file: /cvs/src/src/gdb/mi/mi-cmds.h,v
retrieving revision 1.55
diff -u -r1.55 mi-cmds.h
--- gdb/mi/mi-cmds.h	24 May 2012 00:33:46 -0000	1.55
+++ gdb/mi/mi-cmds.h	12 Jul 2012 10:35:16 -0000
@@ -118,6 +118,10 @@
 extern mi_cmd_argv_ftype mi_cmd_var_update;
 extern mi_cmd_argv_ftype mi_cmd_enable_pretty_printing;
 extern mi_cmd_argv_ftype mi_cmd_var_set_update_range;
+#ifdef ENABLE_GDBMITEL
+extern mi_cmd_argv_ftype mi_cmd_start_telnet_service;
+extern mi_cmd_argv_ftype mi_cmd_stop_telnet_service;
+#endif
 
 /* Description of a single command.  */
 
Index: gdb/mi/mi-telnet.c
===================================================================
RCS file: gdb/mi/mi-telnet.c
diff -N gdb/mi/mi-telnet.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/mi/mi-telnet.c	12 Jul 2012 10:35:16 -0000
@@ -0,0 +1,670 @@
+/* MI telnet support
+
+   Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010,
+   2011, 2012 Free Software Foundation, Inc.
+
+   Contributed by Mentor Graphics Corporation <www.mentor.com>
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* MI telnet support allows remote user to connect to gdb using telnet.
+   GDB should be built with "--enable-gdbmitel=yes" option to enable MI telnet.
+
+   To Start the service use MI command "-start-telnet-service [port]".
+   Default port value is 9950.
+   Service can be stopped by issuing "-stop-telnet-service" command.
+
+   The following options are required for interactive commands
+   and can be turned on directly via telnet on the fly:
+   "set confirm on"
+   "set interactive on"
+*/
+
+#include "defs.h"
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include "top.h"
+#include "mi-cmds.h"
+#include "gdb_string.h"
+#include "event-loop.h"
+#include "interps.h"
+#include "main.h"
+#include "breakpoint.h"
+#include "cli/cli-cmds.h"
+#include "cli/cli-decode.h"
+#include "readline/readline.h"
+#include "readline/history.h"
+
+#define DEFAULT_PORT 9950
+#define MAX_CMD_LENGTH 512
+
+/* Hook to ask remote client for
+   additional 'yes or no' question.  */
+static int telnet_query_hook (const char *msg, va_list argp);
+
+/* Execute telnet command.  */
+static void execute_telnet_command (char* line);
+
+/* This is called when data is available on telnet port.  */
+static void get_input_from_telnet (int err, gdb_client_data client_data);
+
+/* Accept client connection and register it
+   with event_loop to get data from telnet client.  */
+static void telnet_accept_handler(int err, gdb_client_data);
+
+/* Remove the socket descriptor from the event handler and close it.  */
+static void close_socket_desc (int *fd);
+
+/* A utility function to receive data from socket
+   and do error checking.  */
+static int receive (int *fd, void *buf,
+		    size_t n, int flags);
+
+/* A utility function to get a line of input from socket.  */
+static int receive_line (int *fd, char* buf, int buf_size);
+
+/* A utility function to send the output to client.  */
+static void reply_msg (const char *msg);
+
+/* Sends the reply to remote client with extra '\r' character
+   for every '\n' in the msg so that it will show up correctly on
+   telnet console.  */
+static void reply_msg_with_carriage_return (const char *msg);
+
+/* Setup the hooks to do most of the communication work.  */
+static void setup_hooks (int);
+
+/* Socket for accepting telnet connections.  */
+static int telnet_s = -1;
+
+/* Client connection descriptor.  */
+static int client_fd = -1;
+
+/* For output redirecting.  */
+static struct ui_file *str_file = NULL;
+
+/* The Prompt to show on telnet.  */
+static char* mi_prompt = "";
+
+/* Hooks which are called at various points during telnet
+   command processing. */
+
+/* This is called when we are about to process a command.  */
+int (*cmd_start_hook) (int *fd);
+
+/* This is called when we have processed a command.  */
+int (*cmd_end_hook) (int *fd);
+
+/* This is called after connection is complete to setup
+   the mode.  */
+int (*init_mode_hook) (int *fd);
+
+/* This is called when data is avaialble on the socket.   */
+void (*data_available_hook) (int *fd);
+
+/* This is called when we are closeing telnet service.  */
+void (*stop_service_hook) ();
+
+/* This is called when user need to respond to a question.  */
+char (*get_answer_hook) (int *fd);
+
+/* This is called when user needs to provide some input, mostly for
+   getting list of commands.  */
+char* (*get_input_hook) (int *fd, char* prompt);
+
+
+/* Command to start listening for client on specified port.  */
+
+void
+mi_cmd_start_telnet_service (char *command, char **argv, int argc)
+{
+  struct sockaddr_in serv, client;
+  socklen_t len;
+  int port;
+  int val;
+  char* tmp_name;
+
+  if (telnet_s != -1 || client_fd != -1)
+    {
+      error (_("Error: telnet service already started"));
+      return;
+    }
+
+  if (argc != 0 && argc != 1)
+    {
+      error (_("Usage: -start_telnet_service [port]"));
+      return;
+    }
+
+  if (argc == 1)
+    port = atoi (argv[0]);
+  else
+    port = DEFAULT_PORT;
+
+  if (port <= 0)
+    {
+      error (_("Error: wrong port value: %d"), port);
+      return;
+    }
+
+  /* Setup server side of telnet service.  */
+  memset ((char *)&serv, 0, sizeof (serv));
+  serv.sin_family = AF_INET;
+  serv.sin_port = htons (port);
+  serv.sin_addr.s_addr = htonl (INADDR_ANY);
+
+  telnet_s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+  if (telnet_s == -1)
+    {
+      error (_("Error: socket can't be created"));
+      return;
+    }
+
+  if (bind (telnet_s, (const struct sockaddr *)&serv, sizeof (serv)) == -1)
+    {
+      close (telnet_s);
+      telnet_s = -1;
+      error (_("Error: port %d can't be bind"), port);
+      return;
+    }
+
+  /* one client so far allowed */
+  if (listen (telnet_s, 1) == -1)
+    {
+      close (telnet_s);
+      telnet_s = -1;
+      error (_("Error: %s"), safe_strerror (errno));
+      return;
+    }
+
+  /* Allocate file for output.  */
+  if (!str_file)
+    str_file = mem_fileopen ();
+
+  mi_prompt = get_prompt ();
+
+  /* Setup the hooks to handle various situations.  */
+  setup_hooks (0);
+
+  /* Register handler that will accept connections.  */
+  add_file_handler (telnet_s, telnet_accept_handler, 0);
+}
+
+/* Command to stop listening for remote clients.  */
+
+void
+mi_cmd_stop_telnet_service (char *command, char **argv, int argc)
+{
+  close_socket_desc (&client_fd);
+
+  close_socket_desc (&telnet_s);
+
+  if(str_file != NULL)
+    {
+      ui_file_delete (str_file);
+      str_file = NULL;
+    }
+
+  if (stop_service_hook)
+    (*stop_service_hook) ();
+}
+
+/* Hook for query to ask remote client for
+   additional 'yes or no' question.  */
+
+static int
+telnet_query_hook (const char *msg, va_list argp)
+{
+  int retval = 0;
+  char *question = NULL;
+  char cmd;
+
+  gdb_flush (gdb_stdout);
+  question = xstrvprintf (msg, argp);
+
+  reply_msg_with_carriage_return (question);
+  reply_msg ("(y or n) ");
+
+  if(get_answer_hook)
+    {
+      cmd = (*get_answer_hook) (&client_fd);
+
+      /* Check the first letter in the answer.  */
+      switch (cmd)
+	{
+	case 'y':
+	case 'Y':
+	  retval = 1;
+	break;
+
+	case 'n':
+	case 'N':
+	default:
+	  retval = 0;
+	break;
+	}
+    }
+
+  xfree (question);
+  return retval;
+}
+
+/* This function is called when GDB needs to get the list of
+   commands to run on breakpoints.  */
+
+static char *
+telnet_readline_hook (char *prompt)
+{
+  if (get_input_hook)
+    return (*get_input_hook) (&client_fd, prompt);
+  else
+    return "";
+};
+
+/* Execute telnet command.  */
+
+static void
+execute_telnet_command (char* line)
+{
+  struct gdb_exception e;
+  char *result = NULL;
+  struct cleanup *cleanup;
+  struct interp *old_interp = NULL;
+  struct interp *interp_to_use = NULL;
+  HIST_ENTRY *hist = NULL;
+  long len = 0;
+  void* old_query_hook;
+  void* old_readline_hook;
+
+  if (line == NULL)
+    return;
+
+  /* If this is a valid command then add it to history.  */
+  if (*line != '\0' )
+    add_history (line);
+  else
+    {
+      /* This is an empty command. Look in the history. If nothing is
+	 available in history then function will return.  */
+      hist = previous_history ();
+      if ( (hist != NULL) && (hist->line != NULL) && (*hist->line != '\0') )
+	line = hist->line;
+      else
+	return;
+    }
+
+  if (cmd_start_hook)
+    (*cmd_start_hook) (&client_fd);
+
+  /* setup cleanups for input/output.  */
+  cleanup = make_cleanup (null_cleanup, NULL);
+  make_cleanup_restore_ui_file (&gdb_stdin);
+  make_cleanup_restore_ui_file (&gdb_stdout);
+  make_cleanup_restore_ui_file (&gdb_stderr);
+  make_cleanup_restore_ui_file (&gdb_stdlog);
+  make_cleanup_restore_ui_file (&gdb_stdtarg);
+  make_cleanup_restore_ui_file (&gdb_stdtargerr);
+
+  /* execute command in sync, set batch mode to off */
+  make_cleanup_restore_integer (&batch_flag);
+  batch_flag = 0;
+
+  /* figure out current interpreter */
+  if (current_interp_named_p (INTERP_MI))
+    {
+      old_interp = interp_lookup (INTERP_MI);
+    }
+  else if (current_interp_named_p (INTERP_MI1))
+    {
+      old_interp = interp_lookup (INTERP_MI1);
+    }
+  else if (current_interp_named_p (INTERP_MI2))
+    {
+      old_interp = interp_lookup (INTERP_MI2);
+    }
+  else if (current_interp_named_p (INTERP_MI3))
+    {
+      old_interp = interp_lookup (INTERP_MI3);
+    }
+
+  /* switch to console interp */
+  interp_to_use = interp_lookup (INTERP_CONSOLE);
+  if (!interp_set (interp_to_use, 0))
+    {
+      reply_msg ("Error: unexpectedly failed to use CLI the interpreter\r\n");
+      do_cleanups (cleanup);
+      return;
+    }
+
+  /* redirect and catch all input/output into string */
+  if (ui_out_redirect (current_uiout, str_file) < 0)
+    reply_msg ("Error: unexpectedly failed to redirect user interface. "
+	       "No command results will be print\r\n");
+  else
+    make_cleanup_ui_out_redirect_pop (current_uiout);
+
+  gdb_stdout = str_file;
+  gdb_stderr = str_file;
+  gdb_stdlog = str_file;
+  gdb_stdtarg = str_file;
+  gdb_stdtargerr = str_file;
+
+  /* Hook for command that may ask user for questions.  */
+  old_query_hook = deprecated_query_hook;
+  old_readline_hook = deprecated_readline_hook;
+  deprecated_query_hook = telnet_query_hook;
+  deprecated_readline_hook = telnet_readline_hook;
+
+  /* Console interp is properly set up, execute the command.  */
+  TRY_CATCH (e, RETURN_MASK_ALL)
+    {
+      execute_command (line, 1);
+    }
+
+  /* Do any breakpoint-related stuff.  */
+  bpstat_do_actions ();
+
+  /* Restore the hooks.  */
+  deprecated_query_hook = old_query_hook;
+  deprecated_readline_hook = old_readline_hook;
+
+  gdb_flush (str_file);
+
+  if (e.reason < 0)
+    {
+      reply_msg ("Error: ");
+      reply_msg (e.message);
+      reply_msg ("\r\n");
+    }
+
+  /* Send the reply to the client.  */
+  result = ui_file_xstrdup (str_file, &len);
+
+  if (len > 0)
+    {
+      reply_msg_with_carriage_return (result);
+    }
+
+  xfree (result);
+
+  /* Clear output buffer and restore GDB settings.  */
+  ui_file_rewind (str_file);
+  do_cleanups (cleanup);
+
+  /* Get back to MI interp.  */
+  interp_set (old_interp, 0);
+
+  if (cmd_end_hook)
+    (*cmd_end_hook) (&client_fd);
+}
+
+/* This function is called when data is ready on teh socket and calls
+   the corresponding hook.  */
+static void
+get_input_from_telnet (int err, gdb_client_data client_data)
+{
+  if (data_available_hook)
+    (*data_available_hook) (&client_fd);
+}
+
+/* Handler for the listening socket.
+   Accepts client connection and registers it with event_loop.  */
+
+static void
+telnet_accept_handler(int err, gdb_client_data client_data)
+{
+  struct sockaddr_in client;
+  socklen_t len;
+  int s = -1;
+
+  if (client_fd != -1)
+    return;      /* Another client is already connected.  */
+
+  s = accept (telnet_s, (struct sockaddr *)&client, &len);
+  if (s != -1)
+    {
+      client_fd = s;
+
+      if (init_mode_hook)
+	{
+	  if ((*init_mode_hook) (&client_fd) == 0)
+	    {
+	      close_socket_desc (&telnet_s);
+	      return;
+	    }
+	}
+
+      /* Initialize the history library so that we can use the
+         previous command if user just press return.  */
+      using_history ();
+
+      /* Register the socket with event handler.  */
+      add_file_handler (client_fd, get_input_from_telnet, 0);
+
+      /* Remote connection is set up, show prompt.  */
+      send (client_fd, mi_prompt, strlen (mi_prompt), 0);
+    }
+
+  /* In any case, close the listening socket as we only
+     allow one connection.  */
+  close_socket_desc (&telnet_s);
+}
+
+static void
+close_socket_desc (int *fd)
+{
+  if((fd != NULL) && (*fd != -1) )
+    {
+      delete_file_handler (*fd);
+      close (*fd);
+      *fd = -1;
+    }
+}
+
+/* This is wrapper over recv. If recv returns some error then it closes
+   the socket.  */
+
+static int
+receive (int *fd, void *buf, size_t n, int flags)
+{
+  int ret;
+
+  if (fd == NULL)
+    return -1;
+
+  ret = recv (*fd, buf, n, flags);
+  if (ret < 1)
+    {
+      close_socket_desc (fd);
+    }
+  return ret;
+}
+
+/* A utility function to send the output to client.  */
+
+static void
+reply_msg (const char *msg)
+{
+  char *result = NULL;
+  long len;
+
+  if (client_fd != -1 && msg != NULL)
+    {
+      /* flush additional output if any */
+      if (str_file)
+	{
+	  gdb_flush (str_file);
+	  result = ui_file_xstrdup (str_file, &len);
+
+	  send (client_fd, result, len, 0);
+
+	  xfree (result);
+	  ui_file_rewind (str_file);
+	}
+      send (client_fd, msg, strlen (msg), 0);
+    }
+}
+
+/* Sends the reply to remote client with extra '\r' character
+   for every '\n' in the msg so that it will show up correctly on
+   telnet console.  */
+static void
+reply_msg_with_carriage_return (const char *msg)
+{
+  int len;
+  char data;
+  int i =0;
+
+  if (client_fd != -1 && msg != NULL)
+    {
+      len = strlen (msg);
+
+      for(i=0; i < len; i++)
+	{
+	  send (client_fd, &msg[i], 1, 0);
+
+	  if(msg[i] == '\n')
+	    {
+	      data = '\r';
+	      send (client_fd, &data, 1, 0);
+	    }
+	}
+    }
+}
+
+/* Get a line from the client and put the terminating NULL
+   at correct place.  */
+
+static int
+receive_line (int *fd, char* buf, int buf_size)
+{
+  int size;
+  int empty_string = 1;
+  int i;
+
+  /* Read a line from the socket.  */
+  size = receive (fd, buf, (buf_size - 1), 0);
+
+  if (size <= 0)
+    return size;
+
+  /* Put a string terminating NULL character after the first character
+     that is not \n or \r.  */
+  for (i = (size - 1); i >=0; i--)
+    {
+      if ( (buf[i] != '\n') && (buf[i] != '\r') )
+	{
+	  buf[i + 1] = '\0';
+	  empty_string = 0;
+	  break;
+	}
+    }
+
+  /* The client did not send anything except \n and \r, so just send an
+     empty string to execute_telnet_command.  */
+  if (empty_string == 1)
+    buf[0] = '\0';
+
+  return size;
+
+}
+
+/* This function is called when we need to take a yes or no answer
+   from the user.  */
+
+static char
+get_answer_hook_line (int *fd)
+{
+  int size;
+  char cmd[MAX_CMD_LENGTH];
+
+  size = receive (fd, &cmd, MAX_CMD_LENGTH, 0);
+
+  if (size <= 0)
+    {
+      return 0; /* If error return 0 */
+    }
+  return cmd[0];
+}
+
+/* This function is called when GDB needs to get the list of
+   commands to run on breakpoints. See 'commands'.  */
+
+static char*
+get_input_hook_line (int* fd, char* prompt)
+{
+  long len;
+  char buf[MAX_CMD_LENGTH + 1];
+
+  reply_msg (prompt);
+
+  len = receive_line (&client_fd, buf, MAX_CMD_LENGTH + 1);
+
+  if (len <= 0)
+    return NULL;
+
+  return xstrdup (buf);
+}
+
+/* This function is called when data is available on the socket to read. */
+
+static void
+data_available_hook_line (int *fd)
+{
+  int size;
+  unsigned char buf[MAX_CMD_LENGTH+1];
+
+  size = receive_line (&client_fd, buf, MAX_CMD_LENGTH + 1);
+
+  if (size <= 0)
+    return;
+
+  execute_telnet_command (buf);
+
+  /* Print the prompt.  */
+  send (*fd, mi_prompt, strlen (mi_prompt), 0);
+}
+
+/* This function setup the hooks that are called at various points.
+   The mode parameter gives us flexibility to support other modes in
+   future. */
+
+static void
+setup_hooks (int mode)
+{
+  /* Currently, we are supporting only one mode where we get the
+     whole line from the client. So the _line in the end. We can
+     , in future, support getting input character by character. The
+     hook mechanism provides us the flexibility.  */
+  if (mode == 0)
+    {
+      cmd_start_hook = NULL;
+
+      cmd_end_hook = NULL;
+
+      init_mode_hook = NULL;
+
+      data_available_hook = data_available_hook_line;
+
+      stop_service_hook = NULL;
+
+      get_answer_hook = get_answer_hook_line;
+
+      get_input_hook = get_input_hook_line;
+    }
+}
+
Index: gdb/testsuite/gdb.mi/mi-telnet.c
===================================================================
RCS file: gdb/testsuite/gdb.mi/mi-telnet.c
diff -N gdb/testsuite/gdb.mi/mi-telnet.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.mi/mi-telnet.c	12 Jul 2012 10:35:17 -0000
@@ -0,0 +1,73 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2012 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <string.h>
+
+int test_connect(int port)
+{
+	struct sockaddr_in client;
+	struct hostent *hp;
+	int telnet_s;
+	int result = 0;
+	int err;
+
+	if ((hp = gethostbyname("localhost")) != 0)
+	{
+		memset ((char *)&client, 0, sizeof (client));
+		client.sin_family = AF_INET;
+		client.sin_port = htons (port);
+		client.sin_addr.s_addr = ((struct in_addr *)(hp->h_addr))->s_addr;
+
+		telnet_s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP);
+		if (telnet_s != -1)
+		{
+			/* connect to PORT on HOST */
+			err = connect(telnet_s, (struct sockaddr *)  &client, sizeof(client));
+			if (err == -1)
+			{
+				result = 0;  /* Connect-fail-breakpoint */
+			}
+			else
+			{
+				result = 1; /* Connect-succeed-breakpoint */
+			}
+			close(telnet_s);
+		}
+	}
+	return result;
+}
+
+
+int main(int argc, char* argv[])
+{
+	int port;
+	int result = 1;
+
+	if (argc == 2)
+	{
+		port = atoi (argv[1]);
+
+		if (port > 0)
+		{
+			result = test_connect (port);
+		}
+	}
+	return result; /* program-end-breakpoint */
+}
Index: gdb/testsuite/gdb.mi/mi-telnet.exp
===================================================================
RCS file: gdb/testsuite/gdb.mi/mi-telnet.exp
diff -N gdb/testsuite/gdb.mi/mi-telnet.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gdb/testsuite/gdb.mi/mi-telnet.exp	12 Jul 2012 10:35:17 -0000
@@ -0,0 +1,109 @@
+# Copyright 1999-2002, 2004-2005, 2007-2012 Free Software Foundation,
+# Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Test -start-telnet-service and -stop-telnet-service comands.
+#
+
+load_lib mi-support.exp
+set MIFLAGS "-i=mi2"
+set PORT1 8005
+set PORT2 8006
+
+# Executes the test for telnet service. 
+# port is the port on which telnet service will listen.
+# bp_line is the line in test C file where we want to hit the
+# breakpoint.
+# message is the message to print for this test.
+proc connect_test {port bp_line message} {
+    global srcfile
+    global connect_succeed_break
+    global connect_fail_break
+    global program_end_breakpoint
+    
+    # set the argument of the test program
+    mi_gdb_test "-interpreter-exec console \"set args $port\"" \
+      {\^done} \
+      "-interpreter-exec console \"set args $port\""
+
+    mi_create_breakpoint "${srcfile}:${connect_succeed_break}" \
+    2 .* test_connect ".*${srcfile}" ${connect_succeed_break} .* "Connection Succeed breakpoint."
+    
+    mi_create_breakpoint "${srcfile}:${connect_fail_break}" \
+    3 .* test_connect ".*${srcfile}" ${connect_fail_break} .* "Connection fail breakpoint."
+    
+    mi_create_breakpoint "${srcfile}:${program_end_breakpoint}" \
+    4 .* main ".*${srcfile}" ${program_end_breakpoint} .* "Program exit."
+    
+    mi_run_cmd    
+    
+    mi_expect_stop "breakpoint-hit" "test_connect" ".*" ".*mi-telnet.c" "$bp_line" \
+      {"" "disp=\"keep\"" } $message    
+}
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+set testfile "mi-telnet"
+set srcfile ${testfile}.c
+set binfile ${objdir}/${subdir}/mi-telnet
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug}] != "" } {
+     untested "could not compile test program"
+     return -1
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+mi_run_to_main
+
+set connect_succeed_break     [gdb_get_line_number "Connect-succeed-breakpoint"]
+set connect_fail_break        [gdb_get_line_number "Connect-fail-breakpoint"]
+set program_end_breakpoint    [gdb_get_line_number "program-end-breakpoint"]
+
+# Send the command to start the telnet service
+mi_gdb_test "-start-telnet-service $PORT1" "\\\^done" "Start Telnet Service"
+
+# Check if test program can connect to the port.
+connect_test $PORT1 $connect_succeed_break "Client can connect when port is open."
+
+# Re-run the same test but after closing the telnet service. Test if client
+# can connect.
+mi_gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+mi_run_to_main
+
+# Open the telnet service and then close it.
+mi_gdb_test "-start-telnet-service $PORT2" "\\\^done" "Start Telnet Service"
+
+mi_gdb_test "-stop-telnet-service" "\\\^done" "Stop Telnet Service"
+
+# Client program should not be able to connect now.
+connect_test $PORT2 $connect_fail_break "Client cannot connect when port is closed."
+
+mi_gdb_exit
+
+return 0
+
