Exemplo n.º 1
0
static void
send_error (int errnum, char *msg)
{
  XDR xdr;
  CLEANUP_FREE char *buf = NULL;
  char lenbuf[4];
  struct guestfs_message_header hdr;
  struct guestfs_message_error err;
  unsigned len;

  /* Print the full length error message. */
  fprintf (stderr, "guestfsd: error: %s\n", msg);

  /* We want to truncate the error message to GUESTFS_ERROR_LEN bytes
   * (not including the \0 since it is not encoded in XDR).  This is
   * so that the xdr_guestfs_message_error call below won't fail on
   * very long error messages.  We can overwrite the message since all
   * callers of send_error pass a temporary buffer.
   */
  if (strlen (msg) > GUESTFS_ERROR_LEN)
    msg[GUESTFS_ERROR_LEN] = '\0';

  buf = malloc (GUESTFS_ERROR_LEN + 200);
  if (!buf)
    error (EXIT_FAILURE, errno, "malloc");
  xdrmem_create (&xdr, buf, GUESTFS_ERROR_LEN + 200, XDR_ENCODE);

  memset (&hdr, 0, sizeof hdr);
  hdr.prog = GUESTFS_PROGRAM;
  hdr.vers = GUESTFS_PROTOCOL_VERSION;
  hdr.direction = GUESTFS_DIRECTION_REPLY;
  hdr.status = GUESTFS_STATUS_ERROR;
  hdr.proc = proc_nr;
  hdr.serial = serial;

  if (!xdr_guestfs_message_header (&xdr, &hdr))
    error (EXIT_FAILURE, 0, "failed to encode error message header");

  /* These strings are not going to be freed.  We just cast them
   * to (char *) because they are defined that way in the XDR structs.
   */
  err.errno_string =
    (char *) (errnum > 0 ? guestfs_int_errno_to_string (errnum) : "");
  err.error_message = (char *) msg;

  if (!xdr_guestfs_message_error (&xdr, &err))
    error (EXIT_FAILURE, 0, "failed to encode error message body");

  len = xdr_getpos (&xdr);
  xdr_destroy (&xdr);

  xdrmem_create (&xdr, lenbuf, 4, XDR_ENCODE);
  xdr_u_int (&xdr, &len);
  xdr_destroy (&xdr);

  if (xwrite (sock, lenbuf, 4) == -1)
    error (EXIT_FAILURE, 0, "xwrite failed");
  if (xwrite (sock, buf, len) == -1)
    error (EXIT_FAILURE, 0, "xwrite failed");
}
Exemplo n.º 2
0
/* Receive a reply. */
int
guestfs___recv (guestfs_h *g, const char *fn,
                guestfs_message_header *hdr,
                guestfs_message_error *err,
                xdrproc_t xdrp, char *ret)
{
  XDR xdr;
  void *buf;
  uint32_t size;
  int r;

 again:
  r = guestfs___recv_from_daemon (g, &size, &buf);
  if (r == -1)
    return -1;

  /* This can happen if a cancellation happens right at the end
   * of us sending a FileIn parameter to the daemon.  Discard.  The
   * daemon should send us an error message next.
   */
  if (size == GUESTFS_CANCEL_FLAG)
    goto again;

  if (size == GUESTFS_LAUNCH_FLAG) {
    error (g, "%s: received unexpected launch flag from daemon when expecting reply", fn);
    return -1;
  }

  xdrmem_create (&xdr, buf, size, XDR_DECODE);

  if (!xdr_guestfs_message_header (&xdr, hdr)) {
    error (g, "%s: failed to parse reply header", fn);
    xdr_destroy (&xdr);
    free (buf);
    return -1;
  }
  if (hdr->status == GUESTFS_STATUS_ERROR) {
    if (!xdr_guestfs_message_error (&xdr, err)) {
      error (g, "%s: failed to parse reply error", fn);
      xdr_destroy (&xdr);
      free (buf);
      return -1;
    }
  } else {
    if (xdrp && ret && !xdrp (&xdr, ret)) {
      error (g, "%s: failed to parse reply", fn);
      xdr_destroy (&xdr);
      free (buf);
      return -1;
    }
  }
  xdr_destroy (&xdr);
  free (buf);

  return 0;
}
Exemplo n.º 3
0
static void
send_error (int errnum, const char *msg)
{
  XDR xdr;
  char buf[GUESTFS_ERROR_LEN + 200];
  char lenbuf[4];
  struct guestfs_message_header hdr;
  struct guestfs_message_error err;
  unsigned len;

  fprintf (stderr, "guestfsd: error: %s\n", msg);

  xdrmem_create (&xdr, buf, sizeof buf, XDR_ENCODE);

  memset (&hdr, 0, sizeof hdr);
  hdr.prog = GUESTFS_PROGRAM;
  hdr.vers = GUESTFS_PROTOCOL_VERSION;
  hdr.direction = GUESTFS_DIRECTION_REPLY;
  hdr.status = GUESTFS_STATUS_ERROR;
  hdr.proc = proc_nr;
  hdr.serial = serial;

  if (!xdr_guestfs_message_header (&xdr, &hdr)) {
    fprintf (stderr, "guestfsd: failed to encode error message header\n");
    exit (EXIT_FAILURE);
  }

  /* These strings are not going to be freed.  We just cast them
   * to (char *) because they are defined that way in the XDR structs.
   */
  err.errno_string =
    (char *) (errnum > 0 ? guestfs___errno_to_string (errnum) : "");
  err.error_message = (char *) msg;

  if (!xdr_guestfs_message_error (&xdr, &err)) {
    fprintf (stderr, "guestfsd: failed to encode error message body\n");
    exit (EXIT_FAILURE);
  }

  len = xdr_getpos (&xdr);
  xdr_destroy (&xdr);

  xdrmem_create (&xdr, lenbuf, 4, XDR_ENCODE);
  xdr_u_int (&xdr, &len);
  xdr_destroy (&xdr);

  if (xwrite (sock, lenbuf, 4) == -1) {
    fprintf (stderr, "guestfsd: xwrite failed\n");
    exit (EXIT_FAILURE);
  }
  if (xwrite (sock, buf, len) == -1) {
    fprintf (stderr, "guestfsd: xwrite failed\n");
    exit (EXIT_FAILURE);
  }
}