/* A client to make GDB return to command level in Mach 3.
   Copyright (C) 1992, 1993 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 (argc, argv)
     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);
}
