/* Remote File-I/O communications

   Copyright (C) 2003-2016 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 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/>.  */

/* See the GDB User Guide for details of the GDB remote protocol.  */

#include "defs.h"
#include "gdbcmd.h"
#include "remote.h"
#include "gdb_wait.h"
#include <sys/stat.h>
#include "remote-fileio.h"
#include "event-loop.h"
#include "target.h"
#include "filenames.h"
#include "filestuff.h"

#include <fcntl.h>
#include "gdb_sys_time.h"
#ifdef __CYGWIN__
#include <sys/cygwin.h>		/* For cygwin_conv_path.  */
#endif
#include <signal.h>

static struct {
  int *fd_map;
  int fd_map_size;
} remote_fio_data;

#define FIO_FD_INVALID		-1
#define FIO_FD_CONSOLE_IN	-2
#define FIO_FD_CONSOLE_OUT	-3

static int remote_fio_system_call_allowed = 0;

static int
remote_fileio_init_fd_map (void)
{
  int i;

  if (!remote_fio_data.fd_map)
    {
      remote_fio_data.fd_map = XNEWVEC (int, 10);
      remote_fio_data.fd_map_size = 10;
      remote_fio_data.fd_map[0] = FIO_FD_CONSOLE_IN;
      remote_fio_data.fd_map[1] = FIO_FD_CONSOLE_OUT;
      remote_fio_data.fd_map[2] = FIO_FD_CONSOLE_OUT;
      for (i = 3; i < 10; ++i)
        remote_fio_data.fd_map[i] = FIO_FD_INVALID;
    }
  return 3;
}

static int
remote_fileio_resize_fd_map (void)
{
  int i = remote_fio_data.fd_map_size;

  if (!remote_fio_data.fd_map)
    return remote_fileio_init_fd_map ();
  remote_fio_data.fd_map_size += 10;
  remote_fio_data.fd_map =
    (int *) xrealloc (remote_fio_data.fd_map,
		      remote_fio_data.fd_map_size * sizeof (int));
  for (; i < remote_fio_data.fd_map_size; i++)
    remote_fio_data.fd_map[i] = FIO_FD_INVALID;
  return remote_fio_data.fd_map_size - 10;
}

static int
remote_fileio_next_free_fd (void)
{
  int i;

  for (i = 0; i < remote_fio_data.fd_map_size; ++i)
    if (remote_fio_data.fd_map[i] == FIO_FD_INVALID)
      return i;
  return remote_fileio_resize_fd_map ();
}

static int
remote_fileio_fd_to_targetfd (int fd)
{
  int target_fd = remote_fileio_next_free_fd ();

  remote_fio_data.fd_map[target_fd] = fd;
  return target_fd;
}

static int
remote_fileio_map_fd (int target_fd)
{
  remote_fileio_init_fd_map ();
  if (target_fd < 0 || target_fd >= remote_fio_data.fd_map_size)
    return FIO_FD_INVALID;
  return remote_fio_data.fd_map[target_fd];
}

static void
remote_fileio_close_target_fd (int target_fd)
{
  remote_fileio_init_fd_map ();
  if (target_fd >= 0 && target_fd < remote_fio_data.fd_map_size)
    remote_fio_data.fd_map[target_fd] = FIO_FD_INVALID;
}

static int
remote_fileio_oflags_to_host (long flags)
{
  int hflags = 0;

  if (flags & FILEIO_O_CREAT)
    hflags |= O_CREAT;
  if (flags & FILEIO_O_EXCL)
    hflags |= O_EXCL;
  if (flags & FILEIO_O_TRUNC)
    hflags |= O_TRUNC;
  if (flags & FILEIO_O_APPEND)
    hflags |= O_APPEND;
  if (flags & FILEIO_O_RDONLY)
    hflags |= O_RDONLY;
  if (flags & FILEIO_O_WRONLY)
    hflags |= O_WRONLY;
  if (flags & FILEIO_O_RDWR)
    hflags |= O_RDWR;
/* On systems supporting binary and text mode, always open files in
   binary mode.  */
#ifdef O_BINARY
  hflags |= O_BINARY;
#endif
  return hflags;
}

static mode_t
remote_fileio_mode_to_host (long mode, int open_call)
{
  mode_t hmode = 0;

  if (!open_call)
    {
      if (mode & FILEIO_S_IFREG)
	hmode |= S_IFREG;
      if (mode & FILEIO_S_IFDIR)
	hmode |= S_IFDIR;
      if (mode & FILEIO_S_IFCHR)
	hmode |= S_IFCHR;
    }
  if (mode & FILEIO_S_IRUSR)
    hmode |= S_IRUSR;
  if (mode & FILEIO_S_IWUSR)
    hmode |= S_IWUSR;
  if (mode & FILEIO_S_IXUSR)
    hmode |= S_IXUSR;
#ifdef S_IRGRP
  if (mode & FILEIO_S_IRGRP)
    hmode |= S_IRGRP;
#endif
#ifdef S_IWGRP
  if (mode & FILEIO_S_IWGRP)
    hmode |= S_IWGRP;
#endif
#ifdef S_IXGRP
  if (mode & FILEIO_S_IXGRP)
    hmode |= S_IXGRP;
#endif
  if (mode & FILEIO_S_IROTH)
    hmode |= S_IROTH;
#ifdef S_IWOTH
  if (mode & FILEIO_S_IWOTH)
    hmode |= S_IWOTH;
#endif
#ifdef S_IXOTH
  if (mode & FILEIO_S_IXOTH)
    hmode |= S_IXOTH;
#endif
  return hmode;
}

static int
remote_fileio_seek_flag_to_host (long num, int *flag)
{
  if (!flag)
    return 0;
  switch (num)
    {
      case FILEIO_SEEK_SET:
        *flag = SEEK_SET;
	break;
      case FILEIO_SEEK_CUR:
        *flag =  SEEK_CUR;
	break;
      case FILEIO_SEEK_END:
        *flag =  SEEK_END;
	break;
      default:
        return -1;
    }
  return 0;
}

static int
remote_fileio_extract_long (char **buf, LONGEST *retlong)
{
  char *c;
  int sign = 1;

  if (!buf || !*buf || !**buf || !retlong)
    return -1;
  c = strchr (*buf, ',');
  if (c)
    *c++ = '\0';
  else
    c = strchr (*buf, '\0');
  while (strchr ("+-", **buf))
    {
      if (**buf == '-')
	sign = -sign;
      ++*buf;
    }
  for (*retlong = 0; **buf; ++*buf)
    {
      *retlong <<= 4;
      if (**buf >= '0' && **buf <= '9')
        *retlong += **buf - '0';
      else if (**buf >= 'a' && **buf <= 'f')
        *retlong += **buf - 'a' + 10;
      else if (**buf >= 'A' && **buf <= 'F')
        *retlong += **buf - 'A' + 10;
      else
        return -1;
    }
  *retlong *= sign;
  *buf = c;
  return 0;
}

static int
remote_fileio_extract_int (char **buf, long *retint)
{
  int ret;
  LONGEST retlong;

  if (!retint)
    return -1;
  ret = remote_fileio_extract_long (buf, &retlong);
  if (!ret)
    *retint = (long) retlong;
  return ret;
}

static int
remote_fileio_extract_ptr_w_len (char **buf, CORE_ADDR *ptrval, int *length)
{
  char *c;
  LONGEST retlong;

  if (!buf || !*buf || !**buf || !ptrval || !length)
    return -1;
  c = strchr (*buf, '/');
  if (!c)
    return -1;
  *c++ = '\0';
  if (remote_fileio_extract_long (buf, &retlong))
    return -1;
  *ptrval = (CORE_ADDR) retlong;
  *buf = c;
  if (remote_fileio_extract_long (buf, &retlong))
    return -1;
  *length = (int) retlong;
  return 0;
}

static void
remote_fileio_to_fio_long (LONGEST num, fio_long_t fnum)
{
  host_to_bigendian (num, (char *) fnum, 8);
}

static void
remote_fileio_to_fio_timeval (struct timeval *tv, struct fio_timeval *ftv)
{
  host_to_fileio_time (tv->tv_sec, ftv->ftv_sec);
  remote_fileio_to_fio_long (tv->tv_usec, ftv->ftv_usec);
}

/* The quit handler originally installed.  */
static quit_handler_ftype *remote_fileio_o_quit_handler;

/* What to do on a QUIT call while handling a file I/O request.  We
   throw a quit exception, which is caught by remote_fileio_request
   and translated to an EINTR reply back to the target.  */

static void
remote_fileio_quit_handler (void)
{
  if (check_quit_flag ())
    quit ();
}

static void
remote_fileio_reply (int retcode, int error)
{
  char buf[32];
  int ctrl_c = check_quit_flag ();

  strcpy (buf, "F");
  if (retcode < 0)
    {
      strcat (buf, "-");
      retcode = -retcode;
    }
  sprintf (buf + strlen (buf), "%x", retcode);
  if (error || ctrl_c)
    {
      if (error && ctrl_c)
        error = FILEIO_EINTR;
      if (error < 0)
        {
	  strcat (buf, "-");
	  error = -error;
	}
      sprintf (buf + strlen (buf), ",%x", error);
      if (ctrl_c)
        strcat (buf, ",C");
    }
  quit_handler = remote_fileio_o_quit_handler;
  putpkt (buf);
}

static void
remote_fileio_ioerror (void)
{
  remote_fileio_reply (-1, FILEIO_EIO);
}

static void
remote_fileio_badfd (void)
{
  remote_fileio_reply (-1, FILEIO_EBADF);
}

static void
remote_fileio_return_errno (int retcode)
{
  remote_fileio_reply (retcode, retcode < 0
		       ? host_to_fileio_error (errno) : 0);
}

static void
remote_fileio_return_success (int retcode)
{
  remote_fileio_reply (retcode, 0);
}

static void
remote_fileio_func_open (char *buf)
{
  CORE_ADDR ptrval;
  int length;
  long num;
  int flags, fd;
  mode_t mode;
  char *pathname;
  struct stat st;

  /* 1. Parameter: Ptr to pathname / length incl. trailing zero.  */
  if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
    {
      remote_fileio_ioerror ();
      return;
    }
  /* 2. Parameter: open flags */
  if (remote_fileio_extract_int (&buf, &num))
    {
      remote_fileio_ioerror ();
      return;
    }
  flags = remote_fileio_oflags_to_host (num);
  /* 3. Parameter: open mode */
  if (remote_fileio_extract_int (&buf, &num))
    {
      remote_fileio_ioerror ();
      return;
    }
  mode = remote_fileio_mode_to_host (num, 1);

  /* Request pathname.  */
  pathname = (char *) alloca (length);
  if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
    {
      remote_fileio_ioerror ();
      return;
    }

  /* Check if pathname exists and is not a regular file or directory.  If so,
     return an appropriate error code.  Same for trying to open directories
     for writing.  */
  if (!stat (pathname, &st))
    {
      if (!S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
	{
	  remote_fileio_reply (-1, FILEIO_ENODEV);
	  return;
	}
      if (S_ISDIR (st.st_mode)
	  && ((flags & O_WRONLY) == O_WRONLY || (flags & O_RDWR) == O_RDWR))
	{
	  remote_fileio_reply (-1, FILEIO_EISDIR);
	  return;
	}
    }

  fd = gdb_open_cloexec (pathname, flags, mode);
  if (fd < 0)
    {
      remote_fileio_return_errno (-1);
      return;
    }

  fd = remote_fileio_fd_to_targetfd (fd);
  remote_fileio_return_success (fd);
}

static void
remote_fileio_func_close (char *buf)
{
  long num;
  int fd;

  /* Parameter: file descriptor */
  if (remote_fileio_extract_int (&buf, &num))
    {
      remote_fileio_ioerror ();
      return;
    }
  fd = remote_fileio_map_fd ((int) num);
  if (fd == FIO_FD_INVALID)
    {
      remote_fileio_badfd ();
      return;
    }

  if (fd != FIO_FD_CONSOLE_IN && fd != FIO_FD_CONSOLE_OUT && close (fd))
    remote_fileio_return_errno (-1);
  remote_fileio_close_target_fd ((int) num);
  remote_fileio_return_success (0);
}

static void
remote_fileio_func_read (char *buf)
{
  long target_fd, num;
  LONGEST lnum;
  CORE_ADDR ptrval;
  int fd, ret;
  gdb_byte *buffer;
  size_t length;
  off_t old_offset, new_offset;

  /* 1. Parameter: file descriptor */
  if (remote_fileio_extract_int (&buf, &target_fd))
    {
      remote_fileio_ioerror ();
      return;
    }
  fd = remote_fileio_map_fd ((int) target_fd);
  if (fd == FIO_FD_INVALID)
    {
      remote_fileio_badfd ();
      return;
    }
  /* 2. Parameter: buffer pointer */
  if (remote_fileio_extract_long (&buf, &lnum))
    {
      remote_fileio_ioerror ();
      return;
    }
  ptrval = (CORE_ADDR) lnum;
  /* 3. Parameter: buffer length */
  if (remote_fileio_extract_int (&buf, &num))
    {
      remote_fileio_ioerror ();
      return;
    }
  length = (size_t) num;

  switch (fd)
    {
      case FIO_FD_CONSOLE_OUT:
	remote_fileio_badfd ();
	return;
      case FIO_FD_CONSOLE_IN:
	{
	  static char *remaining_buf = NULL;
	  static int remaining_length = 0;

	  buffer = (gdb_byte *) xmalloc (16384);
	  if (remaining_buf)
	    {
	      if (remaining_length > length)
		{
		  memcpy (buffer, remaining_buf, length);
		  memmove (remaining_buf, remaining_buf + length,
			   remaining_length - length);
		  remaining_length -= length;
		  ret = length;
		}
	      else
		{
		  memcpy (buffer, remaining_buf, remaining_length);
		  xfree (remaining_buf);
		  remaining_buf = NULL;
		  ret = remaining_length;
		}
	    }
	  else
	    {
	      /* Windows (at least XP and Server 2003) has difficulty
		 with large reads from consoles.  If a handle is
		 backed by a real console device, overly large reads
		 from the handle will fail and set errno == ENOMEM.
		 On a Windows Server 2003 system where I tested,
		 reading 26608 bytes from the console was OK, but
		 anything above 26609 bytes would fail.  The limit has
		 been observed to vary on different systems.  So, we
		 limit this read to something smaller than that - by a
		 safe margin, in case the limit depends on system
		 resources or version.  */
	      ret = ui_file_read (gdb_stdtargin, (char *) buffer, 16383);
	      if (ret > 0 && (size_t)ret > length)
		{
		  remaining_buf = (char *) xmalloc (ret - length);
		  remaining_length = ret - length;
		  memcpy (remaining_buf, buffer + length, remaining_length);
		  ret = length;
		}
	    }
	}
	break;
      default:
	buffer = (gdb_byte *) xmalloc (length);
	/* POSIX defines EINTR behaviour of read in a weird way.  It's allowed
	   for read() to return -1 even if "some" bytes have been read.  It
	   has been corrected in SUSv2 but that doesn't help us much...
	   Therefore a complete solution must check how many bytes have been
	   read on EINTR to return a more reliable value to the target */
	old_offset = lseek (fd, 0, SEEK_CUR);
	ret = read (fd, buffer, length);
	if (ret < 0 && errno == EINTR)
	  {
	    new_offset = lseek (fd, 0, SEEK_CUR);
	    /* If some data has been read, return the number of bytes read.
	       The Ctrl-C flag is set in remote_fileio_reply() anyway.  */
	    if (old_offset != new_offset)
	      ret = new_offset - old_offset;
	  }
	break;
    }

  if (ret > 0)
    {
      errno = target_write_memory (ptrval, buffer, ret);
      if (errno != 0)
	ret = -1;
    }

  if (ret < 0)
    remote_fileio_return_errno (-1);
  else
    remote_fileio_return_success (ret);

  xfree (buffer);
}

static void
remote_fileio_func_write (char *buf)
{
  long target_fd, num;
  LONGEST lnum;
  CORE_ADDR ptrval;
  int fd, ret;
  gdb_byte *buffer;
  size_t length;

  /* 1. Parameter: file descriptor */
  if (remote_fileio_extract_int (&buf, &target_fd))
    {
      remote_fileio_ioerror ();
      return;
    }
  fd = remote_fileio_map_fd ((int) target_fd);
  if (fd == FIO_FD_INVALID)
    {
      remote_fileio_badfd ();
      return;
    }
  /* 2. Parameter: buffer pointer */
  if (remote_fileio_extract_long (&buf, &lnum))
    {
      remote_fileio_ioerror ();
      return;
    }
  ptrval = (CORE_ADDR) lnum;
  /* 3. Parameter: buffer length */
  if (remote_fileio_extract_int (&buf, &num))
    {
      remote_fileio_ioerror ();
      return;
    }
  length = (size_t) num;
    
  buffer = (gdb_byte *) xmalloc (length);
  if (target_read_memory (ptrval, buffer, length) != 0)
    {
      xfree (buffer);
      remote_fileio_ioerror ();
      return;
    }

  switch (fd)
    {
      case FIO_FD_CONSOLE_IN:
	remote_fileio_badfd ();
	xfree (buffer);
	return;
      case FIO_FD_CONSOLE_OUT:
	ui_file_write (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr,
		       (char *) buffer, length);
	gdb_flush (target_fd == 1 ? gdb_stdtarg : gdb_stdtargerr);
	ret = length;
	break;
      default:
	ret = write (fd, buffer, length);
	if (ret < 0 && errno == EACCES)
	  errno = EBADF; /* Cygwin returns EACCESS when writing to a
			    R/O file.  */
	break;
    }

  if (ret < 0)
    remote_fileio_return_errno (-1);
  else
    remote_fileio_return_success (ret);

  xfree (buffer);
}

static void
remote_fileio_func_lseek (char *buf)
{
  long num;
  LONGEST lnum;
  int fd, flag;
  off_t offset, ret;

  /* 1. Parameter: file descriptor */
  if (remote_fileio_extract_int (&buf, &num))
    {
      remote_fileio_ioerror ();
      return;
    }
  fd = remote_fileio_map_fd ((int) num);
  if (fd == FIO_FD_INVALID)
    {
      remote_fileio_badfd ();
      return;
    }
  else if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
    {
      remote_fileio_reply (-1, FILEIO_ESPIPE);
      return;
    }

  /* 2. Parameter: offset */
  if (remote_fileio_extract_long (&buf, &lnum))
    {
      remote_fileio_ioerror ();
      return;
    }
  offset = (off_t) lnum;
  /* 3. Parameter: flag */
  if (remote_fileio_extract_int (&buf, &num))
    {
      remote_fileio_ioerror ();
      return;
    }
  if (remote_fileio_seek_flag_to_host (num, &flag))
    {
      remote_fileio_reply (-1, FILEIO_EINVAL);
      return;
    }
  
  ret = lseek (fd, offset, flag);

  if (ret == (off_t) -1)
    remote_fileio_return_errno (-1);
  else
    remote_fileio_return_success (ret);
}

static void
remote_fileio_func_rename (char *buf)
{
  CORE_ADDR old_ptr, new_ptr;
  int old_len, new_len;
  char *oldpath, *newpath;
  int ret, of, nf;
  struct stat ost, nst;

  /* 1. Parameter: Ptr to oldpath / length incl. trailing zero */
  if (remote_fileio_extract_ptr_w_len (&buf, &old_ptr, &old_len))
    {
      remote_fileio_ioerror ();
      return;
    }
  
  /* 2. Parameter: Ptr to newpath / length incl. trailing zero */
  if (remote_fileio_extract_ptr_w_len (&buf, &new_ptr, &new_len))
    {
      remote_fileio_ioerror ();
      return;
    }
  
  /* Request oldpath using 'm' packet */
  oldpath = (char *) alloca (old_len);
  if (target_read_memory (old_ptr, (gdb_byte *) oldpath, old_len) != 0)
    {
      remote_fileio_ioerror ();
      return;
    }
  
  /* Request newpath using 'm' packet */
  newpath = (char *) alloca (new_len);
  if (target_read_memory (new_ptr, (gdb_byte *) newpath, new_len) != 0)
    {
      remote_fileio_ioerror ();
      return;
    }
  
  /* Only operate on regular files and directories.  */
  of = stat (oldpath, &ost);
  nf = stat (newpath, &nst);
  if ((!of && !S_ISREG (ost.st_mode) && !S_ISDIR (ost.st_mode))
      || (!nf && !S_ISREG (nst.st_mode) && !S_ISDIR (nst.st_mode)))
    {
      remote_fileio_reply (-1, FILEIO_EACCES);
      return;
    }

  ret = rename (oldpath, newpath);

  if (ret == -1)
    {
      /* Special case: newpath is a non-empty directory.  Some systems
         return ENOTEMPTY, some return EEXIST.  We coerce that to be
	 always EEXIST.  */
      if (errno == ENOTEMPTY)
        errno = EEXIST;
#ifdef __CYGWIN__
      /* Workaround some Cygwin problems with correct errnos.  */
      if (errno == EACCES)
        {
	  if (!of && !nf && S_ISDIR (nst.st_mode))
	    {
	      if (S_ISREG (ost.st_mode))
		errno = EISDIR;
	      else
		{
		  char oldfullpath[PATH_MAX];
		  char newfullpath[PATH_MAX];
		  int len;

		  cygwin_conv_path (CCP_WIN_A_TO_POSIX, oldpath, oldfullpath,
				    PATH_MAX);
		  cygwin_conv_path (CCP_WIN_A_TO_POSIX, newpath, newfullpath,
				    PATH_MAX);
		  len = strlen (oldfullpath);
		  if (IS_DIR_SEPARATOR (newfullpath[len])
		      && !filename_ncmp (oldfullpath, newfullpath, len))
		    errno = EINVAL;
		  else
		    errno = EEXIST;
		}
	    }
	}
#endif

      remote_fileio_return_errno (-1);
    }
  else
    remote_fileio_return_success (ret);
}

static void
remote_fileio_func_unlink (char *buf)
{
  CORE_ADDR ptrval;
  int length;
  char *pathname;
  int ret;
  struct stat st;

  /* Parameter: Ptr to pathname / length incl. trailing zero */
  if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
    {
      remote_fileio_ioerror ();
      return;
    }
  /* Request pathname using 'm' packet */
  pathname = (char *) alloca (length);
  if (target_read_memory (ptrval, (gdb_byte *) pathname, length) != 0)
    {
      remote_fileio_ioerror ();
      return;
    }

  /* Only operate on regular files (and directories, which allows to return
     the correct return code).  */
  if (!stat (pathname, &st) && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
    {
      remote_fileio_reply (-1, FILEIO_ENODEV);
      return;
    }

  ret = unlink (pathname);

  if (ret == -1)
    remote_fileio_return_errno (-1);
  else
    remote_fileio_return_success (ret);
}

static void
remote_fileio_func_stat (char *buf)
{
  CORE_ADDR statptr, nameptr;
  int ret, namelength;
  char *pathname;
  LONGEST lnum;
  struct stat st;
  struct fio_stat fst;

  /* 1. Parameter: Ptr to pathname / length incl. trailing zero */
  if (remote_fileio_extract_ptr_w_len (&buf, &nameptr, &namelength))
    {
      remote_fileio_ioerror ();
      return;
    }

  /* 2. Parameter: Ptr to struct stat */
  if (remote_fileio_extract_long (&buf, &lnum))
    {
      remote_fileio_ioerror ();
      return;
    }
  statptr = (CORE_ADDR) lnum;
  
  /* Request pathname using 'm' packet */
  pathname = (char *) alloca (namelength);
  if (target_read_memory (nameptr, (gdb_byte *) pathname, namelength) != 0)
    {
      remote_fileio_ioerror ();
      return;
    }

  ret = stat (pathname, &st);

  if (ret == -1)
    {
      remote_fileio_return_errno (-1);
      return;
    }
  /* Only operate on regular files and directories.  */
  if (!ret && !S_ISREG (st.st_mode) && !S_ISDIR (st.st_mode))
    {
      remote_fileio_reply (-1, FILEIO_EACCES);
      return;
    }
  if (statptr)
    {
      host_to_fileio_stat (&st, &fst);
      host_to_fileio_uint (0, fst.fst_dev);

      errno = target_write_memory (statptr, (gdb_byte *) &fst, sizeof fst);
      if (errno != 0)
	{
	  remote_fileio_return_errno (-1);
	  return;
	}
    }
  remote_fileio_return_success (ret);
}

static void
remote_fileio_func_fstat (char *buf)
{
  CORE_ADDR ptrval;
  int fd, ret;
  long target_fd;
  LONGEST lnum;
  struct stat st;
  struct fio_stat fst;
  struct timeval tv;

  /* 1. Parameter: file descriptor */
  if (remote_fileio_extract_int (&buf, &target_fd))
    {
      remote_fileio_ioerror ();
      return;
    }
  fd = remote_fileio_map_fd ((int) target_fd);
  if (fd == FIO_FD_INVALID)
    {
      remote_fileio_badfd ();
      return;
    }
  /* 2. Parameter: Ptr to struct stat */
  if (remote_fileio_extract_long (&buf, &lnum))
    {
      remote_fileio_ioerror ();
      return;
    }
  ptrval = (CORE_ADDR) lnum;

  if (fd == FIO_FD_CONSOLE_IN || fd == FIO_FD_CONSOLE_OUT)
    {
      host_to_fileio_uint (1, fst.fst_dev);
      memset (&st, 0, sizeof (st));
      st.st_mode = S_IFCHR | (fd == FIO_FD_CONSOLE_IN ? S_IRUSR : S_IWUSR);
      st.st_nlink = 1;
#ifdef HAVE_GETUID
      st.st_uid = getuid ();
#endif
#ifdef HAVE_GETGID
      st.st_gid = getgid ();
#endif
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
      st.st_blksize = 512;
#endif
#if HAVE_STRUCT_STAT_ST_BLOCKS
      st.st_blocks = 0;
#endif
      if (!gettimeofday (&tv, NULL))
	st.st_atime = st.st_mtime = st.st_ctime = tv.tv_sec;
      else
        st.st_atime = st.st_mtime = st.st_ctime = (time_t) 0;
      ret = 0;
    }
  else
    ret = fstat (fd, &st);

  if (ret == -1)
    {
      remote_fileio_return_errno (-1);
      return;
    }
  if (ptrval)
    {
      host_to_fileio_stat (&st, &fst);

      errno = target_write_memory (ptrval, (gdb_byte *) &fst, sizeof fst);
      if (errno != 0)
	{
	  remote_fileio_return_errno (-1);
	  return;
	}
    }
  remote_fileio_return_success (ret);
}

static void
remote_fileio_func_gettimeofday (char *buf)
{
  LONGEST lnum;
  CORE_ADDR ptrval;
  int ret;
  struct timeval tv;
  struct fio_timeval ftv;

  /* 1. Parameter: struct timeval pointer */
  if (remote_fileio_extract_long (&buf, &lnum))
    {
      remote_fileio_ioerror ();
      return;
    }
  ptrval = (CORE_ADDR) lnum;
  /* 2. Parameter: some pointer value...  */
  if (remote_fileio_extract_long (&buf, &lnum))
    {
      remote_fileio_ioerror ();
      return;
    }
  /* ...which has to be NULL.  */
  if (lnum)
    {
      remote_fileio_reply (-1, FILEIO_EINVAL);
      return;
    }

  ret = gettimeofday (&tv, NULL);

  if (ret == -1)
    {
      remote_fileio_return_errno (-1);
      return;
    }

  if (ptrval)
    {
      remote_fileio_to_fio_timeval (&tv, &ftv);

      errno = target_write_memory (ptrval, (gdb_byte *) &ftv, sizeof ftv);
      if (errno != 0)
	{
	  remote_fileio_return_errno (-1);
	  return;
	}
    }
  remote_fileio_return_success (ret);
}

static void
remote_fileio_func_isatty (char *buf)
{
  long target_fd;
  int fd;

  /* Parameter: file descriptor */
  if (remote_fileio_extract_int (&buf, &target_fd))
    {
      remote_fileio_ioerror ();
      return;
    }
  fd = remote_fileio_map_fd ((int) target_fd);
  remote_fileio_return_success (fd == FIO_FD_CONSOLE_IN ||
  				fd == FIO_FD_CONSOLE_OUT ? 1 : 0);
}

static void
remote_fileio_func_system (char *buf)
{
  CORE_ADDR ptrval;
  int ret, length;
  char *cmdline = NULL;

  /* Parameter: Ptr to commandline / length incl. trailing zero */
  if (remote_fileio_extract_ptr_w_len (&buf, &ptrval, &length))
    {
      remote_fileio_ioerror ();
      return;
    }

  if (length)
    {
      /* Request commandline using 'm' packet */
      cmdline = (char *) alloca (length);
      if (target_read_memory (ptrval, (gdb_byte *) cmdline, length) != 0)
	{
	  remote_fileio_ioerror ();
	  return;
	}
    }
  
  /* Check if system(3) has been explicitely allowed using the
     `set remote system-call-allowed 1' command.  If length is 0,
     indicating a NULL parameter to the system call, return zero to
     indicate a shell is not available.  Otherwise fail with EPERM.  */
  if (!remote_fio_system_call_allowed)
    {
      if (!length)
	remote_fileio_return_success (0);
      else
	remote_fileio_reply (-1, FILEIO_EPERM);
      return;
    }

  ret = system (cmdline);

  if (!length)
    remote_fileio_return_success (ret);
  else if (ret == -1)
    remote_fileio_return_errno (-1);
  else
    remote_fileio_return_success (WEXITSTATUS (ret));
}

static struct {
  char *name;
  void (*func)(char *);
} remote_fio_func_map[] = {
  { "open", remote_fileio_func_open },
  { "close", remote_fileio_func_close },
  { "read", remote_fileio_func_read },
  { "write", remote_fileio_func_write },
  { "lseek", remote_fileio_func_lseek },
  { "rename", remote_fileio_func_rename },
  { "unlink", remote_fileio_func_unlink },
  { "stat", remote_fileio_func_stat },
  { "fstat", remote_fileio_func_fstat },
  { "gettimeofday", remote_fileio_func_gettimeofday },
  { "isatty", remote_fileio_func_isatty },
  { "system", remote_fileio_func_system },
  { NULL, NULL }
};

static int
do_remote_fileio_request (struct ui_out *uiout, void *buf_arg)
{
  char *buf = (char *) buf_arg;
  char *c;
  int idx;

  quit_handler = remote_fileio_quit_handler;

  c = strchr (++buf, ',');
  if (c)
    *c++ = '\0';
  else
    c = strchr (buf, '\0');
  for (idx = 0; remote_fio_func_map[idx].name; ++idx)
    if (!strcmp (remote_fio_func_map[idx].name, buf))
      break;
  if (!remote_fio_func_map[idx].name)	/* ERROR: No such function.  */
    return RETURN_ERROR;
  remote_fio_func_map[idx].func (c);
  return 0;
}

/* Close any open descriptors, and reinitialize the file mapping.  */

void
remote_fileio_reset (void)
{
  int ix;

  for (ix = 0; ix != remote_fio_data.fd_map_size; ix++)
    {
      int fd = remote_fio_data.fd_map[ix];

      if (fd >= 0)
	close (fd);
    }
  if (remote_fio_data.fd_map)
    {
      xfree (remote_fio_data.fd_map);
      remote_fio_data.fd_map = NULL;
      remote_fio_data.fd_map_size = 0;
    }
}

/* Handle a file I/O request.  BUF points to the packet containing the
   request.  CTRLC_PENDING_P should be nonzero if the target has not
   acknowledged the Ctrl-C sent asynchronously earlier.  */

void
remote_fileio_request (char *buf, int ctrlc_pending_p)
{
  int ex;

  /* Save the previous quit handler, so we can restore it.  No need
     for a cleanup since we catch all exceptions below.  Note that the
     quit handler is also restored by remote_fileio_reply just before
     pushing a packet.  */
  remote_fileio_o_quit_handler = quit_handler;

  if (ctrlc_pending_p)
    {
      /* If the target hasn't responded to the Ctrl-C sent
	 asynchronously earlier, take this opportunity to send the
	 Ctrl-C synchronously.  */
      set_quit_flag ();
      remote_fileio_reply (-1, FILEIO_EINTR);
    }
  else
    {
      ex = catch_exceptions (current_uiout,
			     do_remote_fileio_request, (void *)buf,
			     RETURN_MASK_ALL);
      switch (ex)
	{
	case RETURN_ERROR:
	  remote_fileio_reply (-1, FILEIO_ENOSYS);
	  break;
	case RETURN_QUIT:
	  remote_fileio_reply (-1, FILEIO_EINTR);
	  break;
	default:
	  break;
	}
    }

  quit_handler = remote_fileio_o_quit_handler;
}


/* Unpack an fio_uint_t.  */

static unsigned int
remote_fileio_to_host_uint (fio_uint_t fnum)
{
  return extract_unsigned_integer ((gdb_byte *) fnum, 4,
				   BFD_ENDIAN_BIG);
}

/* Unpack an fio_ulong_t.  */

static ULONGEST
remote_fileio_to_host_ulong (fio_ulong_t fnum)
{
  return extract_unsigned_integer ((gdb_byte *) fnum, 8,
				   BFD_ENDIAN_BIG);
}

/* Unpack an fio_mode_t.  */

static mode_t
remote_fileio_to_host_mode (fio_mode_t fnum)
{
  return remote_fileio_mode_to_host (remote_fileio_to_host_uint (fnum),
				     0);
}

/* Unpack an fio_time_t.  */

static time_t
remote_fileio_to_host_time (fio_time_t fnum)
{
  return remote_fileio_to_host_uint (fnum);
}


/* See remote-fileio.h.  */

void
remote_fileio_to_host_stat (struct fio_stat *fst, struct stat *st)
{
  memset (st, 0, sizeof (struct stat));

  st->st_dev = remote_fileio_to_host_uint (fst->fst_dev);
  st->st_ino = remote_fileio_to_host_uint (fst->fst_ino);
  st->st_mode = remote_fileio_to_host_mode (fst->fst_mode);
  st->st_nlink = remote_fileio_to_host_uint (fst->fst_nlink);
  st->st_uid = remote_fileio_to_host_uint (fst->fst_uid);
  st->st_gid = remote_fileio_to_host_uint (fst->fst_gid);
  st->st_rdev = remote_fileio_to_host_uint (fst->fst_rdev);
  st->st_size = remote_fileio_to_host_ulong (fst->fst_size);
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
  st->st_blksize = remote_fileio_to_host_ulong (fst->fst_blksize);
#endif
#if HAVE_STRUCT_STAT_ST_BLOCKS
  st->st_blocks = remote_fileio_to_host_ulong (fst->fst_blocks);
#endif
  st->st_atime = remote_fileio_to_host_time (fst->fst_atime);
  st->st_mtime = remote_fileio_to_host_time (fst->fst_mtime);
  st->st_ctime = remote_fileio_to_host_time (fst->fst_ctime);
}


static void
set_system_call_allowed (char *args, int from_tty)
{
  if (args)
    {
      char *arg_end;
      int val = strtoul (args, &arg_end, 10);

      if (*args && *arg_end == '\0')
        {
	  remote_fio_system_call_allowed = !!val;
	  return;
	}
    }
  error (_("Illegal argument for \"set remote system-call-allowed\" command"));
}

static void
show_system_call_allowed (char *args, int from_tty)
{
  if (args)
    error (_("Garbage after \"show remote "
	     "system-call-allowed\" command: `%s'"), args);
  printf_unfiltered ("Calling host system(3) call from target is %sallowed\n",
		     remote_fio_system_call_allowed ? "" : "not ");
}

void
initialize_remote_fileio (struct cmd_list_element *remote_set_cmdlist,
			  struct cmd_list_element *remote_show_cmdlist)
{
  add_cmd ("system-call-allowed", no_class,
	   set_system_call_allowed,
	   _("Set if the host system(3) call is allowed for the target."),
	   &remote_set_cmdlist);
  add_cmd ("system-call-allowed", no_class,
	   show_system_call_allowed,
	   _("Show if the host system(3) call is allowed for the target."),
	   &remote_show_cmdlist);
}
