2002-06-10 Marcus Brinkmann <marcus@g10code.de>
* engine-gpgsm.c (_gpgme_gpgsm_start): Move the code that sets the close notification for the status fd to ... (_gpgme_gpgsm_new): ... here. * wait.h: Include "sema.h". Remove prototypes of _gpgme_remove_proc_from_wait_queue and _gpgme_register_pipe_handler. Add prototypes of _gpgme_fd_table_init, _gpgme_fd_table_deinit, _gpgme_fd_table_put, _gpgme_add_io_cb, _gpgme_remove_io_cb, _gpgme_wait_event_cb and _gpgme_wait_one.. * wait.c: Remove global variables PROC_QUEUE, PROC_QUEUE_LOCK, FD_TABLE_SIZE, FD_TABLE, FD_TABLE_LOCK. New global variables FDT_GLOBAL, CTX_DONE_LIST, CTX_DONE_LIST_SIZE, CTX_DONE_LIST_LENGTH and CTX_DONE_LIST_LOCK. Remove struct proc_s. Replace struct wait_item_s. (_gpgme_fd_table_init): New function. (_gpgme_fd_table_deinit): Likewise. (_gpgme_fd_table_put): Likewise. (set_process_done): Remove function. (do_select): Take argument FDT. Use that to decide which fds to select on. (_gpgme_remove_proc_from_wait_queue): Remove function. (_gpgme_wait_event_cb): New function. (_gpgme_wait_one): Likewise. (_gpgme_register_pipe_hanldler): Remove function. (_gpgme_add_io_cb): New function. (_gpgme_remove_io_cb): Likewise. (_gpgme_freeze_fd): Remove function. (_gpgme_thaw_fd): Remove function. * rungpg.c (struct fd_data_map_s): Add new member TAG. (struct gpg_object_s): Likewise for STATUS and COLON. Add member IDX to CMD. Add new member IO_CBS. (close_notify_handler): New variables POSSIBLY_DONE and NOT_DONE. For each I/O callback, check if it should be unregistered. If all callbacks have been unregistered, trigger GPGME_EVENT_DONE. Remove member RUNNING. (_gpgme_gpg_new): Initialize new members. (_gpgme_gpg_release): Check PID not RUNNING. Don't call _gpgme_remove_proc_from_wait_queue. Close GPG->CMD.FD if set. (build_argv): Store away the index instead the file descriptor for CMD. (_gpgme_gpg_add_io_cb): New function. (_gpgme_gpg_spawn): Use _gpgme_gpg_add_io_cb to register IO callbacks. (gpg_status_handler): Change return type to void, remove PID argument, close filedescriptor if EOF or error occurs. (read_status): Use _gpgme_gpg_add_io_cb instead _gpgme_thaw_fd. Use IO_CBS->remove instead _gpgme_freeze_fd. (gpg_colon_line_handler): Change return type to void, remove PID argument, close filedescriptor if EOF or error occurs. (command_cb): Use IO_CBS->remove instead _gpgme_freeze_fd. (_gpgme_gpg_set_io_cbs): New function. * rungpg.h (_gpgme_gpg_set_io_cbs): Prototype for _gpgme_gpg_set_io_cbs. * gpgme.h (GpgmeIOCb): New type. (GpgmeRegisterIOCb): Likewise. (GpgmeRemoveIOCb): Likewise. (GpgmeEventIO): Likewise. (GpgmeEventIOCb): Likewise. (struct GpgmeIOCbs): New structure to hold I/O callbacks. (gpgme_set_op_io_cbs): New prototype. (gpgme_get_op_io_cbs): Likewise. * ops.h: New prototype for _gpgme_op_event_cb. Remove prototypes for _gpgme_freeze_fd and _gpgme_thaw_fd. Remove PID argument from _gpgme_data_inbound_handler and _gpgme_data_outbound_handler prototype. Add prototype for _gpgme_op_reset. Add synchronous argument to _gpgme_decrypt_start prototype. * io.h: Beautification. * gpgme.c: Include "wait.h". (gpgme_new): Initialize FDT. (gpgme_set_io_cbs): New function. (gpgme_get_io_cbs): Likewise. (_gpgme_op_event_cb): Likewise. * data.c (_gpgme_data_inbound_handler): Change return type to void. Drop PID argument. Close FD on error and EOF. (write_mem_data): Don't close FD here ... (write_cb_data): ... or here ... (_gpgme_data_outbound_handler): ... but here. Change return type to void. Drop PID argument. * context.h: Include "wait.h". (struct gpgme_context_s): New members FDT and IO_CBS. * op-support.c: New file. * Makefile.am (libgpgme_la_SOURCES): Add op-support.c. * ops.h: Add prototype for _gpgme_op_reset(). * decrypt.c (_gpgme_decrypt_start): New argument SYNCHRONOUS. Use _gpgme_op_reset. (gpgme_op_decrypt_start): Add synchronous argument. (gpgme_op_decrypt): Likewise. Use _gpgme_wait_one instead gpgme_wait. * delete.c (gpgme_op_delete_start): Rename to ... (_gpgme_op_delete_start): ... this. New argument SYNCHRONOUS. Use _gpgme_op_reset. Make function static. (gpgme_op_delete_start): Just a wrapper around _gpgme_op_delete_start now. (gpgme_op_delete): Add synchronous argument. Use _gpgme_wait_one instead gpgme_wait. * encrypt.c: Include "wait.h". (ggpgme_op_encrypt_start): Rename to ... (_gpgme_op_encrypt_start): ... this. New argument SYNCHRONOUS. Use _gpgme_op_reset. Make function static. (gpgme_op_encrypt_start): Just a wrapper around _gpgme_op_encrypt_start now. (gpgme_op_encrypt): Add synchronous argument. Use _gpgme_wait_one instead gpgme_wait. * encrypt_sign.c (gpgme_op_encrypt_sign_start): Rename to ... (_gpgme_op_encrypt_sign_start): ... this. New argument SYNCHRONOUS. Use _gpgme_op_reset. Make function static. (gpgme_op_encrypt_sign_start): Just a wrapper around _gpgme_op_encrypt_sign_start now. (gpgme_op_encrypt_sign): Add synchronous argument. Use _gpgme_wait_one instead gpgme_wait. * export.c (gpgme_op_export_start): Rename to ... (_gpgme_op_export_start): ... this. New argument SYNCHRONOUS. Use _gpgme_op_reset. Make function static. (gpgme_op_export_start): Just a wrapper around _gpgme_op_export_start now. (gpgme_op_export): Add synchronous argument. Use _gpgme_wait_one instead gpgme_wait. * genkey.c (gpgme_op_genkey_start): Rename to ... (_gpgme_op_genkey_start): ... this. New argument SYNCHRONOUS. Use _gpgme_op_reset. Make function static. (gpgme_op_genkey_start): Just a wrapper around _gpgme_op_genkey_start now. (gpgme_op_genkey): Add synchronous argument. Use _gpgme_wait_one instead gpgme_wait. * import.c (gpgme_op_import_start): Rename to ... (_gpgme_op_import_start): ... this. New argument SYNCHRONOUS. Use _gpgme_op_reset. Make function static. (gpgme_op_import_start): Just a wrapper around _gpgme_op_import_start now. (gpgme_op_import): Add synchronous argument. Use _gpgme_wait_one instead gpgme_wait. * keylist.c (gpgme_op_keylist_start): Use _gpgme_op_reset. (gpgme_op_keylist_ext_start): Likewise. * sign.c (gpgme_op_sign_start): Rename to ... (_gpgme_op_sign_start): ... this. New argument SYNCHRONOUS. Use _gpgme_op_reset. Make function static. (gpgme_op_sign_start): Just a wrapper around _gpgme_op_sign_start now. (gpgme_op_sign): Add synchronous argument. Use _gpgme_wait_one instead gpgme_wait. * trustlist.c (gpgme_op_trustlist_start): Use _gpgme_op_reset. * verify.c (gpgme_op_verify_start): Rename to ... (_gpgme_op_verify_start): ... this. New argument SYNCHRONOUS. Use _gpgme_op_reset. Make function static. (gpgme_op_verify_start): Just a wrapper around _gpgme_op_verify_start now. (gpgme_op_verify): Add synchronous argument. Use _gpgme_wait_one instead gpgme_wait. * engine-gpgsm.c (iocb_data_t): New type. (struct gpgsm_object_s): New member status_cb. Replace input_fd and input_data with input_cb. Replace output_fd and output_data with output_cb. Replace message_fd and message_data with message_cb. New member io_cbs. (_gpgme_gpgsm_new): Initialize all new members (and drop the old ones). (close_notify_handler): New variable POSSIBLY_DONE. For each I/O callback, check if it should be unregistered. If all callbacks have been unregistered, trigger GPGME_EVENT_DONE. (_gpgme_gpgsm_release): Remove variable PID. Use new variable names to close the file descriptors. (_gpgme_gpgsm_op_decrypt): Use new variable names, (_gpgme_gpgsm_op_encrypt): Likewise. (_gpgme_gpgsm_op_genkey): Likewise. (_gpgme_gpgsm_op_import): Likewise. (_gpgme_gpgsm_op_keylist): Likewise. (_gpgme_gpgsm_op_keylist_ext): Likewise. (_gpgme_gpgsm_op_sign): Likewise. (_gpgme_gpgsm_op_verify): Likewise. (gpgsm_status_handler): Drop argument PID. Change return type to void. Close status pipe before returning because of EOF or error. (_gpgme_gpgsm_add_io_cb): New function. (_gpgme_gpgsm_start): Use _gpgme_gpgsm_add_io_cb to register callback function. (_gpgme_gpgsm_set_io_cbs): New function. * engine-gpgsm.h: New prototype for _gpgme_gpgsm_set_io_cbs. * engine.c (_gpgme_engine_set_io_cbs): New function. * engine.h: New prototype for _gpgme_engine_set_io_cbs.
This commit is contained in:
parent
7b8ab474d3
commit
5b75138331
180
gpgme/ChangeLog
180
gpgme/ChangeLog
@ -1,3 +1,183 @@
|
||||
2002-06-10 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* engine-gpgsm.c (_gpgme_gpgsm_start): Move the code that sets the
|
||||
close notification for the status fd to ...
|
||||
(_gpgme_gpgsm_new): ... here.
|
||||
* wait.h: Include "sema.h". Remove prototypes of
|
||||
_gpgme_remove_proc_from_wait_queue and
|
||||
_gpgme_register_pipe_handler. Add prototypes of
|
||||
_gpgme_fd_table_init, _gpgme_fd_table_deinit, _gpgme_fd_table_put,
|
||||
_gpgme_add_io_cb, _gpgme_remove_io_cb, _gpgme_wait_event_cb and
|
||||
_gpgme_wait_one..
|
||||
* wait.c: Remove global variables PROC_QUEUE, PROC_QUEUE_LOCK,
|
||||
FD_TABLE_SIZE, FD_TABLE, FD_TABLE_LOCK. New global variables
|
||||
FDT_GLOBAL, CTX_DONE_LIST, CTX_DONE_LIST_SIZE,
|
||||
CTX_DONE_LIST_LENGTH and CTX_DONE_LIST_LOCK. Remove struct
|
||||
proc_s. Replace struct wait_item_s.
|
||||
(_gpgme_fd_table_init): New function.
|
||||
(_gpgme_fd_table_deinit): Likewise.
|
||||
(_gpgme_fd_table_put): Likewise.
|
||||
(set_process_done): Remove function.
|
||||
(do_select): Take argument FDT. Use that to decide which fds to
|
||||
select on.
|
||||
(_gpgme_remove_proc_from_wait_queue): Remove function.
|
||||
(_gpgme_wait_event_cb): New function.
|
||||
(_gpgme_wait_one): Likewise.
|
||||
(_gpgme_register_pipe_hanldler): Remove function.
|
||||
(_gpgme_add_io_cb): New function.
|
||||
(_gpgme_remove_io_cb): Likewise.
|
||||
(_gpgme_freeze_fd): Remove function.
|
||||
(_gpgme_thaw_fd): Remove function.
|
||||
* rungpg.c (struct fd_data_map_s): Add new member TAG.
|
||||
(struct gpg_object_s): Likewise for STATUS and COLON. Add member
|
||||
IDX to CMD. Add new member IO_CBS.
|
||||
(close_notify_handler): New variables POSSIBLY_DONE and NOT_DONE.
|
||||
For each I/O callback, check if it should be unregistered. If all
|
||||
callbacks have been unregistered, trigger GPGME_EVENT_DONE.
|
||||
Remove member RUNNING.
|
||||
(_gpgme_gpg_new): Initialize new members.
|
||||
(_gpgme_gpg_release): Check PID not RUNNING. Don't call
|
||||
_gpgme_remove_proc_from_wait_queue. Close GPG->CMD.FD if set.
|
||||
(build_argv): Store away the index instead the file descriptor for
|
||||
CMD.
|
||||
(_gpgme_gpg_add_io_cb): New function.
|
||||
(_gpgme_gpg_spawn): Use _gpgme_gpg_add_io_cb to register IO
|
||||
callbacks.
|
||||
(gpg_status_handler): Change return type to void, remove PID
|
||||
argument, close filedescriptor if EOF or error occurs.
|
||||
(read_status): Use _gpgme_gpg_add_io_cb instead _gpgme_thaw_fd.
|
||||
Use IO_CBS->remove instead _gpgme_freeze_fd.
|
||||
(gpg_colon_line_handler): Change return type to void, remove PID
|
||||
argument, close filedescriptor if EOF or error occurs.
|
||||
(command_cb): Use IO_CBS->remove instead _gpgme_freeze_fd.
|
||||
(_gpgme_gpg_set_io_cbs): New function.
|
||||
* rungpg.h (_gpgme_gpg_set_io_cbs): Prototype for
|
||||
_gpgme_gpg_set_io_cbs.
|
||||
* gpgme.h (GpgmeIOCb): New type.
|
||||
(GpgmeRegisterIOCb): Likewise.
|
||||
(GpgmeRemoveIOCb): Likewise.
|
||||
(GpgmeEventIO): Likewise.
|
||||
(GpgmeEventIOCb): Likewise.
|
||||
(struct GpgmeIOCbs): New structure to hold I/O callbacks.
|
||||
(gpgme_set_op_io_cbs): New prototype.
|
||||
(gpgme_get_op_io_cbs): Likewise.
|
||||
* ops.h: New prototype for _gpgme_op_event_cb. Remove prototypes
|
||||
for _gpgme_freeze_fd and _gpgme_thaw_fd. Remove PID argument from
|
||||
_gpgme_data_inbound_handler and _gpgme_data_outbound_handler
|
||||
prototype. Add prototype for _gpgme_op_reset.
|
||||
Add synchronous argument to _gpgme_decrypt_start prototype.
|
||||
* io.h: Beautification.
|
||||
* gpgme.c: Include "wait.h".
|
||||
(gpgme_new): Initialize FDT.
|
||||
(gpgme_set_io_cbs): New function.
|
||||
(gpgme_get_io_cbs): Likewise.
|
||||
(_gpgme_op_event_cb): Likewise.
|
||||
* data.c (_gpgme_data_inbound_handler): Change return type to
|
||||
void. Drop PID argument. Close FD on error and EOF.
|
||||
(write_mem_data): Don't close FD here ...
|
||||
(write_cb_data): ... or here ...
|
||||
(_gpgme_data_outbound_handler): ... but here. Change return type
|
||||
to void. Drop PID argument.
|
||||
* context.h: Include "wait.h".
|
||||
(struct gpgme_context_s): New members FDT and IO_CBS.
|
||||
* op-support.c: New file.
|
||||
* Makefile.am (libgpgme_la_SOURCES): Add op-support.c.
|
||||
* ops.h: Add prototype for _gpgme_op_reset().
|
||||
* decrypt.c (_gpgme_decrypt_start): New argument SYNCHRONOUS. Use
|
||||
_gpgme_op_reset.
|
||||
(gpgme_op_decrypt_start): Add synchronous argument.
|
||||
(gpgme_op_decrypt): Likewise. Use _gpgme_wait_one instead
|
||||
gpgme_wait.
|
||||
* delete.c (gpgme_op_delete_start): Rename to ...
|
||||
(_gpgme_op_delete_start): ... this. New argument SYNCHRONOUS.
|
||||
Use _gpgme_op_reset. Make function static.
|
||||
(gpgme_op_delete_start): Just a wrapper around
|
||||
_gpgme_op_delete_start now.
|
||||
(gpgme_op_delete): Add synchronous argument. Use _gpgme_wait_one
|
||||
instead gpgme_wait.
|
||||
* encrypt.c: Include "wait.h".
|
||||
(ggpgme_op_encrypt_start): Rename to ...
|
||||
(_gpgme_op_encrypt_start): ... this. New argument SYNCHRONOUS.
|
||||
Use _gpgme_op_reset. Make function static.
|
||||
(gpgme_op_encrypt_start): Just a wrapper around
|
||||
_gpgme_op_encrypt_start now.
|
||||
(gpgme_op_encrypt): Add synchronous argument. Use _gpgme_wait_one
|
||||
instead gpgme_wait.
|
||||
* encrypt_sign.c (gpgme_op_encrypt_sign_start): Rename to ...
|
||||
(_gpgme_op_encrypt_sign_start): ... this. New argument
|
||||
SYNCHRONOUS. Use _gpgme_op_reset. Make function static.
|
||||
(gpgme_op_encrypt_sign_start): Just a wrapper around
|
||||
_gpgme_op_encrypt_sign_start now.
|
||||
(gpgme_op_encrypt_sign): Add synchronous argument. Use
|
||||
_gpgme_wait_one instead gpgme_wait.
|
||||
* export.c (gpgme_op_export_start): Rename to ...
|
||||
(_gpgme_op_export_start): ... this. New argument SYNCHRONOUS.
|
||||
Use _gpgme_op_reset. Make function static.
|
||||
(gpgme_op_export_start): Just a wrapper around
|
||||
_gpgme_op_export_start now.
|
||||
(gpgme_op_export): Add synchronous argument. Use _gpgme_wait_one
|
||||
instead gpgme_wait.
|
||||
* genkey.c (gpgme_op_genkey_start): Rename to ...
|
||||
(_gpgme_op_genkey_start): ... this. New argument SYNCHRONOUS.
|
||||
Use _gpgme_op_reset. Make function static.
|
||||
(gpgme_op_genkey_start): Just a wrapper around
|
||||
_gpgme_op_genkey_start now.
|
||||
(gpgme_op_genkey): Add synchronous argument. Use _gpgme_wait_one
|
||||
instead gpgme_wait.
|
||||
* import.c (gpgme_op_import_start): Rename to ...
|
||||
(_gpgme_op_import_start): ... this. New argument SYNCHRONOUS.
|
||||
Use _gpgme_op_reset. Make function static.
|
||||
(gpgme_op_import_start): Just a wrapper around
|
||||
_gpgme_op_import_start now.
|
||||
(gpgme_op_import): Add synchronous argument. Use _gpgme_wait_one
|
||||
instead gpgme_wait.
|
||||
* keylist.c (gpgme_op_keylist_start): Use _gpgme_op_reset.
|
||||
(gpgme_op_keylist_ext_start): Likewise.
|
||||
* sign.c (gpgme_op_sign_start): Rename to ...
|
||||
(_gpgme_op_sign_start): ... this. New argument SYNCHRONOUS. Use
|
||||
_gpgme_op_reset. Make function static.
|
||||
(gpgme_op_sign_start): Just a wrapper around _gpgme_op_sign_start
|
||||
now.
|
||||
(gpgme_op_sign): Add synchronous argument. Use _gpgme_wait_one
|
||||
instead gpgme_wait.
|
||||
* trustlist.c (gpgme_op_trustlist_start): Use _gpgme_op_reset.
|
||||
* verify.c (gpgme_op_verify_start): Rename to ...
|
||||
(_gpgme_op_verify_start): ... this. New argument SYNCHRONOUS.
|
||||
Use _gpgme_op_reset. Make function static.
|
||||
(gpgme_op_verify_start): Just a wrapper around
|
||||
_gpgme_op_verify_start now.
|
||||
(gpgme_op_verify): Add synchronous argument. Use _gpgme_wait_one
|
||||
instead gpgme_wait.
|
||||
* engine-gpgsm.c (iocb_data_t): New type.
|
||||
(struct gpgsm_object_s): New member status_cb. Replace input_fd
|
||||
and input_data with input_cb. Replace output_fd and output_data
|
||||
with output_cb. Replace message_fd and message_data with
|
||||
message_cb. New member io_cbs.
|
||||
(_gpgme_gpgsm_new): Initialize all new members (and drop the old
|
||||
ones).
|
||||
(close_notify_handler): New variable POSSIBLY_DONE. For each I/O
|
||||
callback, check if it should be unregistered. If all callbacks
|
||||
have been unregistered, trigger GPGME_EVENT_DONE.
|
||||
(_gpgme_gpgsm_release): Remove variable PID. Use new variable
|
||||
names to close the file descriptors.
|
||||
(_gpgme_gpgsm_op_decrypt): Use new variable names,
|
||||
(_gpgme_gpgsm_op_encrypt): Likewise.
|
||||
(_gpgme_gpgsm_op_genkey): Likewise.
|
||||
(_gpgme_gpgsm_op_import): Likewise.
|
||||
(_gpgme_gpgsm_op_keylist): Likewise.
|
||||
(_gpgme_gpgsm_op_keylist_ext): Likewise.
|
||||
(_gpgme_gpgsm_op_sign): Likewise.
|
||||
(_gpgme_gpgsm_op_verify): Likewise.
|
||||
(gpgsm_status_handler): Drop argument PID. Change return type to
|
||||
void. Close status pipe before returning because of EOF or error.
|
||||
(_gpgme_gpgsm_add_io_cb): New function.
|
||||
(_gpgme_gpgsm_start): Use _gpgme_gpgsm_add_io_cb to register
|
||||
callback function.
|
||||
(_gpgme_gpgsm_set_io_cbs): New function.
|
||||
* engine-gpgsm.h: New prototype for _gpgme_gpgsm_set_io_cbs.
|
||||
* engine.c (_gpgme_engine_set_io_cbs): New function.
|
||||
* engine.h: New prototype for _gpgme_engine_set_io_cbs.
|
||||
|
||||
2002-06-04 Marcus Brinkmann <marcus@g10code.de>
|
||||
|
||||
* Makefile.am (libgpgme_la_SOURCES): Remove mutex.h.
|
||||
|
@ -58,7 +58,8 @@ libgpgme_la_SOURCES = \
|
||||
util.h util.c \
|
||||
context.h ops.h \
|
||||
data.c recipient.c signers.c \
|
||||
wait.c wait.h \
|
||||
wait.c wait.h \
|
||||
op-support.c \
|
||||
encrypt.c \
|
||||
encrypt-sign.c \
|
||||
decrypt.c \
|
||||
|
@ -25,14 +25,18 @@
|
||||
#include "gpgme.h"
|
||||
#include "types.h"
|
||||
#include "engine.h"
|
||||
#include "wait.h"
|
||||
|
||||
struct key_queue_item_s {
|
||||
struct key_queue_item_s *next;
|
||||
GpgmeKey key;
|
||||
struct key_queue_item_s
|
||||
{
|
||||
struct key_queue_item_s *next;
|
||||
GpgmeKey key;
|
||||
};
|
||||
struct trust_queue_item_s {
|
||||
struct trust_queue_item_s *next;
|
||||
GpgmeTrustItem item;
|
||||
|
||||
struct trust_queue_item_s
|
||||
{
|
||||
struct trust_queue_item_s *next;
|
||||
GpgmeTrustItem item;
|
||||
};
|
||||
|
||||
|
||||
@ -98,6 +102,11 @@ struct gpgme_context_s
|
||||
GpgmeProgressCb progress_cb;
|
||||
void *progress_cb_value;
|
||||
|
||||
/* A list of file descriptors in active use by the current
|
||||
(synchronous) operation. */
|
||||
struct fd_table fdt;
|
||||
struct GpgmeIOCbs io_cbs;
|
||||
|
||||
GpgmeData help_data_1;
|
||||
};
|
||||
|
||||
|
33
gpgme/data.c
33
gpgme/data.c
@ -874,8 +874,8 @@ _gpgme_data_append_percentstring_for_xml (GpgmeData dh, const char *string)
|
||||
|
||||
/* Functions to support the wait interface. */
|
||||
|
||||
int
|
||||
_gpgme_data_inbound_handler (void *opaque, int pid, int fd)
|
||||
void
|
||||
_gpgme_data_inbound_handler (void *opaque, int fd)
|
||||
{
|
||||
GpgmeData dh = opaque;
|
||||
GpgmeError err;
|
||||
@ -889,11 +889,14 @@ _gpgme_data_inbound_handler (void *opaque, int pid, int fd)
|
||||
{
|
||||
DEBUG3 ("read_mem_data: read failed on fd %d (n=%d): %s",
|
||||
fd, nread, strerror (errno) );
|
||||
return 1;
|
||||
_gpgme_io_close (fd); /* XXX ??? */
|
||||
return;
|
||||
}
|
||||
else if (!nread)
|
||||
return 1; /* eof */
|
||||
|
||||
{
|
||||
_gpgme_io_close (fd);
|
||||
return; /* eof */
|
||||
}
|
||||
/* We could improve this with a GpgmeData function which takes
|
||||
* the read function or provides a memory area for writing to it.
|
||||
*/
|
||||
@ -905,10 +908,11 @@ _gpgme_data_inbound_handler (void *opaque, int pid, int fd)
|
||||
gpgme_strerror(err));
|
||||
/* Fixme: we should close the pipe or read it to /dev/null in
|
||||
* this case. Returnin EOF is not sufficient */
|
||||
return 1;
|
||||
_gpgme_io_close (fd); /* XXX ??? */
|
||||
return;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -920,7 +924,6 @@ write_mem_data (GpgmeData dh, int fd)
|
||||
nbytes = dh->len - dh->readpos;
|
||||
if (!nbytes)
|
||||
{
|
||||
_gpgme_io_close (fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -938,7 +941,6 @@ write_mem_data (GpgmeData dh, int fd)
|
||||
{
|
||||
DEBUG3 ("write_mem_data(%d): write failed (n=%d): %s",
|
||||
fd, nwritten, strerror (errno));
|
||||
_gpgme_io_close (fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -956,7 +958,6 @@ write_cb_data (GpgmeData dh, int fd)
|
||||
err = gpgme_data_read (dh, buffer, DIM(buffer), &nbytes);
|
||||
if (err == GPGME_EOF)
|
||||
{
|
||||
_gpgme_io_close (fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -967,7 +968,6 @@ write_cb_data (GpgmeData dh, int fd)
|
||||
{
|
||||
DEBUG3 ("write_cb_data(%d): write failed (n=%d): %s",
|
||||
fd, nwritten, strerror (errno));
|
||||
_gpgme_io_close (fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -977,15 +977,14 @@ write_cb_data (GpgmeData dh, int fd)
|
||||
if (_gpgme_data_unread (dh, buffer + nwritten, nbytes - nwritten))
|
||||
DEBUG1 ("wite_cb_data: unread of %d bytes failed\n",
|
||||
nbytes - nwritten);
|
||||
_gpgme_io_close (fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
_gpgme_data_outbound_handler (void *opaque, int pid, int fd)
|
||||
void
|
||||
_gpgme_data_outbound_handler (void *opaque, int fd)
|
||||
{
|
||||
GpgmeData dh = opaque;
|
||||
|
||||
@ -994,15 +993,13 @@ _gpgme_data_outbound_handler (void *opaque, int pid, int fd)
|
||||
{
|
||||
case GPGME_DATA_TYPE_MEM:
|
||||
if (write_mem_data (dh, fd))
|
||||
return 1; /* ready */
|
||||
_gpgme_io_close (fd);
|
||||
break;
|
||||
case GPGME_DATA_TYPE_CB:
|
||||
if (write_cb_data (dh, fd))
|
||||
return 1; /* ready */
|
||||
_gpgme_io_close (fd);
|
||||
break;
|
||||
default:
|
||||
assert (0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ decrypt_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
||||
GpgmeError
|
||||
gpgme_op_decrypt_verify_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain)
|
||||
{
|
||||
return _gpgme_decrypt_start (ctx, ciph, plain,
|
||||
return _gpgme_decrypt_start (ctx, 0, ciph, plain,
|
||||
decrypt_verify_status_handler);
|
||||
}
|
||||
|
||||
@ -69,10 +69,11 @@ gpgme_op_decrypt_verify (GpgmeCtx ctx,
|
||||
ctx->notation = NULL;
|
||||
|
||||
*r_stat = GPGME_SIG_STAT_NONE;
|
||||
err = gpgme_op_decrypt_verify_start (ctx, in, out);
|
||||
err = _gpgme_decrypt_start (ctx, 1, in, out,
|
||||
decrypt_verify_status_handler);
|
||||
if (!err)
|
||||
{
|
||||
gpgme_wait (ctx, &err, 1);
|
||||
err = _gpgme_wait_one (ctx);
|
||||
if (!err)
|
||||
*r_stat = _gpgme_intersect_stati (ctx->result.verify);
|
||||
}
|
||||
|
@ -80,20 +80,12 @@ _gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
||||
|
||||
|
||||
GpgmeError
|
||||
_gpgme_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain,
|
||||
void *status_handler)
|
||||
_gpgme_decrypt_start (GpgmeCtx ctx, int synchronous,
|
||||
GpgmeData ciph, GpgmeData plain, void *status_handler)
|
||||
{
|
||||
GpgmeError err = 0;
|
||||
|
||||
fail_on_pending_request (ctx);
|
||||
ctx->pending = 1;
|
||||
|
||||
_gpgme_release_result (ctx);
|
||||
|
||||
/* Create a process object. */
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
|
||||
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
|
||||
err = _gpgme_op_reset (ctx, synchronous);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
@ -138,7 +130,7 @@ _gpgme_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain,
|
||||
GpgmeError
|
||||
gpgme_op_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain)
|
||||
{
|
||||
return _gpgme_decrypt_start (ctx, ciph, plain,
|
||||
return _gpgme_decrypt_start (ctx, 0, ciph, plain,
|
||||
_gpgme_decrypt_status_handler);
|
||||
}
|
||||
|
||||
@ -158,8 +150,9 @@ gpgme_op_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain)
|
||||
GpgmeError
|
||||
gpgme_op_decrypt (GpgmeCtx ctx, GpgmeData in, GpgmeData out)
|
||||
{
|
||||
GpgmeError err = gpgme_op_decrypt_start (ctx, in, out);
|
||||
GpgmeError err = _gpgme_decrypt_start (ctx, 1, in, out,
|
||||
_gpgme_decrypt_status_handler);
|
||||
if (!err)
|
||||
gpgme_wait (ctx, &err, 1);
|
||||
err = _gpgme_wait_one (ctx);
|
||||
return err;
|
||||
}
|
||||
|
@ -91,30 +91,13 @@ delete_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
||||
}
|
||||
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_delete_start (GpgmeCtx ctx, const GpgmeKey key, int allow_secret)
|
||||
static GpgmeError
|
||||
_gpgme_op_delete_start (GpgmeCtx ctx, int synchronous,
|
||||
const GpgmeKey key, int allow_secret)
|
||||
{
|
||||
GpgmeError err = 0;
|
||||
|
||||
fail_on_pending_request (ctx);
|
||||
ctx->pending = 1;
|
||||
|
||||
if (!key)
|
||||
{
|
||||
err = mk_error (Invalid_Value);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (ctx->engine)
|
||||
{
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
ctx->engine = NULL;
|
||||
}
|
||||
|
||||
_gpgme_release_result (ctx);
|
||||
|
||||
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
|
||||
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
|
||||
err = _gpgme_op_reset (ctx, synchronous);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
@ -135,6 +118,12 @@ gpgme_op_delete_start (GpgmeCtx ctx, const GpgmeKey key, int allow_secret)
|
||||
return err;
|
||||
}
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_delete_start (GpgmeCtx ctx, const GpgmeKey key, int allow_secret)
|
||||
{
|
||||
return _gpgme_op_delete_start (ctx, 0, key, allow_secret);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gpgme_op_delete:
|
||||
@ -150,8 +139,8 @@ gpgme_op_delete_start (GpgmeCtx ctx, const GpgmeKey key, int allow_secret)
|
||||
GpgmeError
|
||||
gpgme_op_delete (GpgmeCtx ctx, const GpgmeKey key, int allow_secret)
|
||||
{
|
||||
GpgmeError err = gpgme_op_delete_start (ctx, key, allow_secret);
|
||||
GpgmeError err = _gpgme_op_delete_start (ctx, 1, key, allow_secret);
|
||||
if (!err)
|
||||
gpgme_wait (ctx, &err, 1);
|
||||
err = _gpgme_wait_one (ctx);
|
||||
return err;
|
||||
}
|
||||
|
@ -50,30 +50,14 @@ encrypt_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
||||
}
|
||||
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_encrypt_sign_start (GpgmeCtx ctx, GpgmeRecipients recp,
|
||||
GpgmeData plain, GpgmeData cipher)
|
||||
static GpgmeError
|
||||
_gpgme_op_encrypt_sign_start (GpgmeCtx ctx, int synchronous,
|
||||
GpgmeRecipients recp,
|
||||
GpgmeData plain, GpgmeData cipher)
|
||||
{
|
||||
int err = 0;
|
||||
GpgmeError err = 0;
|
||||
|
||||
fail_on_pending_request (ctx);
|
||||
ctx->pending = 1;
|
||||
|
||||
_gpgme_release_result (ctx);
|
||||
|
||||
/* Do some checks. */
|
||||
if (!gpgme_recipients_count (recp))
|
||||
{
|
||||
/* FIXME: In this case we should do symmetric encryption. */
|
||||
err = mk_error (No_Recipients);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Create an engine object. */
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
ctx->engine = NULL;
|
||||
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
|
||||
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
|
||||
err = _gpgme_op_reset (ctx, synchronous);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
@ -115,6 +99,13 @@ gpgme_op_encrypt_sign_start (GpgmeCtx ctx, GpgmeRecipients recp,
|
||||
return err;
|
||||
}
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_encrypt_sign_start (GpgmeCtx ctx, GpgmeRecipients recp,
|
||||
GpgmeData plain, GpgmeData cipher)
|
||||
{
|
||||
return _gpgme_op_encrypt_sign_start (ctx, 0, recp, plain, cipher);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gpgme_op_encrypt_sign:
|
||||
@ -133,11 +124,11 @@ GpgmeError
|
||||
gpgme_op_encrypt_sign (GpgmeCtx ctx, GpgmeRecipients recp,
|
||||
GpgmeData plain, GpgmeData cipher)
|
||||
{
|
||||
GpgmeError err = gpgme_op_encrypt_sign_start (ctx, recp, plain, cipher);
|
||||
GpgmeError err = _gpgme_op_encrypt_sign_start (ctx, 1, recp, plain, cipher);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
gpgme_wait (ctx, &err, 1);
|
||||
err = _gpgme_wait_one (ctx);
|
||||
/* Old gpg versions don't return status info for invalid
|
||||
recipients, so we simply check whether we got any output at
|
||||
all, and if not we assume that we don't have valid
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "util.h"
|
||||
#include "context.h"
|
||||
#include "ops.h"
|
||||
#include "wait.h"
|
||||
|
||||
#define SKIP_TOKEN_OR_RETURN(a) do { \
|
||||
while (*(a) && *(a) != ' ') (a)++; \
|
||||
@ -142,18 +143,13 @@ _gpgme_encrypt_sym_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
||||
}
|
||||
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_encrypt_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData plain,
|
||||
GpgmeData ciph)
|
||||
static GpgmeError
|
||||
_gpgme_op_encrypt_start (GpgmeCtx ctx, int synchronous,
|
||||
GpgmeRecipients recp, GpgmeData plain, GpgmeData ciph)
|
||||
{
|
||||
int err = 0;
|
||||
GpgmeError err = 0;
|
||||
int symmetric = 0;
|
||||
|
||||
fail_on_pending_request (ctx);
|
||||
ctx->pending = 1;
|
||||
|
||||
_gpgme_release_result (ctx);
|
||||
|
||||
/* Do some checks. */
|
||||
if (!recp)
|
||||
symmetric = 1;
|
||||
@ -163,11 +159,7 @@ gpgme_op_encrypt_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData plain,
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* Create an engine object. */
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
ctx->engine = NULL;
|
||||
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
|
||||
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
|
||||
err = _gpgme_op_reset (ctx, synchronous);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
@ -216,6 +208,14 @@ gpgme_op_encrypt_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData plain,
|
||||
}
|
||||
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_encrypt_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData plain,
|
||||
GpgmeData ciph)
|
||||
{
|
||||
return _gpgme_op_encrypt_start (ctx, 0, recp, plain, ciph);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gpgme_op_encrypt:
|
||||
* @c: The context
|
||||
@ -233,10 +233,10 @@ GpgmeError
|
||||
gpgme_op_encrypt (GpgmeCtx ctx, GpgmeRecipients recp,
|
||||
GpgmeData plain, GpgmeData cipher)
|
||||
{
|
||||
int err = gpgme_op_encrypt_start (ctx, recp, plain, cipher);
|
||||
int err = _gpgme_op_encrypt_start (ctx, 1, recp, plain, cipher);
|
||||
if (!err)
|
||||
{
|
||||
gpgme_wait (ctx, &err, 1);
|
||||
err = _gpgme_wait_one (ctx);
|
||||
/* Old gpg versions don't return status info for invalid
|
||||
recipients, so we simply check whether we got any output at
|
||||
all, and if not we assume that we don't have valid
|
||||
|
@ -59,20 +59,30 @@
|
||||
#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int fd; /* FD we talk about. */
|
||||
int dir; /* Inbound/Outbound, maybe given implicit? */
|
||||
void *data; /* Handler-specific data. */
|
||||
void *tag; /* ID from the user for gpgme_remove_io_callback. */
|
||||
} iocb_data_t;
|
||||
|
||||
struct gpgsm_object_s
|
||||
{
|
||||
ASSUAN_CONTEXT assuan_ctx;
|
||||
|
||||
iocb_data_t status_cb;
|
||||
|
||||
/* Input, output etc are from the servers perspective. */
|
||||
int input_fd;
|
||||
iocb_data_t input_cb;
|
||||
int input_fd_server;
|
||||
GpgmeData input_data;
|
||||
int output_fd;
|
||||
|
||||
iocb_data_t output_cb;
|
||||
int output_fd_server;
|
||||
GpgmeData output_data;
|
||||
int message_fd;
|
||||
|
||||
iocb_data_t message_cb;
|
||||
int message_fd_server;
|
||||
GpgmeData message_data;
|
||||
|
||||
char *command;
|
||||
|
||||
@ -93,6 +103,8 @@ struct gpgsm_object_s
|
||||
int linelen;
|
||||
} attic;
|
||||
} colon;
|
||||
|
||||
struct GpgmeIOCbs io_cbs;
|
||||
};
|
||||
|
||||
|
||||
@ -124,14 +136,49 @@ static void
|
||||
close_notify_handler (int fd, void *opaque)
|
||||
{
|
||||
GpgsmObject gpgsm = opaque;
|
||||
int possibly_done = 0;
|
||||
|
||||
assert (fd != -1);
|
||||
if (gpgsm->input_fd == fd)
|
||||
gpgsm->input_fd = -1;
|
||||
else if (gpgsm->output_fd == fd)
|
||||
gpgsm->output_fd = -1;
|
||||
else if (gpgsm->message_fd == fd)
|
||||
gpgsm->message_fd = -1;
|
||||
if (gpgsm->status_cb.fd == fd)
|
||||
{
|
||||
if (gpgsm->status_cb.tag)
|
||||
{
|
||||
(*gpgsm->io_cbs.remove) (gpgsm->status_cb.tag);
|
||||
possibly_done = 1;
|
||||
}
|
||||
gpgsm->status_cb.fd = -1;
|
||||
}
|
||||
else if (gpgsm->input_cb.fd == fd)
|
||||
{
|
||||
if (gpgsm->input_cb.tag)
|
||||
{
|
||||
(*gpgsm->io_cbs.remove) (gpgsm->input_cb.tag);
|
||||
possibly_done = 1;
|
||||
}
|
||||
gpgsm->input_cb.fd = -1;
|
||||
}
|
||||
else if (gpgsm->output_cb.fd == fd)
|
||||
{
|
||||
if (gpgsm->output_cb.tag)
|
||||
{
|
||||
(*gpgsm->io_cbs.remove) (gpgsm->output_cb.tag);
|
||||
possibly_done = 1;
|
||||
}
|
||||
gpgsm->output_cb.fd = -1;
|
||||
}
|
||||
else if (gpgsm->message_cb.fd == fd)
|
||||
{
|
||||
if (gpgsm->message_cb.tag)
|
||||
{
|
||||
(*gpgsm->io_cbs.remove) (gpgsm->message_cb.tag);
|
||||
possibly_done = 1;
|
||||
}
|
||||
gpgsm->message_cb.fd = -1;
|
||||
}
|
||||
if (possibly_done && gpgsm->io_cbs.event
|
||||
&& gpgsm->status_cb.fd == -1 && gpgsm->input_cb.fd == -1
|
||||
&& gpgsm->output_cb.fd == -1 && gpgsm->message_cb.fd == -1)
|
||||
(*gpgsm->io_cbs.event) (gpgsm->io_cbs.event_priv, GPGME_EVENT_DONE, NULL);
|
||||
}
|
||||
|
||||
|
||||
@ -248,6 +295,8 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
||||
char *old_lc = NULL;
|
||||
char *dft_lc = NULL;
|
||||
char *optstr;
|
||||
int fdlist[5];
|
||||
int nfds;
|
||||
|
||||
*r_gpgsm = NULL;
|
||||
gpgsm = xtrycalloc (1, sizeof *gpgsm);
|
||||
@ -257,11 +306,17 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
||||
return err;
|
||||
}
|
||||
|
||||
gpgsm->input_fd = -1;
|
||||
gpgsm->status_cb.fd = -1;
|
||||
gpgsm->status_cb.tag = 0;
|
||||
|
||||
gpgsm->input_cb.fd = -1;
|
||||
gpgsm->input_cb.tag = 0;
|
||||
gpgsm->input_fd_server = -1;
|
||||
gpgsm->output_fd = -1;
|
||||
gpgsm->output_cb.fd = -1;
|
||||
gpgsm->output_cb.tag = 0;
|
||||
gpgsm->output_fd_server = -1;
|
||||
gpgsm->message_fd = -1;
|
||||
gpgsm->message_cb.fd = -1;
|
||||
gpgsm->message_cb.tag = 0;
|
||||
gpgsm->message_fd_server = -1;
|
||||
|
||||
gpgsm->status.fnc = 0;
|
||||
@ -270,12 +325,19 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
||||
gpgsm->colon.attic.linesize = 0;
|
||||
gpgsm->colon.attic.linelen = 0;
|
||||
|
||||
gpgsm->io_cbs.add = NULL;
|
||||
gpgsm->io_cbs.add_priv = NULL;
|
||||
gpgsm->io_cbs.remove = NULL;
|
||||
gpgsm->io_cbs.event = NULL;
|
||||
gpgsm->io_cbs.event_priv = NULL;
|
||||
|
||||
if (_gpgme_io_pipe (fds, 0) < 0)
|
||||
{
|
||||
err = mk_error (Pipe_Error);
|
||||
goto leave;
|
||||
}
|
||||
gpgsm->input_fd = fds[1];
|
||||
gpgsm->input_cb.fd = fds[1];
|
||||
gpgsm->input_cb.dir = 0;
|
||||
gpgsm->input_fd_server = fds[0];
|
||||
|
||||
if (_gpgme_io_pipe (fds, 1) < 0)
|
||||
@ -283,7 +345,8 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
||||
err = mk_error (Pipe_Error);
|
||||
goto leave;
|
||||
}
|
||||
gpgsm->output_fd = fds[0];
|
||||
gpgsm->output_cb.fd = fds[0];
|
||||
gpgsm->output_cb.dir = 1;
|
||||
gpgsm->output_fd_server = fds[1];
|
||||
|
||||
if (_gpgme_io_pipe (fds, 0) < 0)
|
||||
@ -291,7 +354,8 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
||||
err = mk_error (Pipe_Error);
|
||||
goto leave;
|
||||
}
|
||||
gpgsm->message_fd = fds[1];
|
||||
gpgsm->message_cb.fd = fds[1];
|
||||
gpgsm->message_cb.dir = 0;
|
||||
gpgsm->message_fd_server = fds[0];
|
||||
|
||||
child_fds[0] = gpgsm->input_fd_server;
|
||||
@ -307,6 +371,20 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
||||
_gpgme_get_gpgsm_path (), argv, child_fds,
|
||||
1 /* dup stderr to /dev/null */);
|
||||
|
||||
/* We need to know the fd used by assuan for reads. We do this by
|
||||
using the assumption that the first returned fd from
|
||||
assuan_get_active_fds() is always this one. */
|
||||
nfds = assuan_get_active_fds (gpgsm->assuan_ctx, 0 /* read fds */,
|
||||
fdlist, DIM (fdlist));
|
||||
if (nfds < 1)
|
||||
{
|
||||
err = mk_error (General_Error); /* FIXME */
|
||||
goto leave;
|
||||
}
|
||||
gpgsm->status_cb.fd = fdlist[0];
|
||||
gpgsm->status_cb.dir = 1;
|
||||
gpgsm->status_cb.data = gpgsm;
|
||||
|
||||
dft_display = getenv ("DISPLAY");
|
||||
if (dft_display)
|
||||
{
|
||||
@ -315,8 +393,8 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
||||
err = mk_error (Out_Of_Core);
|
||||
goto leave;
|
||||
}
|
||||
err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL);
|
||||
err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL);
|
||||
free (optstr);
|
||||
if (err)
|
||||
{
|
||||
@ -400,11 +478,13 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
||||
}
|
||||
|
||||
if (!err &&
|
||||
(_gpgme_io_set_close_notify (gpgsm->input_fd,
|
||||
(_gpgme_io_set_close_notify (gpgsm->status_cb.fd,
|
||||
close_notify_handler, gpgsm)
|
||||
|| _gpgme_io_set_close_notify (gpgsm->output_fd,
|
||||
|| _gpgme_io_set_close_notify (gpgsm->input_cb.fd,
|
||||
close_notify_handler, gpgsm)
|
||||
|| _gpgme_io_set_close_notify (gpgsm->output_cb.fd,
|
||||
close_notify_handler, gpgsm)
|
||||
|| _gpgme_io_set_close_notify (gpgsm->message_fd,
|
||||
|| _gpgme_io_set_close_notify (gpgsm->message_cb.fd,
|
||||
close_notify_handler, gpgsm)))
|
||||
{
|
||||
err = mk_error (General_Error);
|
||||
@ -433,21 +513,15 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
||||
void
|
||||
_gpgme_gpgsm_release (GpgsmObject gpgsm)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
if (!gpgsm)
|
||||
return;
|
||||
|
||||
pid = assuan_get_pid (gpgsm->assuan_ctx);
|
||||
if (pid != -1)
|
||||
_gpgme_remove_proc_from_wait_queue (pid);
|
||||
|
||||
if (gpgsm->input_fd != -1)
|
||||
_gpgme_io_close (gpgsm->input_fd);
|
||||
if (gpgsm->output_fd != -1)
|
||||
_gpgme_io_close (gpgsm->output_fd);
|
||||
if (gpgsm->message_fd != -1)
|
||||
_gpgme_io_close (gpgsm->message_fd);
|
||||
if (gpgsm->input_cb.fd != -1)
|
||||
_gpgme_io_close (gpgsm->input_cb.fd);
|
||||
if (gpgsm->output_cb.fd != -1)
|
||||
_gpgme_io_close (gpgsm->output_cb.fd);
|
||||
if (gpgsm->message_cb.fd != -1)
|
||||
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||
|
||||
assuan_disconnect (gpgsm->assuan_ctx);
|
||||
|
||||
@ -512,12 +586,17 @@ map_input_enc (GpgmeData d)
|
||||
{
|
||||
switch (gpgme_data_get_encoding (d))
|
||||
{
|
||||
case GPGME_DATA_ENCODING_NONE: break;
|
||||
case GPGME_DATA_ENCODING_BINARY: return "--binary";
|
||||
case GPGME_DATA_ENCODING_BASE64: return "--base64";
|
||||
case GPGME_DATA_ENCODING_ARMOR: return "--armor";
|
||||
case GPGME_DATA_ENCODING_NONE:
|
||||
break;
|
||||
case GPGME_DATA_ENCODING_BINARY:
|
||||
return "--binary";
|
||||
case GPGME_DATA_ENCODING_BASE64:
|
||||
return "--base64";
|
||||
case GPGME_DATA_ENCODING_ARMOR:
|
||||
return "--armor";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -534,16 +613,16 @@ _gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph, GpgmeData plain)
|
||||
if (!gpgsm->command)
|
||||
return mk_error (Out_Of_Core);
|
||||
|
||||
gpgsm->input_data = ciph;
|
||||
gpgsm->input_cb.data = ciph;
|
||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server,
|
||||
map_input_enc (gpgsm->input_data));
|
||||
map_input_enc (gpgsm->input_cb.data));
|
||||
if (err)
|
||||
return mk_error (General_Error); /* FIXME */
|
||||
gpgsm->output_data = plain;
|
||||
gpgsm->output_cb.data = plain;
|
||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server, 0);
|
||||
if (err)
|
||||
return mk_error (General_Error); /* FIXME */
|
||||
_gpgme_io_close (gpgsm->message_fd);
|
||||
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -626,17 +705,17 @@ _gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp,
|
||||
if (!gpgsm->command)
|
||||
return mk_error (Out_Of_Core);
|
||||
|
||||
gpgsm->input_data = plain;
|
||||
gpgsm->input_cb.data = plain;
|
||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server,
|
||||
map_input_enc (gpgsm->input_data));
|
||||
map_input_enc (gpgsm->input_cb.data));
|
||||
if (err)
|
||||
return err;
|
||||
gpgsm->output_data = ciph;
|
||||
gpgsm->output_cb.data = ciph;
|
||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server,
|
||||
use_armor ? "--armor" : 0);
|
||||
if (err)
|
||||
return err;
|
||||
_gpgme_io_close (gpgsm->message_fd);
|
||||
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||
|
||||
err = gpgsm_set_recipients (gpgsm, recp);
|
||||
if (err)
|
||||
@ -668,17 +747,17 @@ _gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data, int use_armor,
|
||||
if (!gpgsm->command)
|
||||
return mk_error (Out_Of_Core);
|
||||
|
||||
gpgsm->input_data = help_data;
|
||||
gpgsm->input_cb.data = help_data;
|
||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server,
|
||||
map_input_enc (gpgsm->input_data));
|
||||
map_input_enc (gpgsm->input_cb.data));
|
||||
if (err)
|
||||
return err;
|
||||
gpgsm->output_data = pubkey;
|
||||
gpgsm->output_cb.data = pubkey;
|
||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server,
|
||||
use_armor ? "--armor" : 0);
|
||||
if (err)
|
||||
return err;
|
||||
_gpgme_io_close (gpgsm->message_fd);
|
||||
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -696,13 +775,13 @@ _gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata)
|
||||
if (!gpgsm->command)
|
||||
return mk_error (Out_Of_Core);
|
||||
|
||||
gpgsm->input_data = keydata;
|
||||
gpgsm->input_cb.data = keydata;
|
||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server,
|
||||
map_input_enc (gpgsm->input_data));
|
||||
map_input_enc (gpgsm->input_cb.data));
|
||||
if (err)
|
||||
return err;
|
||||
_gpgme_io_close (gpgsm->output_fd);
|
||||
_gpgme_io_close (gpgsm->message_fd);
|
||||
_gpgme_io_close (gpgsm->output_cb.fd);
|
||||
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -740,9 +819,9 @@ _gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern,
|
||||
strcpy (&line[9], pattern);
|
||||
}
|
||||
|
||||
_gpgme_io_close (gpgsm->input_fd);
|
||||
_gpgme_io_close (gpgsm->output_fd);
|
||||
_gpgme_io_close (gpgsm->message_fd);
|
||||
_gpgme_io_close (gpgsm->input_cb.fd);
|
||||
_gpgme_io_close (gpgsm->output_cb.fd);
|
||||
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||
|
||||
gpgsm->command = line;
|
||||
return 0;
|
||||
@ -839,9 +918,9 @@ _gpgme_gpgsm_op_keylist_ext (GpgsmObject gpgsm, const char *pattern[],
|
||||
}
|
||||
*linep = '\0';
|
||||
|
||||
_gpgme_io_close (gpgsm->input_fd);
|
||||
_gpgme_io_close (gpgsm->output_fd);
|
||||
_gpgme_io_close (gpgsm->message_fd);
|
||||
_gpgme_io_close (gpgsm->input_cb.fd);
|
||||
_gpgme_io_close (gpgsm->output_cb.fd);
|
||||
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||
|
||||
gpgsm->command = line;
|
||||
return 0;
|
||||
@ -872,17 +951,17 @@ _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
gpgsm->input_data = in;
|
||||
gpgsm->input_cb.data = in;
|
||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server,
|
||||
map_input_enc (gpgsm->input_data));
|
||||
map_input_enc (gpgsm->input_cb.data));
|
||||
if (err)
|
||||
return err;
|
||||
gpgsm->output_data = out;
|
||||
gpgsm->output_cb.data = out;
|
||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server,
|
||||
use_armor ? "--armor" : 0);
|
||||
if (err)
|
||||
return err;
|
||||
_gpgme_io_close (gpgsm->message_fd);
|
||||
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -908,26 +987,26 @@ _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text)
|
||||
if (!gpgsm->command)
|
||||
return mk_error (Out_Of_Core);
|
||||
|
||||
gpgsm->input_data = sig;
|
||||
gpgsm->input_cb.data = sig;
|
||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server,
|
||||
map_input_enc (gpgsm->input_data));
|
||||
map_input_enc (gpgsm->input_cb.data));
|
||||
if (err)
|
||||
return err;
|
||||
if (_gpgme_data_get_mode (text) == GPGME_DATA_MODE_IN)
|
||||
{
|
||||
/* Normal or cleartext signature. */
|
||||
gpgsm->output_data = text;
|
||||
gpgsm->output_cb.data = text;
|
||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server,
|
||||
0);
|
||||
_gpgme_io_close (gpgsm->message_fd);
|
||||
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Detached signature. */
|
||||
gpgsm->message_data = text;
|
||||
gpgsm->message_cb.data = text;
|
||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "MESSAGE",
|
||||
gpgsm->message_fd_server, 0);
|
||||
_gpgme_io_close (gpgsm->output_fd);
|
||||
_gpgme_io_close (gpgsm->output_cb.fd);
|
||||
}
|
||||
if (err)
|
||||
return err;
|
||||
@ -946,8 +1025,8 @@ status_cmp (const void *ap, const void *bp)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gpgsm_status_handler (void *opaque, int pid, int fd)
|
||||
static void
|
||||
gpgsm_status_handler (void *opaque, int fd)
|
||||
{
|
||||
AssuanError err;
|
||||
GpgsmObject gpgsm = opaque;
|
||||
@ -966,8 +1045,9 @@ gpgsm_status_handler (void *opaque, int pid, int fd)
|
||||
&& line[0] == 'E' && line[1] == 'R' && line[2] == 'R'
|
||||
&& (line[3] == '\0' || line[3] == ' ')))
|
||||
{
|
||||
/* XXX: If an error occured, find out what happened, then save the error value
|
||||
before running the status handler (so it takes precedence). */
|
||||
/* XXX: If an error occured, find out what happened, then
|
||||
save the error value before running the status handler
|
||||
(so it takes precedence). */
|
||||
if (!err && line[0] == 'E' && line[3] == ' ')
|
||||
{
|
||||
err = map_assuan_error (atoi (&line[4]));
|
||||
@ -990,7 +1070,8 @@ gpgsm_status_handler (void *opaque, int pid, int fd)
|
||||
if (err)
|
||||
assuan_write_line (gpgsm->assuan_ctx, "BYE");
|
||||
|
||||
return 1;
|
||||
_gpgme_io_close (gpgsm->status_cb.fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (linelen > 2
|
||||
@ -1015,7 +1096,10 @@ gpgsm_status_handler (void *opaque, int pid, int fd)
|
||||
unsigned char *newline = xtryrealloc (*aline,
|
||||
*alinelen + linelen + 1);
|
||||
if (!newline)
|
||||
return mk_error (Out_Of_Core);
|
||||
{
|
||||
_gpgme_io_close (gpgsm->status_cb.fd);
|
||||
return;
|
||||
}
|
||||
*aline = newline;
|
||||
gpgsm->colon.attic.linesize += linelen + 1;
|
||||
}
|
||||
@ -1082,8 +1166,6 @@ gpgsm_status_handler (void *opaque, int pid, int fd)
|
||||
}
|
||||
}
|
||||
while (assuan_pending_line (gpgsm->assuan_ctx));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1109,50 +1191,45 @@ _gpgme_gpgsm_set_colon_line_handler (GpgsmObject gpgsm,
|
||||
}
|
||||
|
||||
|
||||
static GpgmeError
|
||||
_gpgme_gpgsm_add_io_cb (GpgsmObject gpgsm, iocb_data_t *iocbd,
|
||||
GpgmeIOCb handler)
|
||||
{
|
||||
GpgmeError err = 0;
|
||||
|
||||
iocbd->tag = (*gpgsm->io_cbs.add) (gpgsm->io_cbs.add_priv,
|
||||
iocbd->fd, iocbd->dir,
|
||||
handler, iocbd->data);
|
||||
if (!iocbd->tag)
|
||||
err = mk_error (General_Error);
|
||||
if (!err && !iocbd->dir)
|
||||
/* FIXME Kludge around poll() problem. */
|
||||
err = _gpgme_io_set_nonblocking (iocbd->fd);
|
||||
return err;
|
||||
}
|
||||
|
||||
GpgmeError
|
||||
_gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque)
|
||||
{
|
||||
GpgmeError err = 0;
|
||||
pid_t pid;
|
||||
int fdlist[5];
|
||||
int nfds;
|
||||
|
||||
if (!gpgsm)
|
||||
return mk_error (Invalid_Value);
|
||||
|
||||
pid = assuan_get_pid (gpgsm->assuan_ctx);
|
||||
|
||||
/* We need to know the fd used by assuan for reads. We do this by
|
||||
using the assumption that the first returned fd from
|
||||
assuan_get_active_fds() is always this one. */
|
||||
nfds = assuan_get_active_fds (gpgsm->assuan_ctx, 0 /* read fds */,
|
||||
fdlist, DIM (fdlist));
|
||||
if (nfds < 1)
|
||||
return mk_error (General_Error); /* FIXME */
|
||||
err = _gpgme_register_pipe_handler (opaque, gpgsm_status_handler, gpgsm, pid,
|
||||
fdlist[0], 1);
|
||||
|
||||
|
||||
if (gpgsm->input_fd != -1)
|
||||
{
|
||||
err = _gpgme_register_pipe_handler (opaque, _gpgme_data_outbound_handler,
|
||||
gpgsm->input_data, pid,
|
||||
gpgsm->input_fd, 0);
|
||||
if (!err) /* FIXME Kludge around poll() problem. */
|
||||
err = _gpgme_io_set_nonblocking (gpgsm->input_fd);
|
||||
}
|
||||
if (!err && gpgsm->output_fd != -1)
|
||||
err = _gpgme_register_pipe_handler (opaque, _gpgme_data_inbound_handler,
|
||||
gpgsm->output_data, pid,
|
||||
gpgsm->output_fd, 1);
|
||||
if (!err && gpgsm->message_fd != -1)
|
||||
{
|
||||
err = _gpgme_register_pipe_handler (opaque, _gpgme_data_outbound_handler,
|
||||
gpgsm->message_data, pid,
|
||||
gpgsm->message_fd, 0);
|
||||
if (!err) /* FIXME Kludge around poll() problem. */
|
||||
err = _gpgme_io_set_nonblocking (gpgsm->message_fd);
|
||||
}
|
||||
err = _gpgme_gpgsm_add_io_cb (gpgsm, &gpgsm->status_cb,
|
||||
gpgsm_status_handler);
|
||||
if (gpgsm->input_cb.fd != -1)
|
||||
err = _gpgme_gpgsm_add_io_cb (gpgsm, &gpgsm->input_cb,
|
||||
_gpgme_data_outbound_handler);
|
||||
if (!err && gpgsm->output_cb.fd != -1)
|
||||
err = _gpgme_gpgsm_add_io_cb (gpgsm, &gpgsm->output_cb,
|
||||
_gpgme_data_inbound_handler);
|
||||
if (!err && gpgsm->message_cb.fd != -1)
|
||||
err = _gpgme_gpgsm_add_io_cb (gpgsm, &gpgsm->message_cb,
|
||||
_gpgme_data_outbound_handler);
|
||||
|
||||
if (!err)
|
||||
err = assuan_write_line (gpgsm->assuan_ctx, gpgsm->command);
|
||||
@ -1160,6 +1237,12 @@ _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque)
|
||||
return err;
|
||||
}
|
||||
|
||||
void
|
||||
_gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, struct GpgmeIOCbs *io_cbs)
|
||||
{
|
||||
gpgsm->io_cbs = *io_cbs;
|
||||
}
|
||||
|
||||
|
||||
#else /* ENABLE_GPGSM */
|
||||
|
||||
@ -1303,5 +1386,8 @@ _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque)
|
||||
return mk_error (Invalid_Engine);
|
||||
}
|
||||
|
||||
void _gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, GpgmeIOCbs io_cbs)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* ! ENABLE_GPGSM */
|
||||
|
@ -63,5 +63,6 @@ GpgmeError _gpgme_gpgsm_op_trustlist (GpgsmObject gpgsm, const char *pattern);
|
||||
GpgmeError _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig,
|
||||
GpgmeData text);
|
||||
GpgmeError _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque);
|
||||
void _gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, struct GpgmeIOCbs *io_cbs);
|
||||
|
||||
#endif /* ENGINE_GPGSM_H */
|
||||
|
@ -567,6 +567,26 @@ _gpgme_engine_start (EngineObject engine, void *opaque)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
_gpgme_engine_set_io_cbs (EngineObject engine,
|
||||
struct GpgmeIOCbs *io_cbs)
|
||||
{
|
||||
if (!engine)
|
||||
return;
|
||||
|
||||
switch (engine->protocol)
|
||||
{
|
||||
case GPGME_PROTOCOL_OpenPGP:
|
||||
_gpgme_gpg_set_io_cbs (engine->engine.gpg, io_cbs);
|
||||
break;
|
||||
case GPGME_PROTOCOL_CMS:
|
||||
_gpgme_gpgsm_set_io_cbs (engine->engine.gpgsm, io_cbs);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gpgme_engine_add_child_to_reap_list (void *buf, int buflen, pid_t pid)
|
||||
|
@ -76,6 +76,9 @@ GpgmeError _gpgme_engine_op_verify (EngineObject engine, GpgmeData sig,
|
||||
GpgmeData text);
|
||||
GpgmeError _gpgme_engine_start (EngineObject engine, void *opaque);
|
||||
|
||||
void _gpgme_engine_set_io_cbs (EngineObject engine,
|
||||
struct GpgmeIOCbs *io_cbs);
|
||||
|
||||
void _gpgme_engine_add_child_to_reap_list (void *buf, int buflen, pid_t pid);
|
||||
void _gpgme_engine_housecleaning (void);
|
||||
|
||||
|
@ -41,21 +41,13 @@ export_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
||||
}
|
||||
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_export_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData keydata)
|
||||
static GpgmeError
|
||||
_gpgme_op_export_start (GpgmeCtx ctx, int synchronous,
|
||||
GpgmeRecipients recp, GpgmeData keydata)
|
||||
{
|
||||
GpgmeError err = 0;
|
||||
|
||||
fail_on_pending_request (ctx);
|
||||
ctx->pending = 1;
|
||||
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
ctx->engine = NULL;
|
||||
|
||||
_gpgme_release_result (ctx);
|
||||
|
||||
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
|
||||
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
|
||||
err = _gpgme_op_reset (ctx, synchronous);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
@ -83,6 +75,11 @@ gpgme_op_export_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData keydata)
|
||||
return err;
|
||||
}
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_export_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData keydata)
|
||||
{
|
||||
return _gpgme_op_export_start (ctx, 0, recp, keydata);
|
||||
}
|
||||
|
||||
/**
|
||||
* gpgme_op_export:
|
||||
@ -100,8 +97,8 @@ gpgme_op_export_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData keydata)
|
||||
GpgmeError
|
||||
gpgme_op_export (GpgmeCtx ctx, GpgmeRecipients recipients, GpgmeData keydata)
|
||||
{
|
||||
GpgmeError err = gpgme_op_export_start (ctx, recipients, keydata);
|
||||
GpgmeError err = _gpgme_op_export_start (ctx, 1, recipients, keydata);
|
||||
if (!err)
|
||||
gpgme_wait (ctx, &err, 1);
|
||||
err = _gpgme_wait_one (ctx);
|
||||
return err;
|
||||
}
|
||||
|
109
gpgme/genkey.c
109
gpgme/genkey.c
@ -78,66 +78,20 @@ genkey_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gpgme_op_genkey:
|
||||
* @c: the context
|
||||
* @parms: XML string with the key parameters
|
||||
* @pubkey: Returns the public key
|
||||
* @seckey: Returns the secret key
|
||||
*
|
||||
* Generate a new key and store the key in the default keyrings if
|
||||
* both @pubkey and @seckey are NULL. If @pubkey and @seckey are
|
||||
* given, the newly created key will be returned in these data
|
||||
* objects. This function just starts the gheneration and does not
|
||||
* wait for completion.
|
||||
*
|
||||
* Here is an example on how @parms should be formatted; for deatils
|
||||
* see the file doc/DETAILS from the GnuPG distribution.
|
||||
*
|
||||
* <literal>
|
||||
* <![CDATA[
|
||||
* <GnupgKeyParms format="internal">
|
||||
* Key-Type: DSA
|
||||
* Key-Length: 1024
|
||||
* Subkey-Type: ELG-E
|
||||
* Subkey-Length: 1024
|
||||
* Name-Real: Joe Tester
|
||||
* Name-Comment: with stupid passphrase
|
||||
* Name-Email: joe@foo.bar
|
||||
* Expire-Date: 0
|
||||
* Passphrase: abc
|
||||
* </GnupgKeyParms>
|
||||
* ]]>
|
||||
* </literal>
|
||||
*
|
||||
* Strings should be given in UTF-8 encoding. The format we support
|
||||
* for now is only "internal". The content of the
|
||||
* <GnupgKeyParms> container is passed verbatim to GnuPG.
|
||||
* Control statements are not allowed.
|
||||
*
|
||||
* Return value: 0 for success or an error code
|
||||
**/
|
||||
GpgmeError
|
||||
gpgme_op_genkey_start (GpgmeCtx ctx, const char *parms,
|
||||
GpgmeData pubkey, GpgmeData seckey)
|
||||
static GpgmeError
|
||||
_gpgme_op_genkey_start (GpgmeCtx ctx, int synchronous, const char *parms,
|
||||
GpgmeData pubkey, GpgmeData seckey)
|
||||
{
|
||||
int err = 0;
|
||||
const char *s, *s2, *sx;
|
||||
|
||||
fail_on_pending_request (ctx);
|
||||
ctx->pending = 1;
|
||||
err = _gpgme_op_reset (ctx, synchronous);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
gpgme_data_release (ctx->help_data_1);
|
||||
ctx->help_data_1 = NULL;
|
||||
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
ctx->engine = NULL;
|
||||
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
|
||||
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
if (!pubkey && !seckey)
|
||||
; /* okay: Add key to the keyrings */
|
||||
else if (pubkey && gpgme_data_get_type (pubkey) != GPGME_DATA_TYPE_NONE)
|
||||
@ -199,6 +153,53 @@ gpgme_op_genkey_start (GpgmeCtx ctx, const char *parms,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gpgme_op_genkey:
|
||||
* @c: the context
|
||||
* @parms: XML string with the key parameters
|
||||
* @pubkey: Returns the public key
|
||||
* @seckey: Returns the secret key
|
||||
*
|
||||
* Generate a new key and store the key in the default keyrings if
|
||||
* both @pubkey and @seckey are NULL. If @pubkey and @seckey are
|
||||
* given, the newly created key will be returned in these data
|
||||
* objects. This function just starts the gheneration and does not
|
||||
* wait for completion.
|
||||
*
|
||||
* Here is an example on how @parms should be formatted; for deatils
|
||||
* see the file doc/DETAILS from the GnuPG distribution.
|
||||
*
|
||||
* <literal>
|
||||
* <![CDATA[
|
||||
* <GnupgKeyParms format="internal">
|
||||
* Key-Type: DSA
|
||||
* Key-Length: 1024
|
||||
* Subkey-Type: ELG-E
|
||||
* Subkey-Length: 1024
|
||||
* Name-Real: Joe Tester
|
||||
* Name-Comment: with stupid passphrase
|
||||
* Name-Email: joe@foo.bar
|
||||
* Expire-Date: 0
|
||||
* Passphrase: abc
|
||||
* </GnupgKeyParms>
|
||||
* ]]>
|
||||
* </literal>
|
||||
*
|
||||
* Strings should be given in UTF-8 encoding. The format we support
|
||||
* for now is only "internal". The content of the
|
||||
* <GnupgKeyParms> container is passed verbatim to GnuPG.
|
||||
* Control statements are not allowed.
|
||||
*
|
||||
* Return value: 0 for success or an error code
|
||||
**/
|
||||
GpgmeError
|
||||
gpgme_op_genkey_start (GpgmeCtx ctx, const char *parms,
|
||||
GpgmeData pubkey, GpgmeData seckey)
|
||||
{
|
||||
return _gpgme_op_genkey_start (ctx, 0, parms, pubkey, seckey);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gpgme_op_genkey:
|
||||
* @c: the context
|
||||
@ -217,8 +218,8 @@ GpgmeError
|
||||
gpgme_op_genkey (GpgmeCtx ctx, const char *parms,
|
||||
GpgmeData pubkey, GpgmeData seckey)
|
||||
{
|
||||
GpgmeError err = gpgme_op_genkey_start (ctx, parms, pubkey, seckey);
|
||||
GpgmeError err = _gpgme_op_genkey_start (ctx, 1, parms, pubkey, seckey);
|
||||
if (!err)
|
||||
gpgme_wait (ctx, &err, 1);
|
||||
err = _gpgme_wait_one (ctx);
|
||||
return err;
|
||||
}
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include "util.h"
|
||||
#include "context.h"
|
||||
#include "ops.h"
|
||||
|
||||
#include "wait.h"
|
||||
|
||||
/**
|
||||
* gpgme_new:
|
||||
@ -53,8 +53,8 @@ gpgme_new (GpgmeCtx *r_ctx)
|
||||
ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
|
||||
ctx->verbosity = 1;
|
||||
ctx->include_certs = 1;
|
||||
_gpgme_fd_table_init (&ctx->fdt);
|
||||
*r_ctx = ctx;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -71,6 +71,7 @@ gpgme_release (GpgmeCtx ctx)
|
||||
if (!ctx)
|
||||
return;
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
_gpgme_fd_table_deinit (&ctx->fdt);
|
||||
_gpgme_release_result (ctx);
|
||||
gpgme_key_release (ctx->tmp_key);
|
||||
gpgme_data_release (ctx->help_data_1);
|
||||
@ -471,7 +472,8 @@ gpgme_set_progress_cb (GpgmeCtx ctx, GpgmeProgressCb cb, void *cb_value)
|
||||
* @r_cb: The current callback function
|
||||
* @r_cb_value: The current value passed to the callback function
|
||||
*
|
||||
* This function returns the callback function to be used as a progress indicator.
|
||||
* This function returns the callback function to be used as a
|
||||
* progress indicator.
|
||||
**/
|
||||
void
|
||||
gpgme_get_progress_cb (GpgmeCtx ctx, GpgmeProgressCb *r_cb, void **r_cb_value)
|
||||
@ -491,3 +493,59 @@ gpgme_get_progress_cb (GpgmeCtx ctx, GpgmeProgressCb *r_cb, void **r_cb_value)
|
||||
*r_cb_value = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gpgme_set_io_cbs:
|
||||
* @ctx: the context
|
||||
* @register_io_cb: A callback function
|
||||
* @register_hook_value: The value passed to the callback function
|
||||
* @remove_io_cb: Another callback function
|
||||
*
|
||||
**/
|
||||
void
|
||||
gpgme_set_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs)
|
||||
{
|
||||
if (ctx && io_cbs)
|
||||
ctx->io_cbs = *io_cbs;
|
||||
else
|
||||
{
|
||||
ctx->io_cbs.add = NULL;
|
||||
ctx->io_cbs.add_priv = NULL;
|
||||
ctx->io_cbs.remove = NULL;
|
||||
ctx->io_cbs.event = NULL;
|
||||
ctx->io_cbs.event_priv = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gpgme_get_io_cbs:
|
||||
* @ctx: the context
|
||||
* @r_register_cb: The current register callback function
|
||||
* @r_register_cb_value: The current value passed to the
|
||||
* register callback function
|
||||
* @r_remove_cb: The current remove callback function
|
||||
*
|
||||
* This function returns the callback function to be used to pass a passphrase
|
||||
* to the crypto engine.
|
||||
**/
|
||||
void
|
||||
gpgme_get_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs)
|
||||
{
|
||||
if (ctx && io_cbs)
|
||||
*io_cbs = ctx->io_cbs;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gpgme_op_event_cb (void *data, GpgmeEventIO type, void *type_data)
|
||||
{
|
||||
GpgmeCtx ctx = data;
|
||||
|
||||
if (type == GPGME_EVENT_DONE)
|
||||
ctx->pending = 0;
|
||||
|
||||
if (ctx->io_cbs.add && ctx->io_cbs.event)
|
||||
(*ctx->io_cbs.event) (ctx->io_cbs.event_priv, type, type_data);
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ extern "C" {
|
||||
AM_PATH_GPGME macro) check that this header matches the installed
|
||||
library. Warning: Do not edit the next line. configure will do
|
||||
that for you! */
|
||||
#define GPGME_VERSION "0.3.7-cvs"
|
||||
#define GPGME_VERSION "0.3.8-cvs"
|
||||
|
||||
|
||||
/* The opaque data types used by GPGME. */
|
||||
@ -316,6 +316,46 @@ char *gpgme_get_op_info (GpgmeCtx ctx, int reserved);
|
||||
|
||||
/* Run control. */
|
||||
|
||||
/* The type of an I/O callback function. */
|
||||
typedef void (*GpgmeIOCb) (void *data, int fd);
|
||||
|
||||
/* The type of a function that can register FNC as the I/O callback
|
||||
function for the file descriptor FD with direction dir (0: inbound,
|
||||
1: outbound). FNC_DATA should be passed as DATA to FNC. The
|
||||
function should return a TAG suitable for the corresponding
|
||||
GpgmeRemoveIOCb. */
|
||||
typedef void *(*GpgmeRegisterIOCb) (void *data, int fd, int dir,
|
||||
GpgmeIOCb fnc, void *fnc_data);
|
||||
|
||||
/* The type of a function that can remove a previously registered I/O
|
||||
callback function given TAG as returned by the register
|
||||
function. */
|
||||
typedef void (*GpgmeRemoveIOCb) (void *tag);
|
||||
|
||||
typedef enum { GPGME_EVENT_DONE,
|
||||
GPGME_EVENT_NEXT_KEY,
|
||||
GPGME_EVENT_NEXT_TRUSTITEM } GpgmeEventIO;
|
||||
|
||||
/* The type of a function that is called when a context finished an
|
||||
operation. */
|
||||
typedef void (*GpgmeEventIOCb) (void *data, GpgmeEventIO type,
|
||||
void *type_data);
|
||||
|
||||
struct GpgmeIOCbs
|
||||
{
|
||||
GpgmeRegisterIOCb add;
|
||||
void *add_priv;
|
||||
GpgmeRemoveIOCb remove;
|
||||
GpgmeEventIOCb event;
|
||||
void *event_priv;
|
||||
};
|
||||
|
||||
/* Set the I/O callback functions in CTX to IO_CBS. */
|
||||
void gpgme_set_op_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs);
|
||||
|
||||
/* Get the current I/O callback functions. */
|
||||
void gpgme_get_op_io_cbs (GpgmeCtx ctx, struct GpgmeIOCbs *io_cbs);
|
||||
|
||||
/* Cancel a pending operation in CTX. */
|
||||
void gpgme_cancel (GpgmeCtx ctx);
|
||||
|
||||
|
@ -162,18 +162,12 @@ import_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
||||
}
|
||||
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_import_start (GpgmeCtx ctx, GpgmeData keydata)
|
||||
static GpgmeError
|
||||
_gpgme_op_import_start (GpgmeCtx ctx, int synchronous, GpgmeData keydata)
|
||||
{
|
||||
int err = 0;
|
||||
|
||||
fail_on_pending_request (ctx);
|
||||
ctx->pending = 1;
|
||||
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
ctx->engine = NULL;
|
||||
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
|
||||
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
|
||||
err = _gpgme_op_reset (ctx, synchronous);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
@ -204,6 +198,12 @@ gpgme_op_import_start (GpgmeCtx ctx, GpgmeData keydata)
|
||||
}
|
||||
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_import_start (GpgmeCtx ctx, GpgmeData keydata)
|
||||
{
|
||||
return _gpgme_op_import_start (ctx, 0, keydata);
|
||||
}
|
||||
|
||||
/**
|
||||
* gpgme_op_import:
|
||||
* @c: Context
|
||||
@ -216,8 +216,8 @@ gpgme_op_import_start (GpgmeCtx ctx, GpgmeData keydata)
|
||||
GpgmeError
|
||||
gpgme_op_import (GpgmeCtx ctx, GpgmeData keydata)
|
||||
{
|
||||
GpgmeError err = gpgme_op_import_start (ctx, keydata);
|
||||
GpgmeError err = _gpgme_op_import_start (ctx, 1, keydata);
|
||||
if (!err)
|
||||
gpgme_wait (ctx, &err, 1);
|
||||
err = _gpgme_wait_one (ctx);
|
||||
return err;
|
||||
}
|
||||
|
70
gpgme/io.h
70
gpgme/io.h
@ -1,6 +1,6 @@
|
||||
/* io.h - I/O functions
|
||||
/* io.h - Interface to the I/O functions.
|
||||
* Copyright (C) 2000 Werner Koch (dd9jn)
|
||||
* Copyright (C) 2001 g10 Code GmbH
|
||||
* Copyright (C) 2001, 2002 g10 Code GmbH
|
||||
*
|
||||
* This file is part of GPGME.
|
||||
*
|
||||
@ -24,48 +24,44 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
struct spawn_fd_item_s {
|
||||
int fd;
|
||||
int dup_to;
|
||||
/* A single file descriptor passed to spawn. For child fds, dup_to
|
||||
specifies the fd it should become in the child. */
|
||||
struct spawn_fd_item_s
|
||||
{
|
||||
int fd;
|
||||
int dup_to;
|
||||
};
|
||||
|
||||
|
||||
struct io_select_fd_s {
|
||||
int fd;
|
||||
int is_closed;
|
||||
int for_read;
|
||||
int for_write;
|
||||
int signaled;
|
||||
int frozen;
|
||||
void *opaque;
|
||||
struct io_select_fd_s
|
||||
{
|
||||
int fd;
|
||||
int for_read;
|
||||
int for_write;
|
||||
int signaled;
|
||||
int frozen;
|
||||
void *opaque;
|
||||
};
|
||||
|
||||
/* These function are either defined in posix-io.c or w32-io.c. */
|
||||
int _gpgme_io_read (int fd, void *buffer, size_t count);
|
||||
int _gpgme_io_write (int fd, const void *buffer, size_t count);
|
||||
int _gpgme_io_pipe (int filedes[2], int inherit_idx);
|
||||
int _gpgme_io_close (int fd);
|
||||
int _gpgme_io_set_close_notify (int fd, void (*handler) (int, void *),
|
||||
void *value);
|
||||
int _gpgme_io_set_nonblocking (int fd);
|
||||
|
||||
/* These function are either defined in posix-io.c or w32-io.c */
|
||||
|
||||
int _gpgme_io_read ( int fd, void *buffer, size_t count );
|
||||
int _gpgme_io_write ( int fd, const void *buffer, size_t count );
|
||||
int _gpgme_io_pipe ( int filedes[2], int inherit_idx );
|
||||
int _gpgme_io_close ( int fd );
|
||||
int _gpgme_io_set_close_notify (int fd,
|
||||
void (*handler)(int, void*), void *value);
|
||||
int _gpgme_io_set_nonblocking ( int fd );
|
||||
int _gpgme_io_spawn ( const char *path, char **argv,
|
||||
struct spawn_fd_item_s *fd_child_list,
|
||||
struct spawn_fd_item_s *fd_parent_list );
|
||||
int _gpgme_io_waitpid ( int pid, int hang, int *r_status, int *r_signal );
|
||||
int _gpgme_io_kill ( int pid, int hard );
|
||||
int _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Spawn the executable PATH with ARGV as arguments, after forking
|
||||
close all fds in FD_PARENT_LIST in the parent and close or dup all
|
||||
fds in FD_CHILD_LIST in the child. */
|
||||
int _gpgme_io_spawn (const char *path, char **argv,
|
||||
struct spawn_fd_item_s *fd_child_list,
|
||||
struct spawn_fd_item_s *fd_parent_list);
|
||||
int _gpgme_io_waitpid (int pid, int hang, int *r_status, int *r_signal);
|
||||
int _gpgme_io_kill (int pid, int hard);
|
||||
int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds);
|
||||
|
||||
#endif /* IO_H */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
111
gpgme/keylist.c
111
gpgme/keylist.c
@ -236,47 +236,51 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
||||
/* Start a new keyblock. */
|
||||
if (_gpgme_key_new (&key))
|
||||
{
|
||||
ctx->error = mk_error (Out_Of_Core); /* the only kind of error we can get*/
|
||||
/* The only kind of error we can get. */
|
||||
ctx->error = mk_error (Out_Of_Core);
|
||||
return;
|
||||
}
|
||||
rectype = RT_PUB;
|
||||
finish_key (ctx);
|
||||
assert (!ctx->tmp_key);
|
||||
ctx->tmp_key = key;
|
||||
rectype = RT_PUB;
|
||||
finish_key (ctx);
|
||||
assert (!ctx->tmp_key);
|
||||
ctx->tmp_key = key;
|
||||
}
|
||||
else if (!strcmp (p, "sec"))
|
||||
{
|
||||
/* Start a new keyblock, */
|
||||
if (_gpgme_key_new_secret (&key))
|
||||
{
|
||||
ctx->error = mk_error (Out_Of_Core); /* The only kind of error we can get*/
|
||||
return;
|
||||
}
|
||||
rectype = RT_SEC;
|
||||
finish_key (ctx);
|
||||
assert (!ctx->tmp_key);
|
||||
ctx->tmp_key = key;
|
||||
else if (!strcmp (p, "sec"))
|
||||
{
|
||||
/* Start a new keyblock, */
|
||||
if (_gpgme_key_new_secret (&key))
|
||||
{
|
||||
/* The only kind of error we can get. */
|
||||
ctx->error = mk_error (Out_Of_Core);
|
||||
return;
|
||||
}
|
||||
rectype = RT_SEC;
|
||||
finish_key (ctx);
|
||||
assert (!ctx->tmp_key);
|
||||
ctx->tmp_key = key;
|
||||
}
|
||||
else if (!strcmp (p, "crt"))
|
||||
{
|
||||
/* Start a new certificate. */
|
||||
if (_gpgme_key_new (&key))
|
||||
{
|
||||
ctx->error = mk_error (Out_Of_Core); /* The only kind of error we can get*/
|
||||
return;
|
||||
}
|
||||
key->x509 = 1;
|
||||
rectype = RT_CRT;
|
||||
finish_key (ctx);
|
||||
assert (!ctx->tmp_key);
|
||||
ctx->tmp_key = key;
|
||||
else if (!strcmp (p, "crt"))
|
||||
{
|
||||
/* Start a new certificate. */
|
||||
if (_gpgme_key_new (&key))
|
||||
{
|
||||
/* The only kind of error we can get. */
|
||||
ctx->error = mk_error (Out_Of_Core);
|
||||
return;
|
||||
}
|
||||
key->x509 = 1;
|
||||
rectype = RT_CRT;
|
||||
finish_key (ctx);
|
||||
assert (!ctx->tmp_key);
|
||||
ctx->tmp_key = key;
|
||||
}
|
||||
else if (!strcmp (p, "crs"))
|
||||
{
|
||||
/* Start a new certificate. */
|
||||
if (_gpgme_key_new_secret (&key))
|
||||
{
|
||||
ctx->error = mk_error (Out_Of_Core); /* The only kind of error we can get*/
|
||||
/* The only kind of error we can get. */
|
||||
ctx->error = mk_error (Out_Of_Core);
|
||||
return;
|
||||
}
|
||||
key->x509 = 1;
|
||||
@ -289,7 +293,6 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
||||
rectype = RT_FPR;
|
||||
else
|
||||
rectype = RT_NONE;
|
||||
|
||||
}
|
||||
else if (rectype == RT_PUB || rectype == RT_SEC
|
||||
|| rectype == RT_CRT || rectype == RT_CRS)
|
||||
@ -401,7 +404,8 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
||||
break;
|
||||
case 10: /* user ID */
|
||||
if (_gpgme_key_append_name (key, p))
|
||||
ctx->error = mk_error (Out_Of_Core); /* The only kind of error we can get*/
|
||||
/* The only kind of error we can get*/
|
||||
ctx->error = mk_error (Out_Of_Core);
|
||||
else
|
||||
{
|
||||
if (trust_info)
|
||||
@ -495,25 +499,13 @@ gpgme_op_keylist_start (GpgmeCtx ctx, const char *pattern, int secret_only)
|
||||
{
|
||||
GpgmeError err = 0;
|
||||
|
||||
if (!ctx)
|
||||
return mk_error (Invalid_Value);
|
||||
ctx->pending = 1;
|
||||
err = _gpgme_op_reset (ctx, 0);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
_gpgme_release_result (ctx);
|
||||
|
||||
if (ctx->engine)
|
||||
{
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
ctx->engine = NULL;
|
||||
}
|
||||
gpgme_key_release (ctx->tmp_key);
|
||||
ctx->tmp_key = NULL;
|
||||
/* Fixme: Release key_queue. */
|
||||
|
||||
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
|
||||
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
_gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
|
||||
err = _gpgme_engine_set_colon_line_handler (ctx->engine,
|
||||
@ -526,7 +518,8 @@ gpgme_op_keylist_start (GpgmeCtx ctx, const char *pattern, int secret_only)
|
||||
just ignore those lines - This should speed up things */
|
||||
_gpgme_engine_set_verbosity (ctx->engine, 0);
|
||||
|
||||
err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only, ctx->keylist_mode);
|
||||
err = _gpgme_engine_op_keylist (ctx->engine, pattern, secret_only,
|
||||
ctx->keylist_mode);
|
||||
|
||||
if (!err) /* And kick off the process. */
|
||||
err = _gpgme_engine_start (ctx->engine, ctx);
|
||||
@ -561,26 +554,12 @@ gpgme_op_keylist_ext_start (GpgmeCtx ctx, const char *pattern[],
|
||||
{
|
||||
GpgmeError err = 0;
|
||||
|
||||
if (!ctx)
|
||||
return mk_error (Invalid_Value);
|
||||
ctx->pending = 1;
|
||||
|
||||
_gpgme_release_result (ctx);
|
||||
|
||||
if (ctx->engine)
|
||||
{
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
ctx->engine = NULL;
|
||||
}
|
||||
gpgme_key_release (ctx->tmp_key);
|
||||
ctx->tmp_key = NULL;
|
||||
/* Fixme: Release key_queue. */
|
||||
|
||||
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
|
||||
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
|
||||
err = _gpgme_op_reset (ctx, 0);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
gpgme_key_release (ctx->tmp_key);
|
||||
|
||||
_gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
|
||||
err = _gpgme_engine_set_colon_line_handler (ctx->engine,
|
||||
keylist_colon_handler, ctx);
|
||||
|
70
gpgme/op-support.c
Normal file
70
gpgme/op-support.c
Normal file
@ -0,0 +1,70 @@
|
||||
/* op-support.c
|
||||
* Copyright (C) 2002 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 General Public License as published by
|
||||
* the Free Software Foundation; either version 2 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "gpgme.h"
|
||||
#include "context.h"
|
||||
#include "ops.h"
|
||||
|
||||
GpgmeError
|
||||
_gpgme_op_reset (GpgmeCtx ctx, int synchronous)
|
||||
{
|
||||
GpgmeError err = 0;
|
||||
struct GpgmeIOCbs io_cbs;
|
||||
|
||||
fail_on_pending_request (ctx);
|
||||
ctx->pending = 1;
|
||||
|
||||
_gpgme_release_result (ctx);
|
||||
|
||||
/* Create an engine object. */
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
ctx->engine = NULL;
|
||||
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
|
||||
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (synchronous)
|
||||
{
|
||||
io_cbs.add = _gpgme_add_io_cb;
|
||||
io_cbs.add_priv = &ctx->fdt;
|
||||
io_cbs.remove = _gpgme_remove_io_cb;
|
||||
io_cbs.event = _gpgme_op_event_cb;
|
||||
io_cbs.event_priv = ctx;
|
||||
}
|
||||
else if (! ctx->io_cbs.add)
|
||||
{
|
||||
io_cbs.add = _gpgme_add_io_cb;
|
||||
io_cbs.add_priv = NULL;
|
||||
io_cbs.remove = _gpgme_remove_io_cb;
|
||||
io_cbs.event = _gpgme_wait_event_cb;
|
||||
io_cbs.event_priv = ctx;
|
||||
}
|
||||
else
|
||||
{
|
||||
io_cbs = ctx->io_cbs;
|
||||
io_cbs.event = _gpgme_op_event_cb;
|
||||
io_cbs.event_priv = ctx;
|
||||
}
|
||||
_gpgme_engine_set_io_cbs (ctx->engine, &io_cbs);
|
||||
return err;
|
||||
}
|
15
gpgme/ops.h
15
gpgme/ops.h
@ -46,12 +46,11 @@
|
||||
void _gpgme_release_result ( GpgmeCtx c );
|
||||
void _gpgme_set_op_info (GpgmeCtx c, GpgmeData info);
|
||||
|
||||
void _gpgme_op_event_cb (void *data, GpgmeEventIO type, void *type_data);
|
||||
|
||||
/*-- wait.c --*/
|
||||
GpgmeCtx _gpgme_wait_on_condition ( GpgmeCtx c,
|
||||
int hang, volatile int *cond );
|
||||
void _gpgme_freeze_fd ( int fd );
|
||||
void _gpgme_thaw_fd ( int fd );
|
||||
|
||||
|
||||
/*-- recipient.c --*/
|
||||
int _gpgme_recipients_all_valid ( const GpgmeRecipients rset );
|
||||
@ -76,14 +75,15 @@ GpgmeError _gpgme_data_append_percentstring_for_xml ( GpgmeData dh,
|
||||
GpgmeError _gpgme_data_unread (GpgmeData dh,
|
||||
const char *buffer, size_t length );
|
||||
|
||||
int _gpgme_data_inbound_handler (void *opaque, int pid, int fd);
|
||||
int _gpgme_data_outbound_handler (void *opaque, int pid, int fd);
|
||||
|
||||
void _gpgme_data_inbound_handler (void *opaque, int fd);
|
||||
void _gpgme_data_outbound_handler (void *opaque, int fd);
|
||||
|
||||
/*-- key.c --*/
|
||||
GpgmeError _gpgme_key_new ( GpgmeKey *r_key );
|
||||
GpgmeError _gpgme_key_new_secret ( GpgmeKey *r_key );
|
||||
|
||||
/*-- op-support.c --*/
|
||||
GpgmeError _gpgme_op_reset (GpgmeCtx ctx, int synchronous);
|
||||
|
||||
/*-- verify.c --*/
|
||||
void _gpgme_release_verify_result (VerifyResult result);
|
||||
@ -95,7 +95,8 @@ void _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code,
|
||||
void _gpgme_release_decrypt_result (DecryptResult result);
|
||||
void _gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code,
|
||||
char *args);
|
||||
GpgmeError _gpgme_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain,
|
||||
GpgmeError _gpgme_decrypt_start (GpgmeCtx ctx, int synchronous,
|
||||
GpgmeData ciph, GpgmeData plain,
|
||||
void *status_handler);
|
||||
GpgmeError _gpgme_decrypt_result (GpgmeCtx ctx);
|
||||
|
||||
|
1092
gpgme/rungpg.c
1092
gpgme/rungpg.c
File diff suppressed because it is too large
Load Diff
@ -159,5 +159,6 @@ GpgmeError _gpgme_gpg_op_sign (GpgObject gpg, GpgmeData in, GpgmeData out,
|
||||
GpgmeError _gpgme_gpg_op_trustlist (GpgObject gpg, const char *pattern);
|
||||
GpgmeError _gpgme_gpg_op_verify (GpgObject gpg, GpgmeData sig, GpgmeData text);
|
||||
GpgmeError _gpgme_gpg_spawn (GpgObject gpg, void *opaque);
|
||||
void _gpgme_gpg_set_io_cbs (GpgObject gpg, struct GpgmeIOCbs *io_cbs);
|
||||
|
||||
#endif /* RUNGPG_H */
|
||||
|
31
gpgme/sign.c
31
gpgme/sign.c
@ -168,27 +168,19 @@ _gpgme_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
||||
}
|
||||
}
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_sign_start (GpgmeCtx ctx, GpgmeData in, GpgmeData out,
|
||||
GpgmeSigMode mode)
|
||||
static GpgmeError
|
||||
_gpgme_op_sign_start (GpgmeCtx ctx, int synchronous,
|
||||
GpgmeData in, GpgmeData out,
|
||||
GpgmeSigMode mode)
|
||||
{
|
||||
GpgmeError err = 0;
|
||||
|
||||
fail_on_pending_request (ctx);
|
||||
ctx->pending = 1;
|
||||
|
||||
_gpgme_release_result (ctx);
|
||||
|
||||
if (mode != GPGME_SIG_MODE_NORMAL
|
||||
&& mode != GPGME_SIG_MODE_DETACH
|
||||
&& mode != GPGME_SIG_MODE_CLEAR)
|
||||
return mk_error (Invalid_Value);
|
||||
|
||||
/* Create a process object. */
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
ctx->engine = NULL;
|
||||
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
|
||||
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
|
||||
|
||||
err = _gpgme_op_reset (ctx, synchronous);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
@ -231,6 +223,13 @@ gpgme_op_sign_start (GpgmeCtx ctx, GpgmeData in, GpgmeData out,
|
||||
return err;
|
||||
}
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_sign_start (GpgmeCtx ctx, GpgmeData in, GpgmeData out,
|
||||
GpgmeSigMode mode)
|
||||
{
|
||||
return _gpgme_op_sign_start (ctx, 0, in, out, mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* gpgme_op_sign:
|
||||
* @ctx: The context
|
||||
@ -255,8 +254,8 @@ gpgme_op_sign_start (GpgmeCtx ctx, GpgmeData in, GpgmeData out,
|
||||
GpgmeError
|
||||
gpgme_op_sign (GpgmeCtx ctx, GpgmeData in, GpgmeData out, GpgmeSigMode mode)
|
||||
{
|
||||
GpgmeError err = gpgme_op_sign_start (ctx, in, out, mode);
|
||||
GpgmeError err = _gpgme_op_sign_start (ctx, 1, in, out, mode);
|
||||
if (!err)
|
||||
gpgme_wait (ctx, &err, 1);
|
||||
err = _gpgme_wait_one (ctx);
|
||||
return err;
|
||||
}
|
||||
|
@ -164,26 +164,13 @@ gpgme_op_trustlist_start (GpgmeCtx ctx, const char *pattern, int max_level)
|
||||
{
|
||||
GpgmeError err = 0;
|
||||
|
||||
fail_on_pending_request (ctx);
|
||||
if (!pattern || !*pattern)
|
||||
return mk_error (Invalid_Value);
|
||||
|
||||
ctx->pending = 1;
|
||||
|
||||
if (ctx->engine)
|
||||
{
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
ctx->engine = NULL;
|
||||
}
|
||||
|
||||
_gpgme_release_result (ctx);
|
||||
|
||||
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
|
||||
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
|
||||
err = _gpgme_op_reset (ctx, 0);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
_gpgme_engine_set_status_handler (ctx->engine, trustlist_status_handler, ctx);
|
||||
err = _gpgme_engine_set_colon_line_handler (ctx->engine,
|
||||
trustlist_colon_handler, ctx);
|
||||
if (err)
|
||||
|
@ -282,26 +282,18 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
||||
}
|
||||
}
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_verify_start (GpgmeCtx ctx, GpgmeData sig, GpgmeData text)
|
||||
static GpgmeError
|
||||
_gpgme_op_verify_start (GpgmeCtx ctx, int synchronous,
|
||||
GpgmeData sig, GpgmeData text)
|
||||
{
|
||||
int err = 0;
|
||||
int pipemode = 0; /* !!text; use pipemode for detached sigs. */
|
||||
|
||||
fail_on_pending_request (ctx);
|
||||
ctx->pending = 1;
|
||||
|
||||
_gpgme_release_result (ctx);
|
||||
|
||||
if (!pipemode)
|
||||
{
|
||||
_gpgme_engine_release (ctx->engine);
|
||||
ctx->engine = NULL;
|
||||
}
|
||||
; /* XXX I am not sure what should happen/not happen in
|
||||
pipemode. */
|
||||
|
||||
if (!ctx->engine)
|
||||
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
|
||||
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
|
||||
err = _gpgme_op_reset (ctx, synchronous);
|
||||
if (err)
|
||||
goto leave;
|
||||
|
||||
@ -347,6 +339,12 @@ gpgme_op_verify_start (GpgmeCtx ctx, GpgmeData sig, GpgmeData text)
|
||||
return err;
|
||||
}
|
||||
|
||||
GpgmeError
|
||||
gpgme_op_verify_start (GpgmeCtx ctx, GpgmeData sig, GpgmeData text)
|
||||
{
|
||||
return _gpgme_op_verify_start (ctx, 0, sig, text);
|
||||
}
|
||||
|
||||
/*
|
||||
* Figure out a common status value for all signatures
|
||||
*/
|
||||
@ -408,10 +406,10 @@ gpgme_op_verify (GpgmeCtx ctx, GpgmeData sig, GpgmeData text,
|
||||
ctx->notation = NULL;
|
||||
|
||||
*r_stat = GPGME_SIG_STAT_NONE;
|
||||
err = gpgme_op_verify_start (ctx, sig, text);
|
||||
err = _gpgme_op_verify_start (ctx, 1, sig, text);
|
||||
if (!err)
|
||||
{
|
||||
gpgme_wait (ctx, &err, 1);
|
||||
err = _gpgme_wait_one (ctx);
|
||||
if (!err)
|
||||
*r_stat = _gpgme_intersect_stati (ctx->result.verify);
|
||||
}
|
||||
|
640
gpgme/wait.c
640
gpgme/wait.c
@ -35,389 +35,84 @@
|
||||
#include "io.h"
|
||||
#include "engine.h"
|
||||
|
||||
struct wait_item_s;
|
||||
struct proc_s;
|
||||
struct fd_table fdt_global;
|
||||
|
||||
static struct proc_s *proc_queue;
|
||||
DEFINE_STATIC_LOCK (proc_queue_lock);
|
||||
|
||||
static int fd_table_size;
|
||||
static struct io_select_fd_s *fd_table;
|
||||
DEFINE_STATIC_LOCK (fd_table_lock);
|
||||
static GpgmeCtx *ctx_done_list;
|
||||
static int ctx_done_list_size;
|
||||
static int ctx_done_list_length;
|
||||
DEFINE_STATIC_LOCK (ctx_done_list_lock);
|
||||
|
||||
static GpgmeIdleFunc idle_function;
|
||||
|
||||
|
||||
struct proc_s
|
||||
struct wait_item_s
|
||||
{
|
||||
struct proc_s *next;
|
||||
int pid;
|
||||
GpgmeCtx ctx;
|
||||
struct wait_item_s *handler_list;
|
||||
/* Non-zero if the process has been completed. */
|
||||
int done;
|
||||
/* Non-zero if the status for this process has been returned
|
||||
already. */
|
||||
int reported;
|
||||
struct wait_item_s *next;
|
||||
GpgmeIOCb handler;
|
||||
void *handler_value;
|
||||
int dir;
|
||||
};
|
||||
|
||||
struct wait_item_s {
|
||||
struct wait_item_s *next;
|
||||
int (*handler)(void*,int,int);
|
||||
void *handler_value;
|
||||
int inbound; /* this is an inbound data handler fd */
|
||||
struct proc_s *proc; /* backlink */
|
||||
int done;
|
||||
int frozen; /* copy of the frozen flag from the fd_table */
|
||||
};
|
||||
|
||||
|
||||
|
||||
static int do_select ( void );
|
||||
static void run_idle (void);
|
||||
|
||||
|
||||
/* only to be called with a locked proc_queue */
|
||||
static int
|
||||
count_running_fds (struct proc_s *proc)
|
||||
|
||||
void
|
||||
_gpgme_fd_table_init (fd_table_t fdt)
|
||||
{
|
||||
struct wait_item_s *q;
|
||||
int count = 0;
|
||||
|
||||
for (q = proc->handler_list; q; q=q->next)
|
||||
{
|
||||
if (!q->frozen && !q->done)
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* only to be called with a locked proc_queue */
|
||||
static void
|
||||
set_process_done (struct proc_s *proc)
|
||||
{
|
||||
struct wait_item_s *q, *q2;
|
||||
int i;
|
||||
|
||||
assert (proc);
|
||||
DEBUG2 ("set_process_done(%p) pid=%d", proc, proc->pid);
|
||||
LOCK (fd_table_lock);
|
||||
for (q = proc->handler_list; q; q=q2)
|
||||
{
|
||||
q2 = q->next;
|
||||
for (i = 0; i < fd_table_size; i++)
|
||||
{
|
||||
if (fd_table[i].fd != -1 && q == fd_table[i].opaque)
|
||||
{
|
||||
fd_table[i].opaque = NULL;
|
||||
fd_table[i].fd = -1;
|
||||
}
|
||||
}
|
||||
xfree (q);
|
||||
}
|
||||
UNLOCK (fd_table_lock);
|
||||
proc->handler_list = NULL;
|
||||
proc->done = 1;
|
||||
INIT_LOCK (fdt->lock);
|
||||
fdt->fds = NULL;
|
||||
fdt->size = 0;
|
||||
}
|
||||
|
||||
void
|
||||
_gpgme_remove_proc_from_wait_queue (int pid)
|
||||
_gpgme_fd_table_deinit (fd_table_t fdt)
|
||||
{
|
||||
struct proc_s *proc, *last;
|
||||
|
||||
DEBUG1 ("removing process %d", pid);
|
||||
LOCK (proc_queue_lock);
|
||||
for (last = NULL, proc = proc_queue; proc; last = proc, proc = proc->next)
|
||||
{
|
||||
if (proc->pid == pid)
|
||||
{
|
||||
set_process_done (proc);
|
||||
if (!last)
|
||||
proc_queue = proc->next;
|
||||
else
|
||||
last->next = proc->next;
|
||||
xfree (proc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
UNLOCK (proc_queue_lock);
|
||||
DESTROY_LOCK (fdt->lock);
|
||||
if (fdt->fds)
|
||||
xfree (fdt->fds);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gpgme_wait:
|
||||
* @c:
|
||||
* @hang:
|
||||
*
|
||||
* Wait for a finished request, if @c is given the function does only
|
||||
* wait on a finished request for that context, otherwise it will return
|
||||
* on any request. When @hang is true the function will wait, otherwise
|
||||
* it will return immediately when there is no pending finished request.
|
||||
*
|
||||
* Return value: Context of the finished request or NULL if @hang is false
|
||||
* and no (or the given) request has finished.
|
||||
**/
|
||||
GpgmeCtx
|
||||
gpgme_wait (GpgmeCtx ctx, GpgmeError *status, int hang)
|
||||
{
|
||||
GpgmeCtx retctx = _gpgme_wait_on_condition (ctx, hang, NULL);
|
||||
if (status)
|
||||
*status = retctx->error;
|
||||
return retctx;
|
||||
}
|
||||
|
||||
GpgmeCtx
|
||||
_gpgme_wait_on_condition (GpgmeCtx ctx, int hang, volatile int *cond)
|
||||
{
|
||||
DEBUG3 ("waiting... ctx=%p hang=%d cond=%p", ctx, hang, cond);
|
||||
do
|
||||
{
|
||||
int any = 0;
|
||||
struct proc_s *proc;
|
||||
|
||||
do_select ();
|
||||
|
||||
if (cond && *cond)
|
||||
hang = 0;
|
||||
else
|
||||
{
|
||||
LOCK (proc_queue_lock);
|
||||
for (proc = proc_queue; proc; proc = proc->next)
|
||||
{
|
||||
/* A process is done if it has completed voluntarily, or
|
||||
if the context it lived in was canceled. */
|
||||
if (!proc->done && !count_running_fds (proc))
|
||||
set_process_done (proc);
|
||||
else if (!proc->done && proc->ctx->cancel)
|
||||
{
|
||||
set_process_done (proc);
|
||||
proc->ctx->cancel = 0;
|
||||
proc->ctx->error = mk_error (Canceled);
|
||||
}
|
||||
/* A process that is done is eligible for election if it
|
||||
is in the requested context or if it was not yet
|
||||
reported. */
|
||||
if (proc->done && (proc->ctx == ctx || (!ctx && !proc->reported)))
|
||||
{
|
||||
if (!ctx)
|
||||
ctx = proc->ctx;
|
||||
hang = 0;
|
||||
ctx->pending = 0;
|
||||
proc->reported = 1;
|
||||
}
|
||||
if (!proc->done)
|
||||
any = 1;
|
||||
}
|
||||
UNLOCK (proc_queue_lock);
|
||||
if (!any)
|
||||
hang = 0;
|
||||
}
|
||||
/* fixme: We should check here for hanging processes. */
|
||||
|
||||
if (hang)
|
||||
run_idle ();
|
||||
}
|
||||
while (hang && (!ctx || !ctx->cancel));
|
||||
if (ctx && ctx->cancel)
|
||||
{
|
||||
/* FIXME: Paranoia? */
|
||||
ctx->cancel = 0;
|
||||
ctx->pending = 0;
|
||||
ctx->error = mk_error (Canceled);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* We use this function to do the select stuff for all running
|
||||
* gpgs. A future version might provide a facility to delegate
|
||||
* those selects to the GDK select stuff.
|
||||
* This function must be called only by one thread!!
|
||||
* Returns: 0 = nothing to run
|
||||
* 1 = did run something
|
||||
*/
|
||||
|
||||
static int
|
||||
do_select (void)
|
||||
{
|
||||
int i, n;
|
||||
int any = 0;
|
||||
|
||||
n = _gpgme_io_select (fd_table, fd_table_size);
|
||||
if (n <= 0)
|
||||
return 0; /* error or timeout */
|
||||
|
||||
for (i = 0; i < fd_table_size && n; i++)
|
||||
{
|
||||
if (fd_table[i].fd != -1 && fd_table[i].signaled
|
||||
&& !fd_table[i].frozen)
|
||||
{
|
||||
struct wait_item_s *q;
|
||||
|
||||
assert (n);
|
||||
n--;
|
||||
|
||||
q = fd_table[i].opaque;
|
||||
assert (q);
|
||||
assert (q->proc);
|
||||
assert (!q->done);
|
||||
any = 1;
|
||||
if (q->handler (q->handler_value,
|
||||
q->proc->pid, fd_table[i].fd))
|
||||
{
|
||||
DEBUG2 ("setting fd %d (q=%p) done", fd_table[i].fd, q);
|
||||
q->done = 1;
|
||||
/* Free the table entry. */
|
||||
LOCK (fd_table_lock);
|
||||
fd_table[i].for_read = 0;
|
||||
fd_table[i].for_write = 0;
|
||||
fd_table[i].fd = -1;
|
||||
fd_table[i].opaque = NULL;
|
||||
UNLOCK (fd_table_lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return any;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* called by rungpg.c to register something for select()
|
||||
*/
|
||||
/* XXX We should keep a marker and roll over for speed. */
|
||||
GpgmeError
|
||||
_gpgme_register_pipe_handler (void *opaque,
|
||||
int (*handler)(void*,int,int),
|
||||
void *handler_value,
|
||||
int pid, int fd, int inbound)
|
||||
_gpgme_fd_table_put (fd_table_t fdt, int fd, int dir, void *opaque, int *idx)
|
||||
{
|
||||
GpgmeCtx ctx = opaque;
|
||||
struct wait_item_s *q;
|
||||
struct proc_s *proc;
|
||||
int i;
|
||||
int i, j;
|
||||
struct io_select_fd_s *new_fds;
|
||||
|
||||
assert (opaque);
|
||||
assert (handler);
|
||||
|
||||
/* Allocate a structure to hold info about the handler. */
|
||||
q = xtrycalloc (1, sizeof *q);
|
||||
if (!q)
|
||||
return mk_error (Out_Of_Core);
|
||||
q->inbound = inbound;
|
||||
q->handler = handler;
|
||||
q->handler_value = handler_value;
|
||||
|
||||
/* Put this into the process queue. */
|
||||
LOCK (proc_queue_lock);
|
||||
for (proc = proc_queue; proc && proc->pid != pid; proc = proc->next)
|
||||
;
|
||||
if (!proc)
|
||||
LOCK (fdt->lock);
|
||||
for (i = 0; i < fdt->size; i++)
|
||||
{
|
||||
/* A new process. */
|
||||
proc = xtrycalloc (1, sizeof *proc);
|
||||
if (!proc)
|
||||
if (fdt->fds[i].fd == -1)
|
||||
break;
|
||||
}
|
||||
if (i == fdt->size)
|
||||
{
|
||||
#define FDT_ALLOCSIZE 10
|
||||
new_fds = xtryrealloc (fdt->fds, (fdt->size + FDT_ALLOCSIZE)
|
||||
* sizeof (*new_fds));
|
||||
if (!new_fds)
|
||||
{
|
||||
UNLOCK (proc_queue_lock);
|
||||
UNLOCK (fdt->lock);
|
||||
return mk_error (Out_Of_Core);
|
||||
}
|
||||
proc->pid = pid;
|
||||
proc->ctx = ctx;
|
||||
proc->next = proc_queue;
|
||||
proc_queue = proc;
|
||||
}
|
||||
|
||||
fdt->fds = new_fds;
|
||||
fdt->size += FDT_ALLOCSIZE;
|
||||
for (j = 0; j < FDT_ALLOCSIZE; j++)
|
||||
fdt->fds[i + j].fd = -1;
|
||||
}
|
||||
assert (proc->ctx == ctx);
|
||||
q->proc = proc;
|
||||
q->next = proc->handler_list;
|
||||
proc->handler_list = q;
|
||||
UNLOCK (proc_queue_lock);
|
||||
|
||||
LOCK (fd_table_lock);
|
||||
again:
|
||||
for (i=0; i < fd_table_size; i++)
|
||||
{
|
||||
if (fd_table[i].fd == -1)
|
||||
{
|
||||
fd_table[i].fd = fd;
|
||||
fd_table[i].for_read = inbound;
|
||||
fd_table[i].for_write = !inbound;
|
||||
fd_table[i].signaled = 0;
|
||||
fd_table[i].frozen = 0;
|
||||
fd_table[i].opaque = q;
|
||||
UNLOCK (fd_table_lock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if ( fd_table_size < 50 ) {
|
||||
/* FIXME: We have to wait until there are no other readers of the
|
||||
* table, i.e that the io_select is not active in another thread */
|
||||
struct io_select_fd_s *tmp;
|
||||
|
||||
tmp = xtryrealloc (fd_table, (fd_table_size + 10) * sizeof *tmp);
|
||||
if (tmp)
|
||||
{
|
||||
for (i = 0; i < 10; i++)
|
||||
tmp[fd_table_size+i].fd = -1;
|
||||
fd_table_size += i;
|
||||
fd_table = tmp;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
UNLOCK (fd_table_lock);
|
||||
xfree (q);
|
||||
/* FIXME: Remove the proc table entry. */
|
||||
return mk_error (Too_Many_Procs);
|
||||
fdt->fds[i].fd = fd;
|
||||
fdt->fds[i].for_read = (dir == 1);
|
||||
fdt->fds[i].for_write = (dir == 0);
|
||||
fdt->fds[i].frozen = 0;
|
||||
fdt->fds[i].signaled = 0;
|
||||
fdt->fds[i].opaque = opaque;
|
||||
UNLOCK (fdt->lock);
|
||||
*idx = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gpgme_freeze_fd (int fd)
|
||||
{
|
||||
int i;
|
||||
|
||||
LOCK (fd_table_lock);
|
||||
for (i = 0; i < fd_table_size; i++)
|
||||
{
|
||||
if (fd_table[i].fd == fd)
|
||||
{
|
||||
struct wait_item_s *q;
|
||||
|
||||
fd_table[i].frozen = 1;
|
||||
q = fd_table[i].opaque;
|
||||
if (q)
|
||||
q->frozen = 1;
|
||||
DEBUG2 ("fd %d frozen (q=%p)", fd, q);
|
||||
break;
|
||||
}
|
||||
}
|
||||
UNLOCK (fd_table_lock);
|
||||
}
|
||||
|
||||
void
|
||||
_gpgme_thaw_fd (int fd)
|
||||
{
|
||||
int i;
|
||||
|
||||
LOCK (fd_table_lock);
|
||||
for (i = 0; i < fd_table_size; i++)
|
||||
{
|
||||
if (fd_table[i].fd == fd)
|
||||
{
|
||||
struct wait_item_s *q;
|
||||
|
||||
fd_table[i].frozen = 0;
|
||||
q = fd_table[i].opaque;
|
||||
if (q)
|
||||
q->frozen = 0;
|
||||
DEBUG2 ("fd %d thawed (q=%p)", fd, q);
|
||||
break;
|
||||
}
|
||||
}
|
||||
UNLOCK (fd_table_lock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* gpgme_register_idle:
|
||||
* @fnc: Callers idle function
|
||||
@ -438,7 +133,6 @@ gpgme_register_idle (GpgmeIdleFunc idle)
|
||||
return old_idle;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
run_idle ()
|
||||
{
|
||||
@ -446,3 +140,233 @@ run_idle ()
|
||||
if (idle_function)
|
||||
idle_function ();
|
||||
}
|
||||
|
||||
|
||||
/* Wait on all file descriptors listed in FDT and process them using
|
||||
the registered callbacks. Returns 0 if nothing to run and 1 if it
|
||||
did run something. */
|
||||
static int
|
||||
do_select (fd_table_t fdt)
|
||||
{
|
||||
int i, n;
|
||||
int any = 0;
|
||||
|
||||
LOCK (fdt->lock);
|
||||
n = _gpgme_io_select (fdt->fds, fdt->size);
|
||||
|
||||
if (n <= 0)
|
||||
{
|
||||
UNLOCK (fdt->lock);
|
||||
return 0; /* Error or timeout. */
|
||||
}
|
||||
|
||||
for (i = 0; i < fdt->size && n; i++)
|
||||
{
|
||||
if (fdt->fds[i].fd != -1 && fdt->fds[i].signaled)
|
||||
{
|
||||
struct wait_item_s *item;
|
||||
|
||||
assert (n);
|
||||
n--;
|
||||
|
||||
item = (struct wait_item_s *) fdt->fds[i].opaque;
|
||||
assert (item);
|
||||
any = 1;
|
||||
|
||||
fdt->fds[i].signaled = 0;
|
||||
UNLOCK (fdt->lock);
|
||||
item->handler (item->handler_value, fdt->fds[i].fd);
|
||||
LOCK (fdt->lock);
|
||||
}
|
||||
}
|
||||
UNLOCK (fdt->lock);
|
||||
|
||||
return any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
_gpgme_wait_event_cb (void *data, GpgmeEventIO type, void *type_data)
|
||||
{
|
||||
if (type != GPGME_EVENT_DONE)
|
||||
return;
|
||||
|
||||
if (ctx_done_list_size == ctx_done_list_length)
|
||||
{
|
||||
#define CTX_DONE_LIST_SIZE_INITIAL 8
|
||||
int new_size = ctx_done_list_size ? 2 * ctx_done_list_size
|
||||
: CTX_DONE_LIST_SIZE_INITIAL;
|
||||
GpgmeCtx *new_list = xtryrealloc (ctx_done_list,
|
||||
new_size * sizeof (GpgmeCtx *));
|
||||
assert (new_list);
|
||||
#if 0
|
||||
if (!new_list)
|
||||
return mk_error (Out_Of_Core);
|
||||
#endif
|
||||
ctx_done_list = new_list;
|
||||
ctx_done_list_size = new_size;
|
||||
}
|
||||
ctx_done_list[ctx_done_list_length++] = (GpgmeCtx) data;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* gpgme_wait:
|
||||
* @c:
|
||||
* @hang:
|
||||
*
|
||||
* Wait for a finished request, if @c is given the function does only
|
||||
* wait on a finished request for that context, otherwise it will return
|
||||
* on any request. When @hang is true the function will wait, otherwise
|
||||
* it will return immediately when there is no pending finished request.
|
||||
*
|
||||
* Return value: Context of the finished request or NULL if @hang is false
|
||||
* and no (or not the given) request has finished.
|
||||
**/
|
||||
GpgmeCtx
|
||||
gpgme_wait (GpgmeCtx ctx, GpgmeError *status, int hang)
|
||||
{
|
||||
ctx = _gpgme_wait_on_condition (ctx, hang, NULL);
|
||||
if (ctx && status)
|
||||
*status = ctx->error;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
GpgmeError
|
||||
_gpgme_wait_one (GpgmeCtx ctx)
|
||||
{
|
||||
int hang = 1;
|
||||
DEBUG1 ("waiting... ctx=%p", ctx);
|
||||
do
|
||||
{
|
||||
if (! do_select (&ctx->fdt))
|
||||
hang = 0;
|
||||
}
|
||||
while (hang && !ctx->cancel);
|
||||
if (ctx->cancel)
|
||||
{
|
||||
/* FIXME: Paranoia? */
|
||||
ctx->cancel = 0;
|
||||
ctx->pending = 0;
|
||||
ctx->error = mk_error (Canceled);
|
||||
}
|
||||
return ctx->error;
|
||||
}
|
||||
|
||||
|
||||
GpgmeCtx
|
||||
_gpgme_wait_on_condition (GpgmeCtx ctx, int hang, volatile int *cond)
|
||||
{
|
||||
DEBUG3 ("waiting... ctx=%p hang=%d cond=%p", ctx, hang, cond);
|
||||
do
|
||||
{
|
||||
if (! do_select (&fdt_global))
|
||||
hang = 0;
|
||||
|
||||
if (cond && *cond)
|
||||
hang = 0;
|
||||
else
|
||||
{
|
||||
int i;
|
||||
|
||||
LOCK (ctx_done_list_lock);
|
||||
/* A process that is done is eligible for election if it is
|
||||
the requested context or if it was not yet reported. */
|
||||
for (i = 0; i < ctx_done_list_length; i++)
|
||||
if (!ctx || ctx == ctx_done_list[i])
|
||||
break;
|
||||
if (i < ctx_done_list_length)
|
||||
{
|
||||
if (!ctx)
|
||||
ctx = ctx_done_list[i];
|
||||
hang = 0;
|
||||
ctx->pending = 0;
|
||||
if (--ctx_done_list_length)
|
||||
memcpy (&ctx_done_list[i],
|
||||
&ctx_done_list[i + 1],
|
||||
(ctx_done_list_length - i) * sizeof (GpgmeCtx *));
|
||||
}
|
||||
UNLOCK (ctx_done_list_lock);
|
||||
}
|
||||
if (hang)
|
||||
run_idle ();
|
||||
}
|
||||
while (hang && (!ctx || !ctx->cancel));
|
||||
if (ctx && ctx->cancel)
|
||||
{
|
||||
/* FIXME: Paranoia? */
|
||||
ctx->cancel = 0;
|
||||
ctx->pending = 0;
|
||||
ctx->error = mk_error (Canceled);
|
||||
}
|
||||
return ctx;
|
||||
}
|
||||
|
||||
|
||||
struct tag
|
||||
{
|
||||
fd_table_t fdt;
|
||||
int idx;
|
||||
};
|
||||
|
||||
void *
|
||||
_gpgme_add_io_cb (void *data, int fd, int dir,
|
||||
GpgmeIOCb fnc, void *fnc_data)
|
||||
{
|
||||
GpgmeError err;
|
||||
fd_table_t fdt = (fd_table_t) (data ? data : &fdt_global);
|
||||
struct wait_item_s *item;
|
||||
struct tag *tag;
|
||||
|
||||
assert (fdt);
|
||||
assert (fnc);
|
||||
|
||||
tag = xtrymalloc (sizeof *tag);
|
||||
if (!tag)
|
||||
return NULL;
|
||||
tag->fdt = fdt;
|
||||
|
||||
/* Allocate a structure to hold info about the handler. */
|
||||
item = xtrycalloc (1, sizeof *item);
|
||||
if (!item)
|
||||
{
|
||||
xfree (tag);
|
||||
return NULL;
|
||||
}
|
||||
item->dir = dir;
|
||||
item->handler = fnc;
|
||||
item->handler_value = fnc_data;
|
||||
|
||||
err = _gpgme_fd_table_put (fdt, fd, dir, item, &tag->idx);
|
||||
if (err)
|
||||
{
|
||||
xfree (tag);
|
||||
xfree (item);
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
||||
void
|
||||
_gpgme_remove_io_cb (void *data)
|
||||
{
|
||||
struct tag *tag = data;
|
||||
fd_table_t fdt = tag->fdt;
|
||||
int idx = tag->idx;
|
||||
|
||||
LOCK (fdt->lock);
|
||||
DEBUG2 ("setting fd %d (item=%p) done", fdt->fds[idx].fd,
|
||||
fdt->fds[idx].opaque);
|
||||
xfree (fdt->fds[idx].opaque);
|
||||
xfree (tag);
|
||||
|
||||
/* Free the table entry. */
|
||||
fdt->fds[idx].fd = -1;
|
||||
fdt->fds[idx].for_read = 0;
|
||||
fdt->fds[idx].for_write = 0;
|
||||
fdt->fds[idx].opaque = NULL;
|
||||
}
|
||||
|
||||
|
22
gpgme/wait.h
22
gpgme/wait.h
@ -23,12 +23,24 @@
|
||||
#define WAIT_H
|
||||
|
||||
#include "gpgme.h"
|
||||
#include "sema.h"
|
||||
|
||||
void _gpgme_remove_proc_from_wait_queue (int pid);
|
||||
struct fd_table
|
||||
{
|
||||
DECLARE_LOCK (lock);
|
||||
struct io_select_fd_s *fds;
|
||||
size_t size;
|
||||
};
|
||||
typedef struct fd_table *fd_table_t;
|
||||
|
||||
GpgmeError _gpgme_register_pipe_handler (void *opaque,
|
||||
int (*handler) (void*, int, int),
|
||||
void *handler_value,
|
||||
int pid, int fd, int inbound);
|
||||
void _gpgme_fd_table_init (fd_table_t fdt);
|
||||
void _gpgme_fd_table_deinit (fd_table_t fdt);
|
||||
|
||||
void *_gpgme_add_io_cb (void *data, int fd, int dir,
|
||||
GpgmeIOCb fnc, void *fnc_data);
|
||||
void _gpgme_remove_io_cb (void *tag);
|
||||
void _gpgme_wait_event_cb (void *data, GpgmeEventIO type, void *type_data);
|
||||
|
||||
GpgmeError _gpgme_wait_one (GpgmeCtx ctx);
|
||||
|
||||
#endif /* WAIT_H */
|
||||
|
Loading…
Reference in New Issue
Block a user