agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
              char **cache_nonce_addr, char **passwd_nonce_addr)
{
  gpg_error_t err;
  struct cache_nonce_parm_s cn_parm;
  char line[ASSUAN_LINELENGTH];
  struct default_inq_parm_s dfltparm;

  memset (&dfltparm, 0, sizeof dfltparm);
  dfltparm.ctrl = ctrl;

  err = start_agent (ctrl, 0);
  if (err)
    return err;
  dfltparm.ctx = agent_ctx;

  if (!hexkeygrip || strlen (hexkeygrip) != 40)
    return gpg_error (GPG_ERR_INV_VALUE);


  if (desc)
    {
      snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
      err = assuan_transact (agent_ctx, line,
                             NULL, NULL, NULL, NULL, NULL, NULL);
      if (err)
        return err;
    }

  snprintf (line, DIM(line)-1, "PASSWD %s%s %s%s %s",
            cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
            cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
            passwd_nonce_addr && *passwd_nonce_addr? "--passwd-nonce=":"",
            passwd_nonce_addr && *passwd_nonce_addr? *passwd_nonce_addr:"",
            hexkeygrip);
  cn_parm.cache_nonce_addr = cache_nonce_addr;
  cn_parm.passwd_nonce_addr = passwd_nonce_addr;
  err = assuan_transact (agent_ctx, line, NULL, NULL,
                         default_inq_cb, &dfltparm,
                         cache_nonce_status_cb, &cn_parm);
  return err;
}
agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc,
              char **cache_nonce_addr, char **passwd_nonce_addr)
{
  gpg_error_t err;
  struct cache_nonce_parm_s cn_parm;
  char line[ASSUAN_LINELENGTH];
  struct default_inq_parm_s dfltparm;

  memset (&dfltparm, 0, sizeof dfltparm);
  dfltparm.ctrl = ctrl;

  err = start_agent (ctrl, 0);
  if (err)
    return err;
  dfltparm.ctx = agent_ctx;

  if (!hexkeygrip || strlen (hexkeygrip) != 40)
    return gpg_error (GPG_ERR_INV_VALUE);


  if (desc)
    {
      snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc);
      err = assuan_transact (agent_ctx, line,
                             NULL, NULL, NULL, NULL, NULL, NULL);
      if (err)
        return err;
    }

  snprintf (line, DIM(line)-1, "PASSWD %s%s %s%s %s",
            cache_nonce_addr && *cache_nonce_addr? "--cache-nonce=":"",
            cache_nonce_addr && *cache_nonce_addr? *cache_nonce_addr:"",
            passwd_nonce_addr && *passwd_nonce_addr? "--passwd-nonce=":"",
            passwd_nonce_addr && *passwd_nonce_addr? *passwd_nonce_addr:"",
            hexkeygrip);
  cn_parm.cache_nonce_addr = cache_nonce_addr;
  cn_parm.passwd_nonce_addr = passwd_nonce_addr;
  err = assuan_transact (agent_ctx, line, NULL, NULL,
                         default_inq_cb, &dfltparm,
                         cache_nonce_status_cb, &cn_parm);
  return err;
}