Beispiel #1
0
static gpgme_error_t
start (engine_gpgsm_t gpgsm, const char *command)
{
  gpgme_error_t err;
  assuan_fd_t afdlist[5];
  int fdlist[5];
  int nfds;
  int i;

  /* We need to know the fd used by assuan for reads.  We do this by
     using the assumption that the first returned fd from
     assuan_get_active_fds() is always this one.  */
  nfds = assuan_get_active_fds (gpgsm->assuan_ctx, 0 /* read fds */,
                                afdlist, DIM (afdlist));
  if (nfds < 1)
    return gpg_error (GPG_ERR_GENERAL);	/* FIXME */
  /* For now... */
  for (i = 0; i < nfds; i++)
    fdlist[i] = (int) afdlist[i];

  /* We "duplicate" the file descriptor, so we can close it here (we
     can't close fdlist[0], as that is closed by libassuan, and
     closing it here might cause libassuan to close some unrelated FD
     later).  Alternatively, we could special case status_fd and
     register/unregister it manually as needed, but this increases
     code duplication and is more complicated as we can not use the
     close notifications etc.  A third alternative would be to let
     Assuan know that we closed the FD, but that complicates the
     Assuan interface.  */

  gpgsm->status_cb.fd = _gpgme_io_dup (fdlist[0]);
  if (gpgsm->status_cb.fd < 0)
    return gpg_error_from_syserror ();

  if (_gpgme_io_set_close_notify (gpgsm->status_cb.fd,
				  close_notify_handler, gpgsm))
    {
      _gpgme_io_close (gpgsm->status_cb.fd);
      gpgsm->status_cb.fd = -1;
      return gpg_error (GPG_ERR_GENERAL);
    }

  err = add_io_cb (gpgsm, &gpgsm->status_cb, status_handler);
  if (!err && gpgsm->input_cb.fd != -1)
    err = add_io_cb (gpgsm, &gpgsm->input_cb, _gpgme_data_outbound_handler);
  if (!err && gpgsm->output_cb.fd != -1)
    err = add_io_cb (gpgsm, &gpgsm->output_cb, _gpgme_data_inbound_handler);
  if (!err && gpgsm->message_cb.fd != -1)
    err = add_io_cb (gpgsm, &gpgsm->message_cb, _gpgme_data_outbound_handler);

  if (!err)
    err = assuan_write_line (gpgsm->assuan_ctx, command);

  if (!err)
    gpgsm_io_event (gpgsm, GPGME_EVENT_START, NULL);

  return err;
}
Beispiel #2
0
static gpgme_error_t
start(engine_gpgsm_t gpgsm, const char *command)
{
    gpgme_error_t err;
    int fdlist[5];
    int nfds;

    /* We need to know the fd used by assuan for reads.  We do this by
       using the assumption that the first returned fd from
       assuan_get_active_fds() is always this one.  */
    nfds = assuan_get_active_fds(gpgsm->assuan_ctx, 0 /* read fds */,
                                 fdlist, DIM(fdlist));
    if(nfds < 1)
        return gpg_error(GPG_ERR_GENERAL);	/* FIXME */

    /* We duplicate the file descriptor, so we can close it without
       disturbing assuan.  Alternatively, we could special case
       status_fd and register/unregister it manually as needed, but this
       increases code duplication and is more complicated as we can not
       use the close notifications etc.  */
    gpgsm->status_cb.fd = dup(fdlist[0]);
    if(gpgsm->status_cb.fd < 0)
        return gpg_error_from_syserror();

    if(_gpgme_io_set_close_notify(gpgsm->status_cb.fd,
                                  close_notify_handler, gpgsm))
    {
        close(gpgsm->status_cb.fd);
        gpgsm->status_cb.fd = -1;
        return gpg_error(GPG_ERR_GENERAL);
    }

    err = add_io_cb(gpgsm, &gpgsm->status_cb, status_handler);
    if(!err && gpgsm->input_cb.fd != -1)
        err = add_io_cb(gpgsm, &gpgsm->input_cb, _gpgme_data_outbound_handler);
    if(!err && gpgsm->output_cb.fd != -1)
        err = add_io_cb(gpgsm, &gpgsm->output_cb, _gpgme_data_inbound_handler);
    if(!err && gpgsm->message_cb.fd != -1)
        err = add_io_cb(gpgsm, &gpgsm->message_cb, _gpgme_data_outbound_handler);

    if(!err)
        err = map_assuan_error(assuan_write_line(gpgsm->assuan_ctx, command));

    if(!err)
        (*gpgsm->io_cbs.event)(gpgsm->io_cbs.event_priv, GPGME_EVENT_START, NULL);

    return err;
}
Beispiel #3
0
static gpgme_error_t
engspawn_start (engine_spawn_t esp, const char *file, const char *argv[],
                unsigned int flags)
{
  gpgme_error_t err;
  int i, n;
  int status;
  struct spawn_fd_item_s *fd_list;
  pid_t pid;
  unsigned int spflags;
  const char *save_argv0 = NULL;

  if (!esp || !file || !argv || !argv[0])
    return gpg_error (GPG_ERR_INV_VALUE);

  spflags = 0;
  if ((flags & GPGME_SPAWN_DETACHED))
    spflags |= IOSPAWN_FLAG_DETACHED;
  if ((flags & GPGME_SPAWN_ALLOW_SET_FG))
    spflags |= IOSPAWN_FLAG_ALLOW_SET_FG;


  err = build_fd_data_map (esp);
  if (err)
    return err;

  n = 0;
  for (i = 0; esp->fd_data_map[i].data; i++)
    n++;
  fd_list = calloc (n+1, sizeof *fd_list);
  if (!fd_list)
    return gpg_error_from_syserror ();

  /* Build the fd list for the child.  */
  n = 0;
  for (i = 0; esp->fd_data_map[i].data; i++)
    {
      fd_list[n].fd = esp->fd_data_map[i].peer_fd;
      fd_list[n].dup_to = esp->fd_data_map[i].dup_to;
      n++;
    }
  fd_list[n].fd = -1;
  fd_list[n].dup_to = -1;

  if (argv[0] && !*argv[0])
    {
      save_argv0 = argv[0];
      argv[0] = _gpgme_get_basename (file);
    }
  status = _gpgme_io_spawn (file, (char * const *)argv, spflags,
                            fd_list, NULL, NULL, &pid);
  if (save_argv0)
    argv[0] = save_argv0;
  free (fd_list);
  if (status == -1)
    return gpg_error_from_syserror ();

  for (i = 0; esp->fd_data_map[i].data; i++)
    {
      err = add_io_cb (esp, esp->fd_data_map[i].fd,
                       esp->fd_data_map[i].inbound,
                       esp->fd_data_map[i].inbound
                       ? _gpgme_data_inbound_handler
                       : _gpgme_data_outbound_handler,
                       esp->fd_data_map[i].data, &esp->fd_data_map[i].tag);
      if (err)
        return err;  /* FIXME: kill the child */
    }

  engspawn_io_event (esp, GPGME_EVENT_START, NULL);

  return 0;
}