diff --git a/src/encrypt-sign.c b/src/encrypt-sign.c index e8272d8e..a168a786 100644 --- a/src/encrypt-sign.c +++ b/src/encrypt-sign.c @@ -56,6 +56,8 @@ encrypt_sym_status_handler (void *priv, gpgme_status_code_t code, char *args) err = _gpgme_sign_status_handler (priv, code, args); if (!err) err = _gpgme_passphrase_status_handler (priv, code, args); + if (!err) + err = _gpgme_encrypt_status_handler (priv, code, args); return err; } @@ -82,11 +84,11 @@ encrypt_sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[], if (recp && !*recp) return gpg_error (GPG_ERR_INV_VALUE); - err = _gpgme_op_encrypt_init_result (ctx); + err = _gpgme_op_encrypt_init_result (ctx, flags & GPGME_ENCRYPT_ARCHIVE); if (err) return err; - err = _gpgme_op_sign_init_result (ctx); + err = _gpgme_op_sign_init_result (ctx, 0); if (err) return err; diff --git a/src/encrypt.c b/src/encrypt.c index 241748cd..24132fda 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -49,6 +49,9 @@ typedef struct the list. This makes appending new invalid recipients painless while preserving the order. */ gpgme_invalid_key_t *lastp; + + /* Whether a SUCCESS status was seen. Emitted by gpgtar. */ + unsigned int success_seen:1; } *op_data_t; @@ -136,6 +139,8 @@ _gpgme_encrypt_status_handler (void *priv, gpgme_status_code_t code, return gpg_error (GPG_ERR_UNUSABLE_PUBKEY); if (opd->failure_code) return opd->failure_code; + if (!opd->success_seen) + return gpg_error (GPG_ERR_EOF); break; case GPGME_STATUS_KEY_CONSIDERED: @@ -164,6 +169,10 @@ _gpgme_encrypt_status_handler (void *priv, gpgme_status_code_t code, /* Should not happen, because we require at least one recipient. */ return gpg_error (GPG_ERR_GENERAL); + case GPGME_STATUS_SUCCESS: + opd->success_seen = 1; + break; + default: break; } @@ -179,6 +188,8 @@ encrypt_sym_status_handler (void *priv, gpgme_status_code_t code, char *args) err = _gpgme_progress_status_handler (priv, code, args); if (!err) err = _gpgme_passphrase_status_handler (priv, code, args); + if (!err) + err = _gpgme_encrypt_status_handler (priv, code, args); return err; } @@ -197,7 +208,7 @@ encrypt_status_handler (void *priv, gpgme_status_code_t code, char *args) gpgme_error_t -_gpgme_op_encrypt_init_result (gpgme_ctx_t ctx) +_gpgme_op_encrypt_init_result (gpgme_ctx_t ctx, int success_required) { gpgme_error_t err; void *hook; @@ -210,6 +221,7 @@ _gpgme_op_encrypt_init_result (gpgme_ctx_t ctx) return err; opd->lastp = &opd->result.invalid_recipients; + opd->success_seen = !success_required; return 0; } @@ -227,7 +239,7 @@ encrypt_start (gpgme_ctx_t ctx, int synchronous, gpgme_key_t recp[], if (err) return err; - err = _gpgme_op_encrypt_init_result (ctx); + err = _gpgme_op_encrypt_init_result (ctx, flags & GPGME_ENCRYPT_ARCHIVE); if (err) return err; diff --git a/src/ops.h b/src/ops.h index aa8d9c94..c82f8252 100644 --- a/src/ops.h +++ b/src/ops.h @@ -102,7 +102,8 @@ void _gpgme_signers_clear (gpgme_ctx_t ctx); /* Create an initial op data object for signing. Needs to be called once before calling _gpgme_sign_status_handler. */ -gpgme_error_t _gpgme_op_sign_init_result (gpgme_ctx_t ctx); +gpgme_error_t _gpgme_op_sign_init_result (gpgme_ctx_t ctx, + int success_required); /* Process a status line for signing operations. */ gpgme_error_t _gpgme_sign_status_handler (void *priv, @@ -114,7 +115,8 @@ gpgme_error_t _gpgme_sign_status_handler (void *priv, /* Create an initial op data object for encrypt. Needs to be called once before calling _gpgme_encrypt_status_handler. */ -gpgme_error_t _gpgme_op_encrypt_init_result (gpgme_ctx_t ctx); +gpgme_error_t _gpgme_op_encrypt_init_result (gpgme_ctx_t ctx, + int success_required); /* Process a status line for encryption operations. */ gpgme_error_t _gpgme_encrypt_status_handler (void *priv, diff --git a/src/sign.c b/src/sign.c index 56b2d5fb..5ef6a861 100644 --- a/src/sign.c +++ b/src/sign.c @@ -60,6 +60,8 @@ typedef struct unsigned int ignore_inv_recp:1; unsigned int inv_sgnr_seen:1; unsigned int sig_created_seen:1; + /* Whether a SUCCESS status was seen. Emitted by gpgtar. */ + unsigned int success_seen:1; } *op_data_t; @@ -377,6 +379,8 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args) else if (!opd->sig_created_seen && ctx->protocol != GPGME_PROTOCOL_UISERVER) err = opd->failure_code? opd->failure_code:gpg_error (GPG_ERR_GENERAL); + else if (!opd->success_seen) + err = opd->failure_code? opd->failure_code:gpg_error (GPG_ERR_EOF); break; case GPGME_STATUS_INQUIRE_MAXLEN: @@ -384,6 +388,10 @@ _gpgme_sign_status_handler (void *priv, gpgme_status_code_t code, char *args) err = ctx->status_cb (ctx->status_cb_value, "INQUIRE_MAXLEN", args); break; + case GPGME_STATUS_SUCCESS: + opd->success_seen = 1; + break; + default: break; } @@ -404,7 +412,7 @@ sign_status_handler (void *priv, gpgme_status_code_t code, char *args) static gpgme_error_t -sign_init_result (gpgme_ctx_t ctx, int ignore_inv_recp) +sign_init_result (gpgme_ctx_t ctx, int ignore_inv_recp, int success_required) { gpgme_error_t err; void *hook; @@ -421,13 +429,14 @@ sign_init_result (gpgme_ctx_t ctx, int ignore_inv_recp) opd->ignore_inv_recp = !!ignore_inv_recp; opd->inv_sgnr_seen = 0; opd->sig_created_seen = 0; + opd->success_seen = !success_required; return 0; } gpgme_error_t -_gpgme_op_sign_init_result (gpgme_ctx_t ctx) +_gpgme_op_sign_init_result (gpgme_ctx_t ctx, int success_required) { - return sign_init_result (ctx, 0); + return sign_init_result (ctx, 0, success_required); } @@ -444,7 +453,8 @@ sign_start (gpgme_ctx_t ctx, int synchronous, gpgme_data_t plain, /* If we are using the CMS protocol, we ignore the INV_RECP status code if a newer GPGSM is in use. GPGMS does not support combined sign+encrypt and thus this can't harm. */ - err = sign_init_result (ctx, (ctx->protocol == GPGME_PROTOCOL_CMS)); + err = sign_init_result (ctx, (ctx->protocol == GPGME_PROTOCOL_CMS), + flags & GPGME_SIG_MODE_ARCHIVE); if (err) return err;