start_agent (ctrl_t ctrl, int for_card)
{
  int rc;

  (void)ctrl;  /* Not yet used.  */

  /* Fixme: We need a context for each thread or serialize the access
     to the agent. */
  if (agent_ctx)
    rc = 0;
  else
    {
      rc = start_new_gpg_agent (&agent_ctx,
                                GPG_ERR_SOURCE_DEFAULT,
                                opt.homedir,
                                opt.agent_program,
                                opt.lc_ctype, opt.lc_messages,
                                opt.session_env,
                                opt.autostart, opt.verbose, DBG_ASSUAN,
                                NULL, NULL);
      if (!opt.autostart && gpg_err_code (rc) == GPG_ERR_NO_AGENT)
        {
          static int shown;

          if (!shown)
            {
              shown = 1;
              log_info (_("no gpg-agent running in this session\n"));
            }
        }
      else if (!rc)
        {
          /* Tell the agent that we support Pinentry notifications.
             No error checking so that it will work also with older
             agents.  */
          assuan_transact (agent_ctx, "OPTION allow-pinentry-notify",
                           NULL, NULL, NULL, NULL, NULL, NULL);
          /* Tell the agent about what version we are aware.  This is
             here used to indirectly enable GPG_ERR_FULLY_CANCELED.  */
          assuan_transact (agent_ctx, "OPTION agent-awareness=2.1.0",
                           NULL, NULL, NULL, NULL, NULL, NULL);
          /* Pass on the pinentry mode.  */
          if (opt.pinentry_mode)
            {
              char *tmp = xasprintf ("OPTION pinentry-mode=%s",
                                     str_pinentry_mode (opt.pinentry_mode));
              rc = assuan_transact (agent_ctx, tmp,
                               NULL, NULL, NULL, NULL, NULL, NULL);
              xfree (tmp);
              if (rc)
                log_error ("setting pinentry mode '%s' failed: %s\n",
                           str_pinentry_mode (opt.pinentry_mode),
                           gpg_strerror (rc));
            }

          check_hijacking (agent_ctx);
        }
    }

  if (!rc && for_card && !did_early_card_test)
    {
      /* Request the serial number of the card for an early test.  */
      struct agent_card_info_s info;

      memset (&info, 0, sizeof info);
      rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp",
                            NULL, NULL, NULL, NULL,
                            learn_status_cb, &info);
      if (rc)
        {
          switch (gpg_err_code (rc))
            {
            case GPG_ERR_NOT_SUPPORTED:
            case GPG_ERR_NO_SCDAEMON:
              write_status_text (STATUS_CARDCTRL, "6");
              break;
            case GPG_ERR_OBJ_TERM_STATE:
              write_status_text (STATUS_CARDCTRL, "7");
              break;
            default:
              write_status_text (STATUS_CARDCTRL, "4");
              log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc));
              break;
            }
        }

      if (!rc && is_status_enabled () && info.serialno)
        {
          char *buf;

          buf = xasprintf ("3 %s", info.serialno);
          write_status_text (STATUS_CARDCTRL, buf);
          xfree (buf);
        }

      agent_release_card_info (&info);

      if (!rc)
        did_early_card_test = 1;
    }


  return rc;
}