+2006-12-17 Marcus Brinkmann <marcus@g10code.de>
+
+ * 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 <marcus@g10code.de>
* engine-gpgsm.c (struct engine_gpgsm): Move members
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);
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);
{
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. */
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;
}
}
- 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)))
}
+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);
gpgsm_set_status_handler,
NULL, /* set_command_handler */
gpgsm_set_colon_line_handler,
+ gpgsm_set_locale,
gpgsm_decrypt,
gpgsm_delete,
NULL, /* edit */
\f
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;
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);
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)
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,
#include <stdlib.h>
#include <errno.h>
#include <string.h>
+#include <locale.h>
#include "gpgme.h"
#include "context.h"
}
/* 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. */
#include <assert.h>
#include <errno.h>
#include <unistd.h>
+#include <locale.h>
#include "gpgme.h"
#include "util.h"
{
char *file_name;
+ char *lc_messages;
+ char *lc_ctype;
+
struct arg_and_data_s *arglist;
struct arg_and_data_s **argtail;
}
}
+/* 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;
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)
{
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;
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;
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);
}
+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
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;
gpg_set_status_handler,
gpg_set_command_handler,
gpg_set_colon_line_handler,
+ gpg_set_locale,
gpg_decrypt,
gpg_delete,
gpg_edit,