From f9bf0d5b796c779312102a48997988048ceb485d Mon Sep 17 00:00:00 2001 From: Marcus Brinkmann Date: Sun, 17 Dec 2006 16:40:09 +0000 Subject: [PATCH] 2006-12-17 Marcus Brinkmann * engine.h (_gpgme_engine_new): Remove arguments lc_ctype and lc_messages from prototype. (_gpgme_engine_set_locale): New prototype. * engine.c (_gpgme_engine_set_locale): New function. * op-support.c (_gpgme_op_reset): Call _gpgme_engine_set_locale. * engine-backend.h (struct engine_ops): Add new member SET_LOCALE. Remove arguments lc_messages and lc_ctype from member NEW. * engine-gpgsm.c (struct engine_gpgsm): New members lc_ctype_set and lc_messages_set. (gpgsm_new): Remove lc_messages and lc_ctype arguments. (gpgsm_set_locale): New function. (_gpgme_engine_ops_gpgsm): Add gpgsm_set_locale. * rungpg.c (struct engine_gpg): Add new members lc_messages and lc_ctype. (gpg_release): Release lc_messages and lc_ctype if set. (gpg_new): Remove lc_messages and lc_ctype arguments. (gpg_set_locale): New function. (_gpgme_engine_ops_gpg): Add gpg_set_locale. (add_arg): Implement in terms of: (add_arg_ext): New function. (start): Set lc-messages and lc-ctype arguments here. --- gpgme/ChangeLog | 25 +++++++++ gpgme/engine-backend.h | 4 +- gpgme/engine-gpgsm.c | 83 +++++++++++++++++------------ gpgme/engine.c | 22 ++++++-- gpgme/engine.h | 8 +-- gpgme/op-support.c | 15 +++++- gpgme/rungpg.c | 115 ++++++++++++++++++++++++++++++++--------- 7 files changed, 202 insertions(+), 70 deletions(-) diff --git a/gpgme/ChangeLog b/gpgme/ChangeLog index 9a460ea..fea3b67 100644 --- a/gpgme/ChangeLog +++ b/gpgme/ChangeLog @@ -1,3 +1,28 @@ +2006-12-17 Marcus Brinkmann + + * engine.h (_gpgme_engine_new): Remove arguments lc_ctype and + lc_messages from prototype. + (_gpgme_engine_set_locale): New prototype. + * engine.c (_gpgme_engine_set_locale): New function. + * op-support.c (_gpgme_op_reset): Call _gpgme_engine_set_locale. + * engine-backend.h (struct engine_ops): Add new member SET_LOCALE. + Remove arguments lc_messages and lc_ctype from member NEW. + * engine-gpgsm.c (struct engine_gpgsm): New members lc_ctype_set + and lc_messages_set. + (gpgsm_new): Remove lc_messages and lc_ctype + arguments. + (gpgsm_set_locale): New function. + (_gpgme_engine_ops_gpgsm): Add gpgsm_set_locale. + * rungpg.c (struct engine_gpg): Add new members lc_messages and + lc_ctype. + (gpg_release): Release lc_messages and lc_ctype if set. + (gpg_new): Remove lc_messages and lc_ctype arguments. + (gpg_set_locale): New function. + (_gpgme_engine_ops_gpg): Add gpg_set_locale. + (add_arg): Implement in terms of: + (add_arg_ext): New function. + (start): Set lc-messages and lc-ctype arguments here. + 2006-12-03 Marcus Brinkmann * engine-gpgsm.c (struct engine_gpgsm): Move members diff --git a/gpgme/engine-backend.h b/gpgme/engine-backend.h index 27fadbc..eed8ffd 100644 --- a/gpgme/engine-backend.h +++ b/gpgme/engine-backend.h @@ -45,8 +45,7 @@ struct engine_ops const char *(*get_req_version) (void); gpgme_error_t (*new) (void **r_engine, - const char *file_name, const char *home_dir, - const char *lc_ctype, const char *lc_messages); + const char *file_name, const char *home_dir); /* Member functions. */ void (*release) (void *engine); @@ -58,6 +57,7 @@ struct engine_ops gpgme_error_t (*set_colon_line_handler) (void *engine, engine_colon_line_handler_t fnc, void *fnc_value); + gpgme_error_t (*set_locale) (void *engine, int category, const char *value); gpgme_error_t (*decrypt) (void *engine, gpgme_data_t ciph, gpgme_data_t plain); gpgme_error_t (*delete) (void *engine, gpgme_key_t key, int allow_secret); diff --git a/gpgme/engine-gpgsm.c b/gpgme/engine-gpgsm.c index 73e6ef8..766323a 100644 --- a/gpgme/engine-gpgsm.c +++ b/gpgme/engine-gpgsm.c @@ -62,6 +62,9 @@ struct engine_gpgsm { assuan_context_t assuan_ctx; + int lc_ctype_set; + int lc_messages_set; + iocb_data_t status_cb; /* Input, output etc are from the servers perspective. */ @@ -317,8 +320,7 @@ gpgsm_release (void *engine) static gpgme_error_t -gpgsm_new (void **engine, const char *file_name, const char *home_dir, - const char *lc_ctype, const char *lc_messages) +gpgsm_new (void **engine, const char *file_name, const char *home_dir) { gpgme_error_t err = 0; engine_gpgsm_t gpgsm; @@ -516,38 +518,6 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir, } } - if (lc_ctype) - { - if (asprintf (&optstr, "OPTION lc-ctype=%s", lc_ctype) < 0) - err = gpg_error_from_errno (errno); - else - { - err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, - NULL, NULL, NULL, NULL); - free (optstr); - if (err) - err = map_assuan_error (err); - } - } - if (err) - goto leave; - - if (lc_messages) - { - if (asprintf (&optstr, "OPTION lc-messages=%s", lc_messages) < 0) - err = gpg_error_from_errno (errno); - else - { - err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, - NULL, NULL, NULL, NULL); - free (optstr); - if (err) - err = map_assuan_error (err); - } - } - if (err) - goto leave; - if (!err && (_gpgme_io_set_close_notify (gpgsm->status_cb.fd, close_notify_handler, gpgsm))) @@ -591,6 +561,50 @@ gpgsm_new (void **engine, const char *file_name, const char *home_dir, } +static gpgme_error_t +gpgsm_set_locale (void *engine, int category, const char *value) +{ + engine_gpgsm_t gpgsm = engine; + gpgme_error_t err; + char *optstr; + char *catstr; + + /* FIXME: If value is NULL, we need to reset the option to default. + But we can't do this. So we error out here. GPGSM needs support + for this. */ + if (category == LC_CTYPE) + { + catstr = "lc-ctype"; + if (!value && gpgsm->lc_ctype_set) + return gpg_error (GPG_ERR_INV_VALUE); + if (value) + gpgsm->lc_ctype_set = 1; + } + else if (category == LC_MESSAGES) + { + catstr = "lc-messages"; + if (!value && gpgsm->lc_messages_set) + return gpg_error (GPG_ERR_INV_VALUE); + if (value) + gpgsm->lc_messages_set = 1; + } + else + return gpg_error (GPG_ERR_INV_VALUE); + + if (asprintf (&optstr, "OPTION %s=%s", catstr, value) < 0) + err = gpg_error_from_errno (errno); + else + { + err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, + NULL, NULL, NULL, NULL); + free (optstr); + if (err) + err = map_assuan_error (err); + } + return err; +} + + /* Forward declaration. */ static gpgme_status_code_t parse_status (const char *name); @@ -1693,6 +1707,7 @@ struct engine_ops _gpgme_engine_ops_gpgsm = gpgsm_set_status_handler, NULL, /* set_command_handler */ gpgsm_set_colon_line_handler, + gpgsm_set_locale, gpgsm_decrypt, gpgsm_delete, NULL, /* edit */ diff --git a/gpgme/engine.c b/gpgme/engine.c index a7ca624..dd89c2d 100644 --- a/gpgme/engine.c +++ b/gpgme/engine.c @@ -389,8 +389,7 @@ gpgme_set_engine_info (gpgme_protocol_t proto, gpgme_error_t -_gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine, - const char *lc_ctype, const char *lc_messages) +_gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine) { engine_t engine; @@ -404,9 +403,9 @@ _gpgme_engine_new (gpgme_engine_info_t info, engine_t *r_engine, engine->ops = engine_ops[info->protocol]; if (engine->ops->new) { - gpgme_error_t err = (*engine->ops->new) (&engine->engine, - info->file_name, info->home_dir, - lc_ctype, lc_messages); + gpgme_error_t err; + err = (*engine->ops->new) (&engine->engine, + info->file_name, info->home_dir); if (err) { free (engine); @@ -476,6 +475,19 @@ _gpgme_engine_set_colon_line_handler (engine_t engine, fnc, fnc_value); } +gpgme_error_t +_gpgme_engine_set_locale (engine_t engine, int category, + const char *value) +{ + if (!engine) + return gpg_error (GPG_ERR_INV_VALUE); + + if (!engine->ops->set_locale) + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + return (*engine->ops->set_locale) (engine->engine, category, value); +} + gpgme_error_t _gpgme_engine_op_decrypt (engine_t engine, gpgme_data_t ciph, gpgme_data_t plain) diff --git a/gpgme/engine.h b/gpgme/engine.h index be9c9b7..893e591 100644 --- a/gpgme/engine.h +++ b/gpgme/engine.h @@ -51,9 +51,11 @@ gpgme_error_t _gpgme_set_engine_info (gpgme_engine_info_t info, gpgme_error_t _gpgme_engine_new (gpgme_engine_info_t info, - engine_t *r_engine, - const char *lc_ctype, - const char *lc_messages); + engine_t *r_engine); + +gpgme_error_t _gpgme_engine_set_locale (engine_t engine, int category, + const char *value); + void _gpgme_engine_release (engine_t engine); void _gpgme_engine_set_status_handler (engine_t engine, engine_status_handler_t fnc, diff --git a/gpgme/op-support.c b/gpgme/op-support.c index 68ff77d..8a42851 100644 --- a/gpgme/op-support.c +++ b/gpgme/op-support.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "gpgme.h" #include "context.h" @@ -86,11 +87,21 @@ _gpgme_op_reset (gpgme_ctx_t ctx, int type) } /* Create an engine object. */ - err = _gpgme_engine_new (info, &ctx->engine, - ctx->lc_ctype, ctx->lc_messages); + err = _gpgme_engine_new (info, &ctx->engine); if (err) return err; + err = _gpgme_engine_set_locale (ctx->engine, LC_CTYPE, ctx->lc_ctype); + if (!err) + err = _gpgme_engine_set_locale (ctx->engine, + LC_MESSAGES, ctx->lc_messages); + if (err) + { + _gpgme_engine_release (ctx->engine); + ctx->engine = NULL; + return err; + } + if (type == 1 || (type == 2 && !ctx->io_cbs.add)) { /* Use private event loop. */ diff --git a/gpgme/rungpg.c b/gpgme/rungpg.c index 3907c3f..f3326b3 100644 --- a/gpgme/rungpg.c +++ b/gpgme/rungpg.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "gpgme.h" #include "util.h" @@ -72,6 +73,9 @@ struct engine_gpg { char *file_name; + char *lc_messages; + char *lc_ctype; + struct arg_and_data_s *arglist; struct arg_and_data_s **argtail; @@ -181,8 +185,10 @@ close_notify_handler (int fd, void *opaque) } } +/* If FRONT is true, push at the front of the list. Use this for + options added late in the process. */ static gpgme_error_t -add_arg (engine_gpg_t gpg, const char *arg) +add_arg_ext (engine_gpg_t gpg, const char *arg, int front) { struct arg_and_data_s *a; @@ -192,15 +198,37 @@ add_arg (engine_gpg_t gpg, const char *arg) a = malloc (sizeof *a + strlen (arg)); if (!a) return gpg_error_from_errno (errno); - a->next = NULL; + a->data = NULL; a->dup_to = -1; strcpy (a->arg, arg); - *gpg->argtail = a; - gpg->argtail = &a->next; + if (front) + { + a->next = gpg->arglist; + if (!gpg->arglist) + { + /* If this is the first argument, we need to update the tail + pointer. */ + gpg->argtail = &a->next; + } + gpg->arglist = a; + } + else + { + a->next = NULL; + *gpg->argtail = a; + gpg->argtail = &a->next; + } + return 0; } +static gpgme_error_t +add_arg (engine_gpg_t gpg, const char *arg) +{ + return add_arg_ext (gpg, arg, 0); +} + static gpgme_error_t add_data (engine_gpg_t gpg, gpgme_data_t data, int dup_to, int inbound) { @@ -317,6 +345,11 @@ gpg_release (void *engine) if (gpg->file_name) free (gpg->file_name); + if (gpg->lc_messages) + free (gpg->lc_messages); + if (gpg->lc_ctype) + free (gpg->lc_ctype); + while (gpg->arglist) { struct arg_and_data_s *next = gpg->arglist->next; @@ -340,8 +373,7 @@ gpg_release (void *engine) static gpgme_error_t -gpg_new (void **engine, const char *file_name, const char *home_dir, - const char *lc_ctype, const char *lc_messages) +gpg_new (void **engine, const char *file_name, const char *home_dir) { engine_gpg_t gpg; gpgme_error_t rc = 0; @@ -468,24 +500,6 @@ gpg_new (void **engine, const char *file_name, const char *home_dir, goto leave; } - if (lc_ctype) - { - rc = add_arg (gpg, "--lc-ctype"); - if (!rc) - rc = add_arg (gpg, lc_ctype); - if (rc) - goto leave; - } - - if (lc_messages) - { - rc = add_arg (gpg, "--lc-messages"); - if (!rc) - rc = add_arg (gpg, lc_messages); - if (rc) - goto leave; - } - leave: if (rc) gpg_release (gpg); @@ -495,6 +509,40 @@ gpg_new (void **engine, const char *file_name, const char *home_dir, } +static gpgme_error_t +gpg_set_locale (void *engine, int category, const char *value) +{ + engine_gpg_t gpg = engine; + + if (category == LC_CTYPE) + { + if (gpg->lc_ctype) + free (gpg->lc_ctype); + if (value) + { + gpg->lc_ctype = strdup (value); + if (!gpg->lc_ctype) + return gpg_error_from_syserror (); + } + } + else if (category == LC_MESSAGES) + { + if (gpg->lc_messages) + free (gpg->lc_messages); + if (value) + { + gpg->lc_messages = strdup (value); + if (!gpg->lc_messages) + return gpg_error_from_syserror (); + } + } + else + return gpg_error (GPG_ERR_INV_VALUE); + + return 0; +} + + /* Note, that the status_handler is allowed to modifiy the args value. */ static void @@ -1163,6 +1211,24 @@ start (engine_gpg_t gpg) if (!gpg->file_name && !_gpgme_get_gpg_path ()) return gpg_error (GPG_ERR_INV_ENGINE); + if (gpg->lc_ctype) + { + rc = add_arg_ext (gpg, gpg->lc_ctype, 1); + if (!rc) + rc = add_arg_ext (gpg, "--lc-ctype", 1); + if (rc) + return rc; + } + + if (gpg->lc_messages) + { + rc = add_arg_ext (gpg, gpg->lc_messages, 1); + if (!rc) + rc = add_arg_ext (gpg, "--lc-messages", 1); + if (rc) + return rc; + } + rc = build_argv (gpg); if (rc) return rc; @@ -2015,6 +2081,7 @@ struct engine_ops _gpgme_engine_ops_gpg = gpg_set_status_handler, gpg_set_command_handler, gpg_set_colon_line_handler, + gpg_set_locale, gpg_decrypt, gpg_delete, gpg_edit, -- 2.26.2