/* Host file transfer support for gdbserver.
   Copyright (C) 2007-2019 Free Software Foundation, Inc.

   Contributed by CodeSourcery.

   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/>.  */

#include "server.h"
#include "gdb/fileio.h"
#include "hostio.h"

#include <fcntl.h>
#include <limits.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "common/fileio.h"

struct fd_list
{
  int fd;
  struct fd_list *next;
};

static struct fd_list *open_fds;

static int
safe_fromhex (char a, int *nibble)
{
  if (a >= '0' && a <= '9')
    *nibble = a - '0';
  else if (a >= 'a' && a <= 'f')
    *nibble = a - 'a' + 10;
  else if (a >= 'A' && a <= 'F')
    *nibble = a - 'A' + 10;
  else
    return -1;

  return 0;
}

/* Filenames are hex encoded, so the maximum we can handle is half the
   packet buffer size.  Cap to PATH_MAX, if it is shorter.  */
#if !defined (PATH_MAX) || (PATH_MAX > (PBUFSIZ / 2 + 1))
#  define HOSTIO_PATH_MAX (PBUFSIZ / 2 + 1)
#else
#  define HOSTIO_PATH_MAX PATH_MAX
#endif

static int
require_filename (char **pp, char *filename)
{
  int count;
  char *p;

  p = *pp;
  count = 0;

  while (*p && *p != ',')
    {
      int nib1, nib2;

      /* Don't allow overflow.  */
      if (count >= HOSTIO_PATH_MAX - 1)
	return -1;

      if (safe_fromhex (p[0], &nib1)
	  || safe_fromhex (p[1], &nib2))
	return -1;

      filename[count++] = nib1 * 16 + nib2;
      p += 2;
    }

  filename[count] = '\0';
  *pp = p;
  return 0;
}

static int
require_int (char **pp, int *value)
{
  char *p;
  int count, firstdigit;

  p = *pp;
  *value = 0;
  count = 0;
  firstdigit = -1;

  while (*p && *p != ',')
    {
      int nib;

      if (safe_fromhex (p[0], &nib))
	return -1;

      if (firstdigit == -1)
	firstdigit = nib;

      /* Don't allow overflow.  */
      if (count >= 8 || (count == 7 && firstdigit >= 0x8))
	return -1;

      *value = *value * 16 + nib;
      p++;
      count++;
    }

  *pp = p;
  return 0;
}

static int
require_data (char *p, int p_len, char **data, int *data_len)
{
  int input_index, output_index, escaped;

  *data = (char *) xmalloc (p_len);

  output_index = 0;
  escaped = 0;
  for (input_index = 0; input_index < p_len; input_index++)
    {
      char b = p[input_index];

      if (escaped)
	{
	  (*data)[output_index++] = b ^ 0x20;
	  escaped = 0;
	}
      else if (b == '}')
	escaped = 1;
      else
	(*data)[output_index++] = b;
    }

  if (escaped)
    {
      free (*data);
      return -1;
    }

  *data_len = output_index;
  return 0;
}

static int
require_comma (char **pp)
{
  if (**pp == ',')
    {
      (*pp)++;
      return 0;
    }
  else
    return -1;
}

static int
require_end (char *p)
{
  if (*p == '\0')
    return 0;
  else
    return -1;
}

static int
require_valid_fd (int fd)
{
  struct fd_list *fd_ptr;

  for (fd_ptr = open_fds; fd_ptr != NULL; fd_ptr = fd_ptr->next)
    if (fd_ptr->fd == fd)
      return 0;

  return -1;
}

/* Fill in own_buf with the last hostio error packet, however it
   suitable for the target.  */
static void
hostio_error (char *own_buf)
{
  the_target->hostio_last_error (own_buf);
}

static void
hostio_packet_error (char *own_buf)
{
  sprintf (own_buf, "F-1,%x", FILEIO_EINVAL);
}

static void
hostio_reply (char *own_buf, int result)
{
  sprintf (own_buf, "F%x", result);
}

static int
hostio_reply_with_data (char *own_buf, char *buffer, int len,
			int *new_packet_len)
{
  int input_index, output_index, out_maxlen;

  sprintf (own_buf, "F%x;", len);
  output_index = strlen (own_buf);

  out_maxlen = PBUFSIZ;

  for (input_index = 0; input_index < len; input_index++)
    {
      char b = buffer[input_index];

      if (b == '$' || b == '#' || b == '}' || b == '*')
	{
	  /* These must be escaped.  */
	  if (output_index + 2 > out_maxlen)
	    break;
	  own_buf[output_index++] = '}';
	  own_buf[output_index++] = b ^ 0x20;
	}
      else
	{
	  if (output_index + 1 > out_maxlen)
	    break;
	  own_buf[output_index++] = b;
	}
    }

  *new_packet_len = output_index;
  return input_index;
}

/* Process ID of inferior whose filesystem hostio functions
   that take FILENAME arguments will use.  Zero means to use
   our own filesystem.  */

static int hostio_fs_pid;

/* See hostio.h.  */

void
hostio_handle_new_gdb_connection (void)
{
  hostio_fs_pid = 0;
}

/* Handle a "vFile:setfs:" packet.  */

static void
handle_setfs (char *own_buf)
{
  char *p;
  int pid;

  /* If the target doesn't have any of the in-filesystem-of methods
     then there's no point in GDB sending "vFile:setfs:" packets.  We
     reply with an empty packet (i.e. we pretend we don't understand
     "vFile:setfs:") and that should stop GDB sending any more.  */
  if (the_target->multifs_open == NULL
      && the_target->multifs_unlink == NULL
      && the_target->multifs_readlink == NULL)
    {
      own_buf[0] = '\0';
      return;
    }

  p = own_buf + strlen ("vFile:setfs:");

  if (require_int (&p, &pid)
      || pid < 0
      || require_end (p))
    {
      hostio_packet_error (own_buf);
      return;
    }

  hostio_fs_pid = pid;

  hostio_reply (own_buf, 0);
}

static void
handle_open (char *own_buf)
{
  char filename[HOSTIO_PATH_MAX];
  char *p;
  int fileio_flags, fileio_mode, flags, fd;
  mode_t mode;
  struct fd_list *new_fd;

  p = own_buf + strlen ("vFile:open:");

  if (require_filename (&p, filename)
      || require_comma (&p)
      || require_int (&p, &fileio_flags)
      || require_comma (&p)
      || require_int (&p, &fileio_mode)
      || require_end (p)
      || fileio_to_host_openflags (fileio_flags, &flags)
      || fileio_to_host_mode (fileio_mode, &mode))
    {
      hostio_packet_error (own_buf);
      return;
    }

  /* We do not need to convert MODE, since the fileio protocol
     uses the standard values.  */
  if (hostio_fs_pid != 0 && the_target->multifs_open != NULL)
    fd = the_target->multifs_open (hostio_fs_pid, filename,
				   flags, mode);
  else
    fd = open (filename, flags, mode);

  if (fd == -1)
    {
      hostio_error (own_buf);
      return;
    }

  /* Record the new file descriptor.  */
  new_fd = XNEW (struct fd_list);
  new_fd->fd = fd;
  new_fd->next = open_fds;
  open_fds = new_fd;

  hostio_reply (own_buf, fd);
}

static void
handle_pread (char *own_buf, int *new_packet_len)
{
  int fd, ret, len, offset, bytes_sent;
  char *p, *data;
  static int max_reply_size = -1;

  p = own_buf + strlen ("vFile:pread:");

  if (require_int (&p, &fd)
      || require_comma (&p)
      || require_valid_fd (fd)
      || require_int (&p, &len)
      || require_comma (&p)
      || require_int (&p, &offset)
      || require_end (p))
    {
      hostio_packet_error (own_buf);
      return;
    }

  /* Do not attempt to read more than the maximum number of bytes
     hostio_reply_with_data can fit in a packet.  We may still read
     too much because of escaping, but this is handled below.  */
  if (max_reply_size == -1)
    {
      sprintf (own_buf, "F%x;", PBUFSIZ);
      max_reply_size = PBUFSIZ - strlen (own_buf);
    }
  if (len > max_reply_size)
    len = max_reply_size;

  data = (char *) xmalloc (len);
#ifdef HAVE_PREAD
  ret = pread (fd, data, len, offset);
#else
  ret = -1;
#endif
  /* If we have no pread or it failed for this file, use lseek/read.  */
  if (ret == -1)
    {
      ret = lseek (fd, offset, SEEK_SET);
      if (ret != -1)
	ret = read (fd, data, len);
    }

  if (ret == -1)
    {
      hostio_error (own_buf);
      free (data);
      return;
    }

  bytes_sent = hostio_reply_with_data (own_buf, data, ret, new_packet_len);

  /* If we were using read, and the data did not all fit in the reply,
     we would have to back up using lseek here.  With pread it does
     not matter.  But we still have a problem; the return value in the
     packet might be wrong, so we must fix it.  This time it will
     definitely fit.  */
  if (bytes_sent < ret)
    bytes_sent = hostio_reply_with_data (own_buf, data, bytes_sent,
					 new_packet_len);

  free (data);
}

static void
handle_pwrite (char *own_buf, int packet_len)
{
  int fd, ret, len, offset;
  char *p, *data;

  p = own_buf + strlen ("vFile:pwrite:");

  if (require_int (&p, &fd)
      || require_comma (&p)
      || require_valid_fd (fd)
      || require_int (&p, &offset)
      || require_comma (&p)
      || require_data (p, packet_len - (p - own_buf), &data, &len))
    {
      hostio_packet_error (own_buf);
      return;
    }

#ifdef HAVE_PWRITE
  ret = pwrite (fd, data, len, offset);
#else
  ret = -1;
#endif
  /* If we have no pwrite or it failed for this file, use lseek/write.  */
  if (ret == -1)
    {
      ret = lseek (fd, offset, SEEK_SET);
      if (ret != -1)
	ret = write (fd, data, len);
    }

  if (ret == -1)
    {
      hostio_error (own_buf);
      free (data);
      return;
    }

  hostio_reply (own_buf, ret);
  free (data);
}

static void
handle_fstat (char *own_buf, int *new_packet_len)
{
  int fd, bytes_sent;
  char *p;
  struct stat st;
  struct fio_stat fst;

  p = own_buf + strlen ("vFile:fstat:");

  if (require_int (&p, &fd)
      || require_valid_fd (fd)
      || require_end (p))
    {
      hostio_packet_error (own_buf);
      return;
    }

  if (fstat (fd, &st) == -1)
    {
      hostio_error (own_buf);
      return;
    }

  host_to_fileio_stat (&st, &fst);

  bytes_sent = hostio_reply_with_data (own_buf,
				       (char *) &fst, sizeof (fst),
				       new_packet_len);

  /* If the response does not fit into a single packet, do not attempt
     to return a partial response, but simply fail.  */
  if (bytes_sent < sizeof (fst))
    write_enn (own_buf);
}

static void
handle_close (char *own_buf)
{
  int fd, ret;
  char *p;
  struct fd_list **open_fd_p, *old_fd;

  p = own_buf + strlen ("vFile:close:");

  if (require_int (&p, &fd)
      || require_valid_fd (fd)
      || require_end (p))
    {
      hostio_packet_error (own_buf);
      return;
    }

  ret = close (fd);

  if (ret == -1)
    {
      hostio_error (own_buf);
      return;
    }

  open_fd_p = &open_fds;
  /* We know that fd is in the list, thanks to require_valid_fd.  */
  while ((*open_fd_p)->fd != fd)
    open_fd_p = &(*open_fd_p)->next;

  old_fd = *open_fd_p;
  *open_fd_p = (*open_fd_p)->next;
  free (old_fd);

  hostio_reply (own_buf, ret);
}

static void
handle_unlink (char *own_buf)
{
  char filename[HOSTIO_PATH_MAX];
  char *p;
  int ret;

  p = own_buf + strlen ("vFile:unlink:");

  if (require_filename (&p, filename)
      || require_end (p))
    {
      hostio_packet_error (own_buf);
      return;
    }

  if (hostio_fs_pid != 0 && the_target->multifs_unlink != NULL)
    ret = the_target->multifs_unlink (hostio_fs_pid, filename);
  else
    ret = unlink (filename);

  if (ret == -1)
    {
      hostio_error (own_buf);
      return;
    }

  hostio_reply (own_buf, ret);
}

static void
handle_readlink (char *own_buf, int *new_packet_len)
{
  char filename[HOSTIO_PATH_MAX], linkname[HOSTIO_PATH_MAX];
  char *p;
  int ret, bytes_sent;

  p = own_buf + strlen ("vFile:readlink:");

  if (require_filename (&p, filename)
      || require_end (p))
    {
      hostio_packet_error (own_buf);
      return;
    }

  if (hostio_fs_pid != 0 && the_target->multifs_readlink != NULL)
    ret = the_target->multifs_readlink (hostio_fs_pid, filename,
					linkname,
					sizeof (linkname) - 1);
  else
    ret = readlink (filename, linkname, sizeof (linkname) - 1);

  if (ret == -1)
    {
      hostio_error (own_buf);
      return;
    }

  bytes_sent = hostio_reply_with_data (own_buf, linkname, ret, new_packet_len);

  /* If the response does not fit into a single packet, do not attempt
     to return a partial response, but simply fail.  */
  if (bytes_sent < ret)
    sprintf (own_buf, "F-1,%x", FILEIO_ENAMETOOLONG);
}

/* Handle all the 'F' file transfer packets.  */

int
handle_vFile (char *own_buf, int packet_len, int *new_packet_len)
{
  if (startswith (own_buf, "vFile:open:"))
    handle_open (own_buf);
  else if (startswith (own_buf, "vFile:pread:"))
    handle_pread (own_buf, new_packet_len);
  else if (startswith (own_buf, "vFile:pwrite:"))
    handle_pwrite (own_buf, packet_len);
  else if (startswith (own_buf, "vFile:fstat:"))
    handle_fstat (own_buf, new_packet_len);
  else if (startswith (own_buf, "vFile:close:"))
    handle_close (own_buf);
  else if (startswith (own_buf, "vFile:unlink:"))
    handle_unlink (own_buf);
  else if (startswith (own_buf, "vFile:readlink:"))
    handle_readlink (own_buf, new_packet_len);
  else if (startswith (own_buf, "vFile:setfs:"))
    handle_setfs (own_buf);
  else
    return 0;

  return 1;
}
