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.
This commit is contained in:
Marcus Brinkmann 2006-12-17 16:40:09 +00:00
parent ba58b21408
commit f9bf0d5b79
7 changed files with 202 additions and 70 deletions

View File

@ -1,3 +1,28 @@
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

View File

@ -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);

View File

@ -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 */

View File

@ -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)

View File

@ -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,

View File

@ -24,6 +24,7 @@
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <locale.h>
#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. */

View File

@ -28,6 +28,7 @@
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#include <locale.h>
#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,