/* delete.c - Delete a key. Copyright (C) 2001, 2002, 2003, 2004 g10 Code GmbH This file is part of GPGME. GPGME is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. GPGME 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #if HAVE_CONFIG_H #include #endif #include #include #include "debug.h" #include "gpgme.h" #include "context.h" #include "ops.h" static gpgme_error_t delete_status_handler (void *priv, gpgme_status_code_t code, char *args) { (void)priv; if (code == GPGME_STATUS_DELETE_PROBLEM) { enum delete_problem { DELETE_No_Problem = 0, DELETE_No_Such_Key = 1, DELETE_Must_Delete_Secret_Key = 2, DELETE_Ambiguous_Specification = 3 }; long problem; char *tail; gpg_err_set_errno (0); problem = strtol (args, &tail, 0); if (errno || (*tail && *tail != ' ')) return trace_gpg_error (GPG_ERR_INV_ENGINE); switch (problem) { case DELETE_No_Problem: break; case DELETE_No_Such_Key: return gpg_error (GPG_ERR_NO_PUBKEY); case DELETE_Must_Delete_Secret_Key: return gpg_error (GPG_ERR_CONFLICT); case DELETE_Ambiguous_Specification: return gpg_error (GPG_ERR_AMBIGUOUS_NAME); } return gpg_error (GPG_ERR_GENERAL); } else if (code == GPGME_STATUS_ERROR) { /* Some error stati are informational, so we don't return an error code if we are not ready to process this status. */ gpgme_error_t err; char *where = strchr (args, ' '); char *which; if (where) { *where = '\0'; which = where + 1; where = strchr (which, ' '); if (where) *where = '\0'; where = args; } else return trace_gpg_error (GPG_ERR_INV_ENGINE); err = atoi (which); if (!strcmp (where, "delete_key.secret") && (gpg_err_code (err) == GPG_ERR_CANCELED || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)) { /* This indicates a user cancellation on the confirmation dialog. */ return gpg_error (gpg_err_code (err)); } } return 0; } static gpgme_error_t delete_start (gpgme_ctx_t ctx, int synchronous, const gpgme_key_t key, unsigned int flags) { gpgme_error_t err; err = _gpgme_op_reset (ctx, synchronous); if (err) return err; _gpgme_engine_set_status_handler (ctx->engine, delete_status_handler, ctx); return _gpgme_engine_op_delete (ctx->engine, key, flags); } /* Delete KEY from the keyring. If ALLOW_SECRET is non-zero, secret keys are also deleted. */ gpgme_error_t gpgme_op_delete_start (gpgme_ctx_t ctx, const gpgme_key_t key, int allow_secret) { gpgme_error_t err; TRACE_BEG (DEBUG_CTX, "gpgme_op_delete_start", ctx, "key=%p (%s), allow_secret=%i", key, (key->subkeys && key->subkeys->fpr) ? key->subkeys->fpr : "invalid", allow_secret); if (!ctx) return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); err = delete_start (ctx, 0, key, allow_secret ? GPGME_DELETE_ALLOW_SECRET : 0); return TRACE_ERR (err); } /* Delete KEY from the keyring. If ALLOW_SECRET is non-zero, secret keys are also deleted. */ gpgme_error_t gpgme_op_delete (gpgme_ctx_t ctx, const gpgme_key_t key, int allow_secret) { gpgme_error_t err; TRACE_BEG (DEBUG_CTX, "gpgme_op_delete", ctx, "key=%p (%s), allow_secret=%i", key, (key->subkeys && key->subkeys->fpr) ? key->subkeys->fpr : "invalid", allow_secret); if (!ctx) return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); err = delete_start (ctx, 1, key, allow_secret ? GPGME_DELETE_ALLOW_SECRET : 0); if (!err) err = _gpgme_wait_one (ctx); return err; } /* Delete KEY from the keyring. */ gpgme_error_t gpgme_op_delete_ext_start (gpgme_ctx_t ctx, const gpgme_key_t key, unsigned int flags) { gpgme_error_t err; TRACE_BEG (DEBUG_CTX, "gpgme_op_delete_ext_start", ctx, "key=%p (%s), flags=0x%x", key, (key->subkeys && key->subkeys->fpr) ? key->subkeys->fpr : "invalid", flags); if (!ctx) return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); err = delete_start (ctx, 0, key, flags); return TRACE_ERR (err); } /* Delete KEY from the keyring. */ gpgme_error_t gpgme_op_delete_ext (gpgme_ctx_t ctx, const gpgme_key_t key, unsigned int flags) { gpgme_error_t err; TRACE_BEG (DEBUG_CTX, "gpgme_op_delete_ext", ctx, "key=%p (%s), flags=0x%x", key, (key->subkeys && key->subkeys->fpr) ? key->subkeys->fpr : "invalid", flags); if (!ctx) return TRACE_ERR (gpg_error (GPG_ERR_INV_VALUE)); err = delete_start (ctx, 1, key, flags); if (!err) err = _gpgme_wait_one (ctx); return err; }