/* A client to make GDB return to command level in Mach 3.
   Copyright 1992, 1993, 1994, 2000 Free Software Foundation, Inc.

   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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

/* Authors: Jukka Virtanen <jtv@hut.fi> and Peter Stout <pds@cs.cmu.edu>.

   A simple client to make GDB (versions 4.4 and later) on Mach 3 return
   to the command level when it is waiting for the inferior to stop.

   Actions: Lookup the send right to the GDB message port from the
   NetMsgServer.

   Send an asynchronous message with msgh_id
   GDB_MESSAGE_ID_STOP to that port.
 */

#include <stdio.h>

#include "defs.h"

#include <mach.h>
#include <mach/message.h>
#include <mach_error.h>
#include <servers/netname.h>
#include <servers/netname_defs.h>

void
main (int argc, char **argv)
{
  kern_return_t kr;
  mach_msg_header_t msg;
  mach_port_t gdb_port;
  char *host;
  char *name;

  if (argc == 1)
    argv[argc++] = GDB_DEF_NAME;

  if (argc != 2)
    {
      fprintf (stderr, "Usage : %s <GDB name>\n", argv[0]);
      exit (1);
    }

  /* Allow the user to specify a remote host.  */
  host = strchr (argv[1], '@');
  if (host)
    *(host++) = '\0';
  else
    host = (char *) "";

  name = malloc (strlen (argv[1]) + sizeof (GDB_NAME_PREFIX));
  if (name == NULL)
    {
      fprintf (stderr, "Unable to allocate memory for name.");
      exit (1);
    }

  strcpy (name, GDB_NAME_PREFIX);
  strcat (name, argv[1]);

  /* Look up the GDB service port.  For convenience, add the
     GDB_NAME_PREFIX the argument before looking up the name.
     For backwards compatibility, do it without.  */

  kr = netname_look_up (name_server_port, host, name, &gdb_port);
  if (kr == NETNAME_NOT_CHECKED_IN)
    kr = netname_look_up (name_server_port, host, argv[1], &gdb_port);
  if (kr != KERN_SUCCESS)
    {
      fprintf (stderr, "Unable to lookup the GDB service port: %s.\n",
	       mach_error_string (kr));
      exit (1);
    }

  /* Code generated by mig stub generator, with minor cleanups :-)

     simpleroutine stop_inferior(gdb_port : mach_port_t);  */

  msg.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0);
  msg.msgh_remote_port = gdb_port;
  msg.msgh_local_port = MACH_PORT_NULL;
  msg.msgh_size = sizeof (msg);
  msg.msgh_seqno = 0;
  msg.msgh_id = GDB_MESSAGE_ID_STOP;

  kr = mach_msg_send (&msg);
  if (kr != KERN_SUCCESS)
    fprintf (stderr, "Message not sent, return code %d : %s\n", kr,
	     mach_error_string (kr));

  exit (kr != KERN_SUCCESS);
}
