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>
|
2002-06-04 Marcus Brinkmann <marcus@g10code.de>
|
||||||
|
|
||||||
* Makefile.am (libgpgme_la_SOURCES): Remove mutex.h.
|
* Makefile.am (libgpgme_la_SOURCES): Remove mutex.h.
|
||||||
|
@ -59,6 +59,7 @@ libgpgme_la_SOURCES = \
|
|||||||
context.h ops.h \
|
context.h ops.h \
|
||||||
data.c recipient.c signers.c \
|
data.c recipient.c signers.c \
|
||||||
wait.c wait.h \
|
wait.c wait.h \
|
||||||
|
op-support.c \
|
||||||
encrypt.c \
|
encrypt.c \
|
||||||
encrypt-sign.c \
|
encrypt-sign.c \
|
||||||
decrypt.c \
|
decrypt.c \
|
||||||
|
@ -25,12 +25,16 @@
|
|||||||
#include "gpgme.h"
|
#include "gpgme.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
|
#include "wait.h"
|
||||||
|
|
||||||
struct key_queue_item_s {
|
struct key_queue_item_s
|
||||||
|
{
|
||||||
struct key_queue_item_s *next;
|
struct key_queue_item_s *next;
|
||||||
GpgmeKey key;
|
GpgmeKey key;
|
||||||
};
|
};
|
||||||
struct trust_queue_item_s {
|
|
||||||
|
struct trust_queue_item_s
|
||||||
|
{
|
||||||
struct trust_queue_item_s *next;
|
struct trust_queue_item_s *next;
|
||||||
GpgmeTrustItem item;
|
GpgmeTrustItem item;
|
||||||
};
|
};
|
||||||
@ -98,6 +102,11 @@ struct gpgme_context_s
|
|||||||
GpgmeProgressCb progress_cb;
|
GpgmeProgressCb progress_cb;
|
||||||
void *progress_cb_value;
|
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;
|
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. */
|
/* Functions to support the wait interface. */
|
||||||
|
|
||||||
int
|
void
|
||||||
_gpgme_data_inbound_handler (void *opaque, int pid, int fd)
|
_gpgme_data_inbound_handler (void *opaque, int fd)
|
||||||
{
|
{
|
||||||
GpgmeData dh = opaque;
|
GpgmeData dh = opaque;
|
||||||
GpgmeError err;
|
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",
|
DEBUG3 ("read_mem_data: read failed on fd %d (n=%d): %s",
|
||||||
fd, nread, strerror (errno) );
|
fd, nread, strerror (errno) );
|
||||||
return 1;
|
_gpgme_io_close (fd); /* XXX ??? */
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (!nread)
|
else if (!nread)
|
||||||
return 1; /* eof */
|
{
|
||||||
|
_gpgme_io_close (fd);
|
||||||
|
return; /* eof */
|
||||||
|
}
|
||||||
/* We could improve this with a GpgmeData function which takes
|
/* We could improve this with a GpgmeData function which takes
|
||||||
* the read function or provides a memory area for writing to it.
|
* 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));
|
gpgme_strerror(err));
|
||||||
/* Fixme: we should close the pipe or read it to /dev/null in
|
/* Fixme: we should close the pipe or read it to /dev/null in
|
||||||
* this case. Returnin EOF is not sufficient */
|
* this case. Returnin EOF is not sufficient */
|
||||||
return 1;
|
_gpgme_io_close (fd); /* XXX ??? */
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -920,7 +924,6 @@ write_mem_data (GpgmeData dh, int fd)
|
|||||||
nbytes = dh->len - dh->readpos;
|
nbytes = dh->len - dh->readpos;
|
||||||
if (!nbytes)
|
if (!nbytes)
|
||||||
{
|
{
|
||||||
_gpgme_io_close (fd);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -938,7 +941,6 @@ write_mem_data (GpgmeData dh, int fd)
|
|||||||
{
|
{
|
||||||
DEBUG3 ("write_mem_data(%d): write failed (n=%d): %s",
|
DEBUG3 ("write_mem_data(%d): write failed (n=%d): %s",
|
||||||
fd, nwritten, strerror (errno));
|
fd, nwritten, strerror (errno));
|
||||||
_gpgme_io_close (fd);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -956,7 +958,6 @@ write_cb_data (GpgmeData dh, int fd)
|
|||||||
err = gpgme_data_read (dh, buffer, DIM(buffer), &nbytes);
|
err = gpgme_data_read (dh, buffer, DIM(buffer), &nbytes);
|
||||||
if (err == GPGME_EOF)
|
if (err == GPGME_EOF)
|
||||||
{
|
{
|
||||||
_gpgme_io_close (fd);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -967,7 +968,6 @@ write_cb_data (GpgmeData dh, int fd)
|
|||||||
{
|
{
|
||||||
DEBUG3 ("write_cb_data(%d): write failed (n=%d): %s",
|
DEBUG3 ("write_cb_data(%d): write failed (n=%d): %s",
|
||||||
fd, nwritten, strerror (errno));
|
fd, nwritten, strerror (errno));
|
||||||
_gpgme_io_close (fd);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -977,15 +977,14 @@ write_cb_data (GpgmeData dh, int fd)
|
|||||||
if (_gpgme_data_unread (dh, buffer + nwritten, nbytes - nwritten))
|
if (_gpgme_data_unread (dh, buffer + nwritten, nbytes - nwritten))
|
||||||
DEBUG1 ("wite_cb_data: unread of %d bytes failed\n",
|
DEBUG1 ("wite_cb_data: unread of %d bytes failed\n",
|
||||||
nbytes - nwritten);
|
nbytes - nwritten);
|
||||||
_gpgme_io_close (fd);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
_gpgme_data_outbound_handler (void *opaque, int pid, int fd)
|
_gpgme_data_outbound_handler (void *opaque, int fd)
|
||||||
{
|
{
|
||||||
GpgmeData dh = opaque;
|
GpgmeData dh = opaque;
|
||||||
|
|
||||||
@ -994,15 +993,13 @@ _gpgme_data_outbound_handler (void *opaque, int pid, int fd)
|
|||||||
{
|
{
|
||||||
case GPGME_DATA_TYPE_MEM:
|
case GPGME_DATA_TYPE_MEM:
|
||||||
if (write_mem_data (dh, fd))
|
if (write_mem_data (dh, fd))
|
||||||
return 1; /* ready */
|
_gpgme_io_close (fd);
|
||||||
break;
|
break;
|
||||||
case GPGME_DATA_TYPE_CB:
|
case GPGME_DATA_TYPE_CB:
|
||||||
if (write_cb_data (dh, fd))
|
if (write_cb_data (dh, fd))
|
||||||
return 1; /* ready */
|
_gpgme_io_close (fd);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert (0);
|
assert (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ decrypt_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
|||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_op_decrypt_verify_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain)
|
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);
|
decrypt_verify_status_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,10 +69,11 @@ gpgme_op_decrypt_verify (GpgmeCtx ctx,
|
|||||||
ctx->notation = NULL;
|
ctx->notation = NULL;
|
||||||
|
|
||||||
*r_stat = GPGME_SIG_STAT_NONE;
|
*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)
|
if (!err)
|
||||||
{
|
{
|
||||||
gpgme_wait (ctx, &err, 1);
|
err = _gpgme_wait_one (ctx);
|
||||||
if (!err)
|
if (!err)
|
||||||
*r_stat = _gpgme_intersect_stati (ctx->result.verify);
|
*r_stat = _gpgme_intersect_stati (ctx->result.verify);
|
||||||
}
|
}
|
||||||
|
@ -80,20 +80,12 @@ _gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
|||||||
|
|
||||||
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
_gpgme_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain,
|
_gpgme_decrypt_start (GpgmeCtx ctx, int synchronous,
|
||||||
void *status_handler)
|
GpgmeData ciph, GpgmeData plain, void *status_handler)
|
||||||
{
|
{
|
||||||
GpgmeError err = 0;
|
GpgmeError err = 0;
|
||||||
|
|
||||||
fail_on_pending_request (ctx);
|
err = _gpgme_op_reset (ctx, synchronous);
|
||||||
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);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
@ -138,7 +130,7 @@ _gpgme_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain,
|
|||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_op_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain)
|
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);
|
_gpgme_decrypt_status_handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,8 +150,9 @@ gpgme_op_decrypt_start (GpgmeCtx ctx, GpgmeData ciph, GpgmeData plain)
|
|||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_op_decrypt (GpgmeCtx ctx, GpgmeData in, GpgmeData out)
|
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)
|
if (!err)
|
||||||
gpgme_wait (ctx, &err, 1);
|
err = _gpgme_wait_one (ctx);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -91,30 +91,13 @@ delete_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GpgmeError
|
static GpgmeError
|
||||||
gpgme_op_delete_start (GpgmeCtx ctx, const GpgmeKey key, int allow_secret)
|
_gpgme_op_delete_start (GpgmeCtx ctx, int synchronous,
|
||||||
|
const GpgmeKey key, int allow_secret)
|
||||||
{
|
{
|
||||||
GpgmeError err = 0;
|
GpgmeError err = 0;
|
||||||
|
|
||||||
fail_on_pending_request (ctx);
|
err = _gpgme_op_reset (ctx, synchronous);
|
||||||
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);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
@ -135,6 +118,12 @@ gpgme_op_delete_start (GpgmeCtx ctx, const GpgmeKey key, int allow_secret)
|
|||||||
return err;
|
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:
|
* gpgme_op_delete:
|
||||||
@ -150,8 +139,8 @@ gpgme_op_delete_start (GpgmeCtx ctx, const GpgmeKey key, int allow_secret)
|
|||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_op_delete (GpgmeCtx ctx, const GpgmeKey key, int allow_secret)
|
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)
|
if (!err)
|
||||||
gpgme_wait (ctx, &err, 1);
|
err = _gpgme_wait_one (ctx);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -50,30 +50,14 @@ encrypt_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GpgmeError
|
static GpgmeError
|
||||||
gpgme_op_encrypt_sign_start (GpgmeCtx ctx, GpgmeRecipients recp,
|
_gpgme_op_encrypt_sign_start (GpgmeCtx ctx, int synchronous,
|
||||||
|
GpgmeRecipients recp,
|
||||||
GpgmeData plain, GpgmeData cipher)
|
GpgmeData plain, GpgmeData cipher)
|
||||||
{
|
{
|
||||||
int err = 0;
|
GpgmeError err = 0;
|
||||||
|
|
||||||
fail_on_pending_request (ctx);
|
err = _gpgme_op_reset (ctx, synchronous);
|
||||||
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);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
@ -115,6 +99,13 @@ gpgme_op_encrypt_sign_start (GpgmeCtx ctx, GpgmeRecipients recp,
|
|||||||
return err;
|
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:
|
* gpgme_op_encrypt_sign:
|
||||||
@ -133,11 +124,11 @@ GpgmeError
|
|||||||
gpgme_op_encrypt_sign (GpgmeCtx ctx, GpgmeRecipients recp,
|
gpgme_op_encrypt_sign (GpgmeCtx ctx, GpgmeRecipients recp,
|
||||||
GpgmeData plain, GpgmeData cipher)
|
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)
|
if (!err)
|
||||||
{
|
{
|
||||||
gpgme_wait (ctx, &err, 1);
|
err = _gpgme_wait_one (ctx);
|
||||||
/* Old gpg versions don't return status info for invalid
|
/* Old gpg versions don't return status info for invalid
|
||||||
recipients, so we simply check whether we got any output at
|
recipients, so we simply check whether we got any output at
|
||||||
all, and if not we assume that we don't have valid
|
all, and if not we assume that we don't have valid
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "ops.h"
|
#include "ops.h"
|
||||||
|
#include "wait.h"
|
||||||
|
|
||||||
#define SKIP_TOKEN_OR_RETURN(a) do { \
|
#define SKIP_TOKEN_OR_RETURN(a) do { \
|
||||||
while (*(a) && *(a) != ' ') (a)++; \
|
while (*(a) && *(a) != ' ') (a)++; \
|
||||||
@ -142,18 +143,13 @@ _gpgme_encrypt_sym_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GpgmeError
|
static GpgmeError
|
||||||
gpgme_op_encrypt_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData plain,
|
_gpgme_op_encrypt_start (GpgmeCtx ctx, int synchronous,
|
||||||
GpgmeData ciph)
|
GpgmeRecipients recp, GpgmeData plain, GpgmeData ciph)
|
||||||
{
|
{
|
||||||
int err = 0;
|
GpgmeError err = 0;
|
||||||
int symmetric = 0;
|
int symmetric = 0;
|
||||||
|
|
||||||
fail_on_pending_request (ctx);
|
|
||||||
ctx->pending = 1;
|
|
||||||
|
|
||||||
_gpgme_release_result (ctx);
|
|
||||||
|
|
||||||
/* Do some checks. */
|
/* Do some checks. */
|
||||||
if (!recp)
|
if (!recp)
|
||||||
symmetric = 1;
|
symmetric = 1;
|
||||||
@ -163,11 +159,7 @@ gpgme_op_encrypt_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData plain,
|
|||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create an engine object. */
|
err = _gpgme_op_reset (ctx, synchronous);
|
||||||
_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)
|
if (err)
|
||||||
goto leave;
|
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:
|
* gpgme_op_encrypt:
|
||||||
* @c: The context
|
* @c: The context
|
||||||
@ -233,10 +233,10 @@ GpgmeError
|
|||||||
gpgme_op_encrypt (GpgmeCtx ctx, GpgmeRecipients recp,
|
gpgme_op_encrypt (GpgmeCtx ctx, GpgmeRecipients recp,
|
||||||
GpgmeData plain, GpgmeData cipher)
|
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)
|
if (!err)
|
||||||
{
|
{
|
||||||
gpgme_wait (ctx, &err, 1);
|
err = _gpgme_wait_one (ctx);
|
||||||
/* Old gpg versions don't return status info for invalid
|
/* Old gpg versions don't return status info for invalid
|
||||||
recipients, so we simply check whether we got any output at
|
recipients, so we simply check whether we got any output at
|
||||||
all, and if not we assume that we don't have valid
|
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))
|
#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
|
struct gpgsm_object_s
|
||||||
{
|
{
|
||||||
ASSUAN_CONTEXT assuan_ctx;
|
ASSUAN_CONTEXT assuan_ctx;
|
||||||
|
|
||||||
|
iocb_data_t status_cb;
|
||||||
|
|
||||||
/* Input, output etc are from the servers perspective. */
|
/* Input, output etc are from the servers perspective. */
|
||||||
int input_fd;
|
iocb_data_t input_cb;
|
||||||
int input_fd_server;
|
int input_fd_server;
|
||||||
GpgmeData input_data;
|
|
||||||
int output_fd;
|
iocb_data_t output_cb;
|
||||||
int output_fd_server;
|
int output_fd_server;
|
||||||
GpgmeData output_data;
|
|
||||||
int message_fd;
|
iocb_data_t message_cb;
|
||||||
int message_fd_server;
|
int message_fd_server;
|
||||||
GpgmeData message_data;
|
|
||||||
|
|
||||||
char *command;
|
char *command;
|
||||||
|
|
||||||
@ -93,6 +103,8 @@ struct gpgsm_object_s
|
|||||||
int linelen;
|
int linelen;
|
||||||
} attic;
|
} attic;
|
||||||
} colon;
|
} colon;
|
||||||
|
|
||||||
|
struct GpgmeIOCbs io_cbs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -124,14 +136,49 @@ static void
|
|||||||
close_notify_handler (int fd, void *opaque)
|
close_notify_handler (int fd, void *opaque)
|
||||||
{
|
{
|
||||||
GpgsmObject gpgsm = opaque;
|
GpgsmObject gpgsm = opaque;
|
||||||
|
int possibly_done = 0;
|
||||||
|
|
||||||
assert (fd != -1);
|
assert (fd != -1);
|
||||||
if (gpgsm->input_fd == fd)
|
if (gpgsm->status_cb.fd == fd)
|
||||||
gpgsm->input_fd = -1;
|
{
|
||||||
else if (gpgsm->output_fd == fd)
|
if (gpgsm->status_cb.tag)
|
||||||
gpgsm->output_fd = -1;
|
{
|
||||||
else if (gpgsm->message_fd == fd)
|
(*gpgsm->io_cbs.remove) (gpgsm->status_cb.tag);
|
||||||
gpgsm->message_fd = -1;
|
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 *old_lc = NULL;
|
||||||
char *dft_lc = NULL;
|
char *dft_lc = NULL;
|
||||||
char *optstr;
|
char *optstr;
|
||||||
|
int fdlist[5];
|
||||||
|
int nfds;
|
||||||
|
|
||||||
*r_gpgsm = NULL;
|
*r_gpgsm = NULL;
|
||||||
gpgsm = xtrycalloc (1, sizeof *gpgsm);
|
gpgsm = xtrycalloc (1, sizeof *gpgsm);
|
||||||
@ -257,11 +306,17 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
|||||||
return err;
|
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->input_fd_server = -1;
|
||||||
gpgsm->output_fd = -1;
|
gpgsm->output_cb.fd = -1;
|
||||||
|
gpgsm->output_cb.tag = 0;
|
||||||
gpgsm->output_fd_server = -1;
|
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->message_fd_server = -1;
|
||||||
|
|
||||||
gpgsm->status.fnc = 0;
|
gpgsm->status.fnc = 0;
|
||||||
@ -270,12 +325,19 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
|||||||
gpgsm->colon.attic.linesize = 0;
|
gpgsm->colon.attic.linesize = 0;
|
||||||
gpgsm->colon.attic.linelen = 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)
|
if (_gpgme_io_pipe (fds, 0) < 0)
|
||||||
{
|
{
|
||||||
err = mk_error (Pipe_Error);
|
err = mk_error (Pipe_Error);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
gpgsm->input_fd = fds[1];
|
gpgsm->input_cb.fd = fds[1];
|
||||||
|
gpgsm->input_cb.dir = 0;
|
||||||
gpgsm->input_fd_server = fds[0];
|
gpgsm->input_fd_server = fds[0];
|
||||||
|
|
||||||
if (_gpgme_io_pipe (fds, 1) < 0)
|
if (_gpgme_io_pipe (fds, 1) < 0)
|
||||||
@ -283,7 +345,8 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
|||||||
err = mk_error (Pipe_Error);
|
err = mk_error (Pipe_Error);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
gpgsm->output_fd = fds[0];
|
gpgsm->output_cb.fd = fds[0];
|
||||||
|
gpgsm->output_cb.dir = 1;
|
||||||
gpgsm->output_fd_server = fds[1];
|
gpgsm->output_fd_server = fds[1];
|
||||||
|
|
||||||
if (_gpgme_io_pipe (fds, 0) < 0)
|
if (_gpgme_io_pipe (fds, 0) < 0)
|
||||||
@ -291,7 +354,8 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
|||||||
err = mk_error (Pipe_Error);
|
err = mk_error (Pipe_Error);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
gpgsm->message_fd = fds[1];
|
gpgsm->message_cb.fd = fds[1];
|
||||||
|
gpgsm->message_cb.dir = 0;
|
||||||
gpgsm->message_fd_server = fds[0];
|
gpgsm->message_fd_server = fds[0];
|
||||||
|
|
||||||
child_fds[0] = gpgsm->input_fd_server;
|
child_fds[0] = gpgsm->input_fd_server;
|
||||||
@ -307,6 +371,20 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
|||||||
_gpgme_get_gpgsm_path (), argv, child_fds,
|
_gpgme_get_gpgsm_path (), argv, child_fds,
|
||||||
1 /* dup stderr to /dev/null */);
|
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");
|
dft_display = getenv ("DISPLAY");
|
||||||
if (dft_display)
|
if (dft_display)
|
||||||
{
|
{
|
||||||
@ -315,8 +393,8 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
|||||||
err = mk_error (Out_Of_Core);
|
err = mk_error (Out_Of_Core);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL, NULL, NULL,
|
err = assuan_transact (gpgsm->assuan_ctx, optstr, NULL, NULL, NULL,
|
||||||
NULL);
|
NULL, NULL, NULL);
|
||||||
free (optstr);
|
free (optstr);
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
@ -400,11 +478,13 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!err &&
|
if (!err &&
|
||||||
(_gpgme_io_set_close_notify (gpgsm->input_fd,
|
(_gpgme_io_set_close_notify (gpgsm->status_cb.fd,
|
||||||
close_notify_handler, gpgsm)
|
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)
|
close_notify_handler, gpgsm)
|
||||||
|| _gpgme_io_set_close_notify (gpgsm->message_fd,
|
|| _gpgme_io_set_close_notify (gpgsm->output_cb.fd,
|
||||||
|
close_notify_handler, gpgsm)
|
||||||
|
|| _gpgme_io_set_close_notify (gpgsm->message_cb.fd,
|
||||||
close_notify_handler, gpgsm)))
|
close_notify_handler, gpgsm)))
|
||||||
{
|
{
|
||||||
err = mk_error (General_Error);
|
err = mk_error (General_Error);
|
||||||
@ -433,21 +513,15 @@ _gpgme_gpgsm_new (GpgsmObject *r_gpgsm)
|
|||||||
void
|
void
|
||||||
_gpgme_gpgsm_release (GpgsmObject gpgsm)
|
_gpgme_gpgsm_release (GpgsmObject gpgsm)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
|
||||||
|
|
||||||
if (!gpgsm)
|
if (!gpgsm)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pid = assuan_get_pid (gpgsm->assuan_ctx);
|
if (gpgsm->input_cb.fd != -1)
|
||||||
if (pid != -1)
|
_gpgme_io_close (gpgsm->input_cb.fd);
|
||||||
_gpgme_remove_proc_from_wait_queue (pid);
|
if (gpgsm->output_cb.fd != -1)
|
||||||
|
_gpgme_io_close (gpgsm->output_cb.fd);
|
||||||
if (gpgsm->input_fd != -1)
|
if (gpgsm->message_cb.fd != -1)
|
||||||
_gpgme_io_close (gpgsm->input_fd);
|
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||||
if (gpgsm->output_fd != -1)
|
|
||||||
_gpgme_io_close (gpgsm->output_fd);
|
|
||||||
if (gpgsm->message_fd != -1)
|
|
||||||
_gpgme_io_close (gpgsm->message_fd);
|
|
||||||
|
|
||||||
assuan_disconnect (gpgsm->assuan_ctx);
|
assuan_disconnect (gpgsm->assuan_ctx);
|
||||||
|
|
||||||
@ -512,12 +586,17 @@ map_input_enc (GpgmeData d)
|
|||||||
{
|
{
|
||||||
switch (gpgme_data_get_encoding (d))
|
switch (gpgme_data_get_encoding (d))
|
||||||
{
|
{
|
||||||
case GPGME_DATA_ENCODING_NONE: break;
|
case GPGME_DATA_ENCODING_NONE:
|
||||||
case GPGME_DATA_ENCODING_BINARY: return "--binary";
|
break;
|
||||||
case GPGME_DATA_ENCODING_BASE64: return "--base64";
|
case GPGME_DATA_ENCODING_BINARY:
|
||||||
case GPGME_DATA_ENCODING_ARMOR: return "--armor";
|
return "--binary";
|
||||||
|
case GPGME_DATA_ENCODING_BASE64:
|
||||||
|
return "--base64";
|
||||||
|
case GPGME_DATA_ENCODING_ARMOR:
|
||||||
|
return "--armor";
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,16 +613,16 @@ _gpgme_gpgsm_op_decrypt (GpgsmObject gpgsm, GpgmeData ciph, GpgmeData plain)
|
|||||||
if (!gpgsm->command)
|
if (!gpgsm->command)
|
||||||
return mk_error (Out_Of_Core);
|
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,
|
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)
|
if (err)
|
||||||
return mk_error (General_Error); /* FIXME */
|
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);
|
err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server, 0);
|
||||||
if (err)
|
if (err)
|
||||||
return mk_error (General_Error); /* FIXME */
|
return mk_error (General_Error); /* FIXME */
|
||||||
_gpgme_io_close (gpgsm->message_fd);
|
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -626,17 +705,17 @@ _gpgme_gpgsm_op_encrypt (GpgsmObject gpgsm, GpgmeRecipients recp,
|
|||||||
if (!gpgsm->command)
|
if (!gpgsm->command)
|
||||||
return mk_error (Out_Of_Core);
|
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,
|
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)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
gpgsm->output_data = ciph;
|
gpgsm->output_cb.data = ciph;
|
||||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server,
|
err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server,
|
||||||
use_armor ? "--armor" : 0);
|
use_armor ? "--armor" : 0);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
_gpgme_io_close (gpgsm->message_fd);
|
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||||
|
|
||||||
err = gpgsm_set_recipients (gpgsm, recp);
|
err = gpgsm_set_recipients (gpgsm, recp);
|
||||||
if (err)
|
if (err)
|
||||||
@ -668,17 +747,17 @@ _gpgme_gpgsm_op_genkey (GpgsmObject gpgsm, GpgmeData help_data, int use_armor,
|
|||||||
if (!gpgsm->command)
|
if (!gpgsm->command)
|
||||||
return mk_error (Out_Of_Core);
|
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,
|
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)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
gpgsm->output_data = pubkey;
|
gpgsm->output_cb.data = pubkey;
|
||||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server,
|
err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server,
|
||||||
use_armor ? "--armor" : 0);
|
use_armor ? "--armor" : 0);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
_gpgme_io_close (gpgsm->message_fd);
|
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -696,13 +775,13 @@ _gpgme_gpgsm_op_import (GpgsmObject gpgsm, GpgmeData keydata)
|
|||||||
if (!gpgsm->command)
|
if (!gpgsm->command)
|
||||||
return mk_error (Out_Of_Core);
|
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,
|
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)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
_gpgme_io_close (gpgsm->output_fd);
|
_gpgme_io_close (gpgsm->output_cb.fd);
|
||||||
_gpgme_io_close (gpgsm->message_fd);
|
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -740,9 +819,9 @@ _gpgme_gpgsm_op_keylist (GpgsmObject gpgsm, const char *pattern,
|
|||||||
strcpy (&line[9], pattern);
|
strcpy (&line[9], pattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
_gpgme_io_close (gpgsm->input_fd);
|
_gpgme_io_close (gpgsm->input_cb.fd);
|
||||||
_gpgme_io_close (gpgsm->output_fd);
|
_gpgme_io_close (gpgsm->output_cb.fd);
|
||||||
_gpgme_io_close (gpgsm->message_fd);
|
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||||
|
|
||||||
gpgsm->command = line;
|
gpgsm->command = line;
|
||||||
return 0;
|
return 0;
|
||||||
@ -839,9 +918,9 @@ _gpgme_gpgsm_op_keylist_ext (GpgsmObject gpgsm, const char *pattern[],
|
|||||||
}
|
}
|
||||||
*linep = '\0';
|
*linep = '\0';
|
||||||
|
|
||||||
_gpgme_io_close (gpgsm->input_fd);
|
_gpgme_io_close (gpgsm->input_cb.fd);
|
||||||
_gpgme_io_close (gpgsm->output_fd);
|
_gpgme_io_close (gpgsm->output_cb.fd);
|
||||||
_gpgme_io_close (gpgsm->message_fd);
|
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||||
|
|
||||||
gpgsm->command = line;
|
gpgsm->command = line;
|
||||||
return 0;
|
return 0;
|
||||||
@ -872,17 +951,17 @@ _gpgme_gpgsm_op_sign (GpgsmObject gpgsm, GpgmeData in, GpgmeData out,
|
|||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
gpgsm->input_data = in;
|
gpgsm->input_cb.data = in;
|
||||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "INPUT", gpgsm->input_fd_server,
|
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)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
gpgsm->output_data = out;
|
gpgsm->output_cb.data = out;
|
||||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server,
|
err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server,
|
||||||
use_armor ? "--armor" : 0);
|
use_armor ? "--armor" : 0);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
_gpgme_io_close (gpgsm->message_fd);
|
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -908,26 +987,26 @@ _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig, GpgmeData text)
|
|||||||
if (!gpgsm->command)
|
if (!gpgsm->command)
|
||||||
return mk_error (Out_Of_Core);
|
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,
|
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)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
if (_gpgme_data_get_mode (text) == GPGME_DATA_MODE_IN)
|
if (_gpgme_data_get_mode (text) == GPGME_DATA_MODE_IN)
|
||||||
{
|
{
|
||||||
/* Normal or cleartext signature. */
|
/* 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,
|
err = gpgsm_set_fd (gpgsm->assuan_ctx, "OUTPUT", gpgsm->output_fd_server,
|
||||||
0);
|
0);
|
||||||
_gpgme_io_close (gpgsm->message_fd);
|
_gpgme_io_close (gpgsm->message_cb.fd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Detached signature. */
|
/* Detached signature. */
|
||||||
gpgsm->message_data = text;
|
gpgsm->message_cb.data = text;
|
||||||
err = gpgsm_set_fd (gpgsm->assuan_ctx, "MESSAGE",
|
err = gpgsm_set_fd (gpgsm->assuan_ctx, "MESSAGE",
|
||||||
gpgsm->message_fd_server, 0);
|
gpgsm->message_fd_server, 0);
|
||||||
_gpgme_io_close (gpgsm->output_fd);
|
_gpgme_io_close (gpgsm->output_cb.fd);
|
||||||
}
|
}
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
@ -946,8 +1025,8 @@ status_cmp (const void *ap, const void *bp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static void
|
||||||
gpgsm_status_handler (void *opaque, int pid, int fd)
|
gpgsm_status_handler (void *opaque, int fd)
|
||||||
{
|
{
|
||||||
AssuanError err;
|
AssuanError err;
|
||||||
GpgsmObject gpgsm = opaque;
|
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[0] == 'E' && line[1] == 'R' && line[2] == 'R'
|
||||||
&& (line[3] == '\0' || line[3] == ' ')))
|
&& (line[3] == '\0' || line[3] == ' ')))
|
||||||
{
|
{
|
||||||
/* XXX: If an error occured, find out what happened, then save the error value
|
/* XXX: If an error occured, find out what happened, then
|
||||||
before running the status handler (so it takes precedence). */
|
save the error value before running the status handler
|
||||||
|
(so it takes precedence). */
|
||||||
if (!err && line[0] == 'E' && line[3] == ' ')
|
if (!err && line[0] == 'E' && line[3] == ' ')
|
||||||
{
|
{
|
||||||
err = map_assuan_error (atoi (&line[4]));
|
err = map_assuan_error (atoi (&line[4]));
|
||||||
@ -990,7 +1070,8 @@ gpgsm_status_handler (void *opaque, int pid, int fd)
|
|||||||
if (err)
|
if (err)
|
||||||
assuan_write_line (gpgsm->assuan_ctx, "BYE");
|
assuan_write_line (gpgsm->assuan_ctx, "BYE");
|
||||||
|
|
||||||
return 1;
|
_gpgme_io_close (gpgsm->status_cb.fd);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (linelen > 2
|
if (linelen > 2
|
||||||
@ -1015,7 +1096,10 @@ gpgsm_status_handler (void *opaque, int pid, int fd)
|
|||||||
unsigned char *newline = xtryrealloc (*aline,
|
unsigned char *newline = xtryrealloc (*aline,
|
||||||
*alinelen + linelen + 1);
|
*alinelen + linelen + 1);
|
||||||
if (!newline)
|
if (!newline)
|
||||||
return mk_error (Out_Of_Core);
|
{
|
||||||
|
_gpgme_io_close (gpgsm->status_cb.fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
*aline = newline;
|
*aline = newline;
|
||||||
gpgsm->colon.attic.linesize += linelen + 1;
|
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));
|
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
|
GpgmeError
|
||||||
_gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque)
|
_gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque)
|
||||||
{
|
{
|
||||||
GpgmeError err = 0;
|
GpgmeError err = 0;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int fdlist[5];
|
|
||||||
int nfds;
|
|
||||||
|
|
||||||
if (!gpgsm)
|
if (!gpgsm)
|
||||||
return mk_error (Invalid_Value);
|
return mk_error (Invalid_Value);
|
||||||
|
|
||||||
pid = assuan_get_pid (gpgsm->assuan_ctx);
|
pid = assuan_get_pid (gpgsm->assuan_ctx);
|
||||||
|
|
||||||
/* We need to know the fd used by assuan for reads. We do this by
|
err = _gpgme_gpgsm_add_io_cb (gpgsm, &gpgsm->status_cb,
|
||||||
using the assumption that the first returned fd from
|
gpgsm_status_handler);
|
||||||
assuan_get_active_fds() is always this one. */
|
if (gpgsm->input_cb.fd != -1)
|
||||||
nfds = assuan_get_active_fds (gpgsm->assuan_ctx, 0 /* read fds */,
|
err = _gpgme_gpgsm_add_io_cb (gpgsm, &gpgsm->input_cb,
|
||||||
fdlist, DIM (fdlist));
|
_gpgme_data_outbound_handler);
|
||||||
if (nfds < 1)
|
if (!err && gpgsm->output_cb.fd != -1)
|
||||||
return mk_error (General_Error); /* FIXME */
|
err = _gpgme_gpgsm_add_io_cb (gpgsm, &gpgsm->output_cb,
|
||||||
err = _gpgme_register_pipe_handler (opaque, gpgsm_status_handler, gpgsm, pid,
|
_gpgme_data_inbound_handler);
|
||||||
fdlist[0], 1);
|
if (!err && gpgsm->message_cb.fd != -1)
|
||||||
|
err = _gpgme_gpgsm_add_io_cb (gpgsm, &gpgsm->message_cb,
|
||||||
|
_gpgme_data_outbound_handler);
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
err = assuan_write_line (gpgsm->assuan_ctx, gpgsm->command);
|
err = assuan_write_line (gpgsm->assuan_ctx, gpgsm->command);
|
||||||
@ -1160,6 +1237,12 @@ _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, struct GpgmeIOCbs *io_cbs)
|
||||||
|
{
|
||||||
|
gpgsm->io_cbs = *io_cbs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#else /* ENABLE_GPGSM */
|
#else /* ENABLE_GPGSM */
|
||||||
|
|
||||||
@ -1303,5 +1386,8 @@ _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque)
|
|||||||
return mk_error (Invalid_Engine);
|
return mk_error (Invalid_Engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, GpgmeIOCbs io_cbs)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* ! ENABLE_GPGSM */
|
#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,
|
GpgmeError _gpgme_gpgsm_op_verify (GpgsmObject gpgsm, GpgmeData sig,
|
||||||
GpgmeData text);
|
GpgmeData text);
|
||||||
GpgmeError _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque);
|
GpgmeError _gpgme_gpgsm_start (GpgsmObject gpgsm, void *opaque);
|
||||||
|
void _gpgme_gpgsm_set_io_cbs (GpgsmObject gpgsm, struct GpgmeIOCbs *io_cbs);
|
||||||
|
|
||||||
#endif /* ENGINE_GPGSM_H */
|
#endif /* ENGINE_GPGSM_H */
|
||||||
|
@ -567,6 +567,26 @@ _gpgme_engine_start (EngineObject engine, void *opaque)
|
|||||||
return 0;
|
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
|
void
|
||||||
_gpgme_engine_add_child_to_reap_list (void *buf, int buflen, pid_t pid)
|
_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);
|
GpgmeData text);
|
||||||
GpgmeError _gpgme_engine_start (EngineObject engine, void *opaque);
|
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_add_child_to_reap_list (void *buf, int buflen, pid_t pid);
|
||||||
void _gpgme_engine_housecleaning (void);
|
void _gpgme_engine_housecleaning (void);
|
||||||
|
|
||||||
|
@ -41,21 +41,13 @@ export_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GpgmeError
|
static GpgmeError
|
||||||
gpgme_op_export_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData keydata)
|
_gpgme_op_export_start (GpgmeCtx ctx, int synchronous,
|
||||||
|
GpgmeRecipients recp, GpgmeData keydata)
|
||||||
{
|
{
|
||||||
GpgmeError err = 0;
|
GpgmeError err = 0;
|
||||||
|
|
||||||
fail_on_pending_request (ctx);
|
err = _gpgme_op_reset (ctx, synchronous);
|
||||||
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);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
@ -83,6 +75,11 @@ gpgme_op_export_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData keydata)
|
|||||||
return err;
|
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:
|
* gpgme_op_export:
|
||||||
@ -100,8 +97,8 @@ gpgme_op_export_start (GpgmeCtx ctx, GpgmeRecipients recp, GpgmeData keydata)
|
|||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_op_export (GpgmeCtx ctx, GpgmeRecipients recipients, GpgmeData keydata)
|
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)
|
if (!err)
|
||||||
gpgme_wait (ctx, &err, 1);
|
err = _gpgme_wait_one (ctx);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
107
gpgme/genkey.c
107
gpgme/genkey.c
@ -78,66 +78,20 @@ genkey_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GpgmeError
|
||||||
/**
|
_gpgme_op_genkey_start (GpgmeCtx ctx, int synchronous, 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)
|
GpgmeData pubkey, GpgmeData seckey)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
const char *s, *s2, *sx;
|
const char *s, *s2, *sx;
|
||||||
|
|
||||||
fail_on_pending_request (ctx);
|
err = _gpgme_op_reset (ctx, synchronous);
|
||||||
ctx->pending = 1;
|
if (err)
|
||||||
|
goto leave;
|
||||||
|
|
||||||
gpgme_data_release (ctx->help_data_1);
|
gpgme_data_release (ctx->help_data_1);
|
||||||
ctx->help_data_1 = NULL;
|
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)
|
if (!pubkey && !seckey)
|
||||||
; /* okay: Add key to the keyrings */
|
; /* okay: Add key to the keyrings */
|
||||||
else if (pubkey && gpgme_data_get_type (pubkey) != GPGME_DATA_TYPE_NONE)
|
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:
|
* gpgme_op_genkey:
|
||||||
* @c: the context
|
* @c: the context
|
||||||
@ -217,8 +218,8 @@ GpgmeError
|
|||||||
gpgme_op_genkey (GpgmeCtx ctx, const char *parms,
|
gpgme_op_genkey (GpgmeCtx ctx, const char *parms,
|
||||||
GpgmeData pubkey, GpgmeData seckey)
|
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)
|
if (!err)
|
||||||
gpgme_wait (ctx, &err, 1);
|
err = _gpgme_wait_one (ctx);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "ops.h"
|
#include "ops.h"
|
||||||
|
#include "wait.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gpgme_new:
|
* gpgme_new:
|
||||||
@ -53,8 +53,8 @@ gpgme_new (GpgmeCtx *r_ctx)
|
|||||||
ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
|
ctx->keylist_mode = GPGME_KEYLIST_MODE_LOCAL;
|
||||||
ctx->verbosity = 1;
|
ctx->verbosity = 1;
|
||||||
ctx->include_certs = 1;
|
ctx->include_certs = 1;
|
||||||
|
_gpgme_fd_table_init (&ctx->fdt);
|
||||||
*r_ctx = ctx;
|
*r_ctx = ctx;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,6 +71,7 @@ gpgme_release (GpgmeCtx ctx)
|
|||||||
if (!ctx)
|
if (!ctx)
|
||||||
return;
|
return;
|
||||||
_gpgme_engine_release (ctx->engine);
|
_gpgme_engine_release (ctx->engine);
|
||||||
|
_gpgme_fd_table_deinit (&ctx->fdt);
|
||||||
_gpgme_release_result (ctx);
|
_gpgme_release_result (ctx);
|
||||||
gpgme_key_release (ctx->tmp_key);
|
gpgme_key_release (ctx->tmp_key);
|
||||||
gpgme_data_release (ctx->help_data_1);
|
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: The current callback function
|
||||||
* @r_cb_value: The current value passed to the 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
|
void
|
||||||
gpgme_get_progress_cb (GpgmeCtx ctx, GpgmeProgressCb *r_cb, void **r_cb_value)
|
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;
|
*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
|
AM_PATH_GPGME macro) check that this header matches the installed
|
||||||
library. Warning: Do not edit the next line. configure will do
|
library. Warning: Do not edit the next line. configure will do
|
||||||
that for you! */
|
that for you! */
|
||||||
#define GPGME_VERSION "0.3.7-cvs"
|
#define GPGME_VERSION "0.3.8-cvs"
|
||||||
|
|
||||||
|
|
||||||
/* The opaque data types used by GPGME. */
|
/* The opaque data types used by GPGME. */
|
||||||
@ -316,6 +316,46 @@ char *gpgme_get_op_info (GpgmeCtx ctx, int reserved);
|
|||||||
|
|
||||||
/* Run control. */
|
/* 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. */
|
/* Cancel a pending operation in CTX. */
|
||||||
void gpgme_cancel (GpgmeCtx ctx);
|
void gpgme_cancel (GpgmeCtx ctx);
|
||||||
|
|
||||||
|
@ -162,18 +162,12 @@ import_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GpgmeError
|
static GpgmeError
|
||||||
gpgme_op_import_start (GpgmeCtx ctx, GpgmeData keydata)
|
_gpgme_op_import_start (GpgmeCtx ctx, int synchronous, GpgmeData keydata)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
fail_on_pending_request (ctx);
|
err = _gpgme_op_reset (ctx, synchronous);
|
||||||
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);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
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:
|
* gpgme_op_import:
|
||||||
* @c: Context
|
* @c: Context
|
||||||
@ -216,8 +216,8 @@ gpgme_op_import_start (GpgmeCtx ctx, GpgmeData keydata)
|
|||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_op_import (GpgmeCtx ctx, GpgmeData keydata)
|
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)
|
if (!err)
|
||||||
gpgme_wait (ctx, &err, 1);
|
err = _gpgme_wait_one (ctx);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
52
gpgme/io.h
52
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) 2000 Werner Koch (dd9jn)
|
||||||
* Copyright (C) 2001 g10 Code GmbH
|
* Copyright (C) 2001, 2002 g10 Code GmbH
|
||||||
*
|
*
|
||||||
* This file is part of GPGME.
|
* This file is part of GPGME.
|
||||||
*
|
*
|
||||||
@ -24,15 +24,17 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
struct spawn_fd_item_s {
|
/* 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 fd;
|
||||||
int dup_to;
|
int dup_to;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct io_select_fd_s
|
||||||
struct io_select_fd_s {
|
{
|
||||||
int fd;
|
int fd;
|
||||||
int is_closed;
|
|
||||||
int for_read;
|
int for_read;
|
||||||
int for_write;
|
int for_write;
|
||||||
int signaled;
|
int signaled;
|
||||||
@ -40,32 +42,26 @@ struct io_select_fd_s {
|
|||||||
void *opaque;
|
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 */
|
/* 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
|
||||||
int _gpgme_io_read ( int fd, void *buffer, size_t count );
|
fds in FD_CHILD_LIST in the child. */
|
||||||
int _gpgme_io_write ( int fd, const void *buffer, size_t count );
|
int _gpgme_io_spawn (const char *path, char **argv,
|
||||||
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_child_list,
|
||||||
struct spawn_fd_item_s *fd_parent_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_waitpid (int pid, int hang, int *r_status, int *r_signal);
|
||||||
int _gpgme_io_kill ( int pid, int hard );
|
int _gpgme_io_kill (int pid, int hard);
|
||||||
int _gpgme_io_select ( struct io_select_fd_s *fds, size_t nfds);
|
int _gpgme_io_select (struct io_select_fd_s *fds, size_t nfds);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* IO_H */
|
#endif /* IO_H */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -236,7 +236,8 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
/* Start a new keyblock. */
|
/* Start a new keyblock. */
|
||||||
if (_gpgme_key_new (&key))
|
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;
|
return;
|
||||||
}
|
}
|
||||||
rectype = RT_PUB;
|
rectype = RT_PUB;
|
||||||
@ -249,7 +250,8 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
/* Start a new keyblock, */
|
/* Start a new keyblock, */
|
||||||
if (_gpgme_key_new_secret (&key))
|
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;
|
return;
|
||||||
}
|
}
|
||||||
rectype = RT_SEC;
|
rectype = RT_SEC;
|
||||||
@ -262,7 +264,8 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
/* Start a new certificate. */
|
/* Start a new certificate. */
|
||||||
if (_gpgme_key_new (&key))
|
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;
|
return;
|
||||||
}
|
}
|
||||||
key->x509 = 1;
|
key->x509 = 1;
|
||||||
@ -276,7 +279,8 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
/* Start a new certificate. */
|
/* Start a new certificate. */
|
||||||
if (_gpgme_key_new_secret (&key))
|
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;
|
return;
|
||||||
}
|
}
|
||||||
key->x509 = 1;
|
key->x509 = 1;
|
||||||
@ -289,7 +293,6 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
rectype = RT_FPR;
|
rectype = RT_FPR;
|
||||||
else
|
else
|
||||||
rectype = RT_NONE;
|
rectype = RT_NONE;
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (rectype == RT_PUB || rectype == RT_SEC
|
else if (rectype == RT_PUB || rectype == RT_SEC
|
||||||
|| rectype == RT_CRT || rectype == RT_CRS)
|
|| rectype == RT_CRT || rectype == RT_CRS)
|
||||||
@ -401,7 +404,8 @@ keylist_colon_handler (GpgmeCtx ctx, char *line)
|
|||||||
break;
|
break;
|
||||||
case 10: /* user ID */
|
case 10: /* user ID */
|
||||||
if (_gpgme_key_append_name (key, p))
|
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
|
else
|
||||||
{
|
{
|
||||||
if (trust_info)
|
if (trust_info)
|
||||||
@ -495,26 +499,14 @@ gpgme_op_keylist_start (GpgmeCtx ctx, const char *pattern, int secret_only)
|
|||||||
{
|
{
|
||||||
GpgmeError err = 0;
|
GpgmeError err = 0;
|
||||||
|
|
||||||
if (!ctx)
|
err = _gpgme_op_reset (ctx, 0);
|
||||||
return mk_error (Invalid_Value);
|
if (err)
|
||||||
ctx->pending = 1;
|
goto leave;
|
||||||
|
|
||||||
_gpgme_release_result (ctx);
|
|
||||||
|
|
||||||
if (ctx->engine)
|
|
||||||
{
|
|
||||||
_gpgme_engine_release (ctx->engine);
|
|
||||||
ctx->engine = NULL;
|
|
||||||
}
|
|
||||||
gpgme_key_release (ctx->tmp_key);
|
gpgme_key_release (ctx->tmp_key);
|
||||||
ctx->tmp_key = NULL;
|
ctx->tmp_key = NULL;
|
||||||
/* Fixme: Release key_queue. */
|
/* 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);
|
_gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
|
||||||
err = _gpgme_engine_set_colon_line_handler (ctx->engine,
|
err = _gpgme_engine_set_colon_line_handler (ctx->engine,
|
||||||
keylist_colon_handler, ctx);
|
keylist_colon_handler, ctx);
|
||||||
@ -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 */
|
just ignore those lines - This should speed up things */
|
||||||
_gpgme_engine_set_verbosity (ctx->engine, 0);
|
_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. */
|
if (!err) /* And kick off the process. */
|
||||||
err = _gpgme_engine_start (ctx->engine, ctx);
|
err = _gpgme_engine_start (ctx->engine, ctx);
|
||||||
@ -561,26 +554,12 @@ gpgme_op_keylist_ext_start (GpgmeCtx ctx, const char *pattern[],
|
|||||||
{
|
{
|
||||||
GpgmeError err = 0;
|
GpgmeError err = 0;
|
||||||
|
|
||||||
if (!ctx)
|
err = _gpgme_op_reset (ctx, 0);
|
||||||
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);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
|
gpgme_key_release (ctx->tmp_key);
|
||||||
|
|
||||||
_gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
|
_gpgme_engine_set_status_handler (ctx->engine, keylist_status_handler, ctx);
|
||||||
err = _gpgme_engine_set_colon_line_handler (ctx->engine,
|
err = _gpgme_engine_set_colon_line_handler (ctx->engine,
|
||||||
keylist_colon_handler, ctx);
|
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_release_result ( GpgmeCtx c );
|
||||||
void _gpgme_set_op_info (GpgmeCtx c, GpgmeData info);
|
void _gpgme_set_op_info (GpgmeCtx c, GpgmeData info);
|
||||||
|
|
||||||
|
void _gpgme_op_event_cb (void *data, GpgmeEventIO type, void *type_data);
|
||||||
|
|
||||||
/*-- wait.c --*/
|
/*-- wait.c --*/
|
||||||
GpgmeCtx _gpgme_wait_on_condition ( GpgmeCtx c,
|
GpgmeCtx _gpgme_wait_on_condition ( GpgmeCtx c,
|
||||||
int hang, volatile int *cond );
|
int hang, volatile int *cond );
|
||||||
void _gpgme_freeze_fd ( int fd );
|
|
||||||
void _gpgme_thaw_fd ( int fd );
|
|
||||||
|
|
||||||
|
|
||||||
/*-- recipient.c --*/
|
/*-- recipient.c --*/
|
||||||
int _gpgme_recipients_all_valid ( const GpgmeRecipients rset );
|
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,
|
GpgmeError _gpgme_data_unread (GpgmeData dh,
|
||||||
const char *buffer, size_t length );
|
const char *buffer, size_t length );
|
||||||
|
|
||||||
int _gpgme_data_inbound_handler (void *opaque, int pid, int fd);
|
void _gpgme_data_inbound_handler (void *opaque, int fd);
|
||||||
int _gpgme_data_outbound_handler (void *opaque, int pid, int fd);
|
void _gpgme_data_outbound_handler (void *opaque, int fd);
|
||||||
|
|
||||||
|
|
||||||
/*-- key.c --*/
|
/*-- key.c --*/
|
||||||
GpgmeError _gpgme_key_new ( GpgmeKey *r_key );
|
GpgmeError _gpgme_key_new ( GpgmeKey *r_key );
|
||||||
GpgmeError _gpgme_key_new_secret ( GpgmeKey *r_key );
|
GpgmeError _gpgme_key_new_secret ( GpgmeKey *r_key );
|
||||||
|
|
||||||
|
/*-- op-support.c --*/
|
||||||
|
GpgmeError _gpgme_op_reset (GpgmeCtx ctx, int synchronous);
|
||||||
|
|
||||||
/*-- verify.c --*/
|
/*-- verify.c --*/
|
||||||
void _gpgme_release_verify_result (VerifyResult result);
|
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_release_decrypt_result (DecryptResult result);
|
||||||
void _gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code,
|
void _gpgme_decrypt_status_handler (GpgmeCtx ctx, GpgStatusCode code,
|
||||||
char *args);
|
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);
|
void *status_handler);
|
||||||
GpgmeError _gpgme_decrypt_result (GpgmeCtx ctx);
|
GpgmeError _gpgme_decrypt_result (GpgmeCtx ctx);
|
||||||
|
|
||||||
|
518
gpgme/rungpg.c
518
gpgme/rungpg.c
@ -54,21 +54,25 @@ struct arg_and_data_s {
|
|||||||
char arg[1]; /* .. this is used */
|
char arg[1]; /* .. this is used */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fd_data_map_s {
|
struct fd_data_map_s
|
||||||
|
{
|
||||||
GpgmeData data;
|
GpgmeData data;
|
||||||
int inbound; /* true if this is used for reading from gpg */
|
int inbound; /* true if this is used for reading from gpg */
|
||||||
int dup_to;
|
int dup_to;
|
||||||
int fd; /* the fd to use */
|
int fd; /* the fd to use */
|
||||||
int peer_fd; /* the outher side of the pipe */
|
int peer_fd; /* the outher side of the pipe */
|
||||||
|
void *tag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct gpg_object_s {
|
struct gpg_object_s
|
||||||
|
{
|
||||||
struct arg_and_data_s *arglist;
|
struct arg_and_data_s *arglist;
|
||||||
struct arg_and_data_s **argtail;
|
struct arg_and_data_s **argtail;
|
||||||
int arg_error;
|
int arg_error;
|
||||||
|
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
int fd[2];
|
int fd[2];
|
||||||
size_t bufsize;
|
size_t bufsize;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
@ -76,10 +80,12 @@ struct gpg_object_s {
|
|||||||
int eof;
|
int eof;
|
||||||
GpgStatusHandler fnc;
|
GpgStatusHandler fnc;
|
||||||
void *fnc_value;
|
void *fnc_value;
|
||||||
|
void *tag;
|
||||||
} status;
|
} status;
|
||||||
|
|
||||||
/* This is a kludge - see the comment at gpg_colon_line_handler */
|
/* This is a kludge - see the comment at gpg_colon_line_handler */
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
int fd[2];
|
int fd[2];
|
||||||
size_t bufsize;
|
size_t bufsize;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
@ -87,6 +93,7 @@ struct gpg_object_s {
|
|||||||
int eof;
|
int eof;
|
||||||
GpgColonLineHandler fnc; /* this indicate use of this structrue */
|
GpgColonLineHandler fnc; /* this indicate use of this structrue */
|
||||||
void *fnc_value;
|
void *fnc_value;
|
||||||
|
void *tag;
|
||||||
int simple;
|
int simple;
|
||||||
} colon;
|
} colon;
|
||||||
|
|
||||||
@ -95,10 +102,9 @@ struct gpg_object_s {
|
|||||||
|
|
||||||
int pid; /* we can't use pid_t because we don't use it in Windoze */
|
int pid; /* we can't use pid_t because we don't use it in Windoze */
|
||||||
|
|
||||||
int running;
|
|
||||||
|
|
||||||
/* stuff needed for pipemode */
|
/* stuff needed for pipemode */
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
int used;
|
int used;
|
||||||
int active;
|
int active;
|
||||||
GpgmeData sig;
|
GpgmeData sig;
|
||||||
@ -107,60 +113,107 @@ struct gpg_object_s {
|
|||||||
} pm;
|
} pm;
|
||||||
|
|
||||||
/* stuff needed for interactive (command) mode */
|
/* stuff needed for interactive (command) mode */
|
||||||
struct {
|
struct
|
||||||
|
{
|
||||||
int used;
|
int used;
|
||||||
int fd;
|
int fd;
|
||||||
GpgmeData cb_data; /* hack to get init the above fd later */
|
int idx; /* Index in fd_data_map */
|
||||||
|
GpgmeData cb_data; /* hack to get init the above idx later */
|
||||||
GpgStatusCode code; /* last code */
|
GpgStatusCode code; /* last code */
|
||||||
char *keyword; /* what has been requested (malloced) */
|
char *keyword; /* what has been requested (malloced) */
|
||||||
GpgCommandHandler fnc;
|
GpgCommandHandler fnc;
|
||||||
void *fnc_value;
|
void *fnc_value;
|
||||||
} cmd;
|
} cmd;
|
||||||
|
|
||||||
|
struct GpgmeIOCbs io_cbs;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void free_argv ( char **argv );
|
static void free_argv (char **argv);
|
||||||
static void free_fd_data_map ( struct fd_data_map_s *fd_data_map );
|
static void free_fd_data_map (struct fd_data_map_s *fd_data_map);
|
||||||
|
|
||||||
static int gpg_status_handler ( void *opaque, int pid, int fd );
|
static void gpg_status_handler (void *opaque, int fd);
|
||||||
static GpgmeError read_status ( GpgObject gpg );
|
static GpgmeError read_status (GpgObject gpg);
|
||||||
|
|
||||||
static int gpg_colon_line_handler ( void *opaque, int pid, int fd );
|
static void gpg_colon_line_handler (void *opaque, int fd);
|
||||||
static GpgmeError read_colon_line ( GpgObject gpg );
|
static GpgmeError read_colon_line (GpgObject gpg);
|
||||||
|
|
||||||
static int pipemode_cb ( void *opaque,
|
|
||||||
char *buffer, size_t length, size_t *nread );
|
|
||||||
static int command_cb ( void *opaque,
|
|
||||||
char *buffer, size_t length, size_t *nread );
|
|
||||||
|
|
||||||
|
static int pipemode_cb (void *opaque, char *buffer, size_t length,
|
||||||
|
size_t *nread);
|
||||||
|
static int command_cb (void *opaque, char *buffer, size_t length,
|
||||||
|
size_t *nread);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
close_notify_handler ( int fd, void *opaque )
|
close_notify_handler (int fd, void *opaque)
|
||||||
{
|
{
|
||||||
GpgObject gpg = opaque;
|
GpgObject gpg = opaque;
|
||||||
|
int possibly_done = 0;
|
||||||
|
int not_done = 0;
|
||||||
assert (fd != -1);
|
assert (fd != -1);
|
||||||
if (gpg->status.fd[0] == fd )
|
|
||||||
|
if (gpg->status.fd[0] == fd)
|
||||||
|
{
|
||||||
|
if (gpg->status.tag)
|
||||||
|
{
|
||||||
|
(*gpg->io_cbs.remove) (gpg->status.tag);
|
||||||
|
possibly_done = 1;
|
||||||
|
}
|
||||||
gpg->status.fd[0] = -1;
|
gpg->status.fd[0] = -1;
|
||||||
else if (gpg->status.fd[1] == fd )
|
}
|
||||||
|
else if (gpg->status.fd[1] == fd)
|
||||||
gpg->status.fd[1] = -1;
|
gpg->status.fd[1] = -1;
|
||||||
else if (gpg->colon.fd[0] == fd )
|
else if (gpg->colon.fd[0] == fd)
|
||||||
|
{
|
||||||
|
if (gpg->colon.tag)
|
||||||
|
{
|
||||||
|
(*gpg->io_cbs.remove) (gpg->colon.tag);
|
||||||
|
possibly_done = 1;
|
||||||
|
}
|
||||||
gpg->colon.fd[0] = -1;
|
gpg->colon.fd[0] = -1;
|
||||||
else if (gpg->colon.fd[1] == fd )
|
}
|
||||||
|
else if (gpg->colon.fd[1] == fd)
|
||||||
gpg->colon.fd[1] = -1;
|
gpg->colon.fd[1] = -1;
|
||||||
else if (gpg->fd_data_map) {
|
else if (gpg->fd_data_map)
|
||||||
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; gpg->fd_data_map[i].data; i++ ) {
|
for (i = 0; gpg->fd_data_map[i].data; i++)
|
||||||
if ( gpg->fd_data_map[i].fd == fd ) {
|
{
|
||||||
|
if (gpg->fd_data_map[i].fd == fd)
|
||||||
|
{
|
||||||
|
if (gpg->fd_data_map[i].tag)
|
||||||
|
{
|
||||||
|
(*gpg->io_cbs.remove) (gpg->fd_data_map[i].tag);
|
||||||
|
possibly_done = 1;
|
||||||
|
}
|
||||||
gpg->fd_data_map[i].fd = -1;
|
gpg->fd_data_map[i].fd = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( gpg->fd_data_map[i].peer_fd == fd ) {
|
if (gpg->fd_data_map[i].peer_fd == fd)
|
||||||
|
{
|
||||||
gpg->fd_data_map[i].peer_fd = -1;
|
gpg->fd_data_map[i].peer_fd = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!possibly_done)
|
||||||
|
not_done = 1;
|
||||||
|
else if (gpg->status.fd[0] != -1)
|
||||||
|
not_done = 1;
|
||||||
|
else if (gpg->colon.fd[0] != -1)
|
||||||
|
not_done = 1;
|
||||||
|
else if (gpg->fd_data_map)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; gpg->fd_data_map[i].data; i++)
|
||||||
|
if (gpg->fd_data_map[i].fd != -1)
|
||||||
|
{
|
||||||
|
not_done = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!not_done && gpg->io_cbs.event)
|
||||||
|
(*gpg->io_cbs.event) (gpg->io_cbs.event_priv, GPGME_EVENT_DONE, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *
|
const char *
|
||||||
@ -185,13 +238,14 @@ _gpgme_gpg_check_version (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
_gpgme_gpg_new ( GpgObject *r_gpg )
|
_gpgme_gpg_new (GpgObject *r_gpg)
|
||||||
{
|
{
|
||||||
GpgObject gpg;
|
GpgObject gpg;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
gpg = xtrycalloc ( 1, sizeof *gpg );
|
gpg = xtrycalloc (1, sizeof *gpg);
|
||||||
if ( !gpg ) {
|
if (!gpg)
|
||||||
|
{
|
||||||
rc = mk_error (Out_Of_Core);
|
rc = mk_error (Out_Of_Core);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -202,42 +256,46 @@ _gpgme_gpg_new ( GpgObject *r_gpg )
|
|||||||
gpg->colon.fd[0] = -1;
|
gpg->colon.fd[0] = -1;
|
||||||
gpg->colon.fd[1] = -1;
|
gpg->colon.fd[1] = -1;
|
||||||
gpg->cmd.fd = -1;
|
gpg->cmd.fd = -1;
|
||||||
|
gpg->cmd.idx = -1;
|
||||||
|
|
||||||
gpg->pid = -1;
|
gpg->pid = -1;
|
||||||
|
|
||||||
/* allocate the read buffer for the status pipe */
|
/* Allocate the read buffer for the status pipe. */
|
||||||
gpg->status.bufsize = 1024;
|
gpg->status.bufsize = 1024;
|
||||||
gpg->status.readpos = 0;
|
gpg->status.readpos = 0;
|
||||||
gpg->status.buffer = xtrymalloc (gpg->status.bufsize);
|
gpg->status.buffer = xtrymalloc (gpg->status.bufsize);
|
||||||
if (!gpg->status.buffer) {
|
if (!gpg->status.buffer)
|
||||||
|
{
|
||||||
rc = mk_error (Out_Of_Core);
|
rc = mk_error (Out_Of_Core);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
/* In any case we need a status pipe - create it right here and
|
/* In any case we need a status pipe - create it right here and
|
||||||
* don't handle it with our generic GpgmeData mechanism */
|
don't handle it with our generic GpgmeData mechanism. */
|
||||||
if (_gpgme_io_pipe (gpg->status.fd, 1) == -1) {
|
if (_gpgme_io_pipe (gpg->status.fd, 1) == -1)
|
||||||
|
{
|
||||||
rc = mk_error (Pipe_Error);
|
rc = mk_error (Pipe_Error);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
if ( _gpgme_io_set_close_notify (gpg->status.fd[0],
|
if (_gpgme_io_set_close_notify (gpg->status.fd[0],
|
||||||
close_notify_handler, gpg)
|
close_notify_handler, gpg)
|
||||||
|| _gpgme_io_set_close_notify (gpg->status.fd[1],
|
|| _gpgme_io_set_close_notify (gpg->status.fd[1],
|
||||||
close_notify_handler, gpg) ) {
|
close_notify_handler, gpg))
|
||||||
|
{
|
||||||
rc = mk_error (General_Error);
|
rc = mk_error (General_Error);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
gpg->status.eof = 0;
|
gpg->status.eof = 0;
|
||||||
_gpgme_gpg_add_arg ( gpg, "--status-fd" );
|
_gpgme_gpg_add_arg (gpg, "--status-fd");
|
||||||
{
|
{
|
||||||
char buf[25];
|
char buf[25];
|
||||||
sprintf ( buf, "%d", gpg->status.fd[1]);
|
sprintf (buf, "%d", gpg->status.fd[1]);
|
||||||
_gpgme_gpg_add_arg ( gpg, buf );
|
_gpgme_gpg_add_arg (gpg, buf);
|
||||||
}
|
}
|
||||||
_gpgme_gpg_add_arg ( gpg, "--no-tty" );
|
_gpgme_gpg_add_arg (gpg, "--no-tty");
|
||||||
|
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
if (rc) {
|
if (rc)
|
||||||
|
{
|
||||||
_gpgme_gpg_release (gpg);
|
_gpgme_gpg_release (gpg);
|
||||||
*r_gpg = NULL;
|
*r_gpg = NULL;
|
||||||
}
|
}
|
||||||
@ -268,8 +326,6 @@ _gpgme_gpg_release (GpgObject gpg)
|
|||||||
gpgme_data_release (gpg->cmd.cb_data);
|
gpgme_data_release (gpg->cmd.cb_data);
|
||||||
xfree (gpg->cmd.keyword);
|
xfree (gpg->cmd.keyword);
|
||||||
|
|
||||||
if (gpg->pid != -1)
|
|
||||||
_gpgme_remove_proc_from_wait_queue (gpg->pid);
|
|
||||||
if (gpg->status.fd[0] != -1)
|
if (gpg->status.fd[0] != -1)
|
||||||
_gpgme_io_close (gpg->status.fd[0]);
|
_gpgme_io_close (gpg->status.fd[0]);
|
||||||
if (gpg->status.fd[1] != -1)
|
if (gpg->status.fd[1] != -1)
|
||||||
@ -279,7 +335,9 @@ _gpgme_gpg_release (GpgObject gpg)
|
|||||||
if (gpg->colon.fd[1] != -1)
|
if (gpg->colon.fd[1] != -1)
|
||||||
_gpgme_io_close (gpg->colon.fd[1]);
|
_gpgme_io_close (gpg->colon.fd[1]);
|
||||||
free_fd_data_map (gpg->fd_data_map);
|
free_fd_data_map (gpg->fd_data_map);
|
||||||
if (gpg->running)
|
if (gpg->cmd.fd != -1)
|
||||||
|
_gpgme_io_close (gpg->cmd.fd);
|
||||||
|
if (gpg->pid != -1)
|
||||||
_gpgme_engine_add_child_to_reap_list (gpg, sizeof *gpg, gpg->pid);
|
_gpgme_engine_add_child_to_reap_list (gpg, sizeof *gpg, gpg->pid);
|
||||||
else
|
else
|
||||||
xfree (gpg);
|
xfree (gpg);
|
||||||
@ -512,7 +570,7 @@ free_fd_data_map ( struct fd_data_map_s *fd_data_map )
|
|||||||
|
|
||||||
|
|
||||||
static GpgmeError
|
static GpgmeError
|
||||||
build_argv ( GpgObject gpg )
|
build_argv (GpgObject gpg)
|
||||||
{
|
{
|
||||||
struct arg_and_data_s *a;
|
struct arg_and_data_s *a;
|
||||||
struct fd_data_map_s *fd_data_map;
|
struct fd_data_map_s *fd_data_map;
|
||||||
@ -521,29 +579,34 @@ build_argv ( GpgObject gpg )
|
|||||||
int need_special = 0;
|
int need_special = 0;
|
||||||
int use_agent = !!getenv ("GPG_AGENT_INFO");
|
int use_agent = !!getenv ("GPG_AGENT_INFO");
|
||||||
|
|
||||||
if ( gpg->argv ) {
|
if (gpg->argv)
|
||||||
free_argv ( gpg->argv );
|
{
|
||||||
|
free_argv (gpg->argv);
|
||||||
gpg->argv = NULL;
|
gpg->argv = NULL;
|
||||||
}
|
}
|
||||||
if (gpg->fd_data_map) {
|
if (gpg->fd_data_map)
|
||||||
|
{
|
||||||
free_fd_data_map (gpg->fd_data_map);
|
free_fd_data_map (gpg->fd_data_map);
|
||||||
gpg->fd_data_map = NULL;
|
gpg->fd_data_map = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
argc++; /* for argv[0] */
|
argc++; /* For argv[0]. */
|
||||||
for ( a=gpg->arglist; a; a = a->next ) {
|
for (a = gpg->arglist; a; a = a->next)
|
||||||
|
{
|
||||||
argc++;
|
argc++;
|
||||||
if (a->data) {
|
if (a->data)
|
||||||
|
{
|
||||||
/*fprintf (stderr, "build_argv: data\n" );*/
|
/*fprintf (stderr, "build_argv: data\n" );*/
|
||||||
datac++;
|
datac++;
|
||||||
if ( a->dup_to == -1 && !a->print_fd )
|
if (a->dup_to == -1 && !a->print_fd)
|
||||||
need_special = 1;
|
need_special = 1;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
/* fprintf (stderr, "build_argv: arg=`%s'\n", a->arg );*/
|
/* fprintf (stderr, "build_argv: arg=`%s'\n", a->arg );*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ( need_special )
|
if (need_special)
|
||||||
argc++;
|
argc++;
|
||||||
if (use_agent)
|
if (use_agent)
|
||||||
argc++;
|
argc++;
|
||||||
@ -551,86 +614,100 @@ build_argv ( GpgObject gpg )
|
|||||||
argc++;
|
argc++;
|
||||||
argc += 2; /* --comment */
|
argc += 2; /* --comment */
|
||||||
|
|
||||||
argv = xtrycalloc ( argc+1, sizeof *argv );
|
argv = xtrycalloc (argc + 1, sizeof *argv);
|
||||||
if (!argv)
|
if (!argv)
|
||||||
return mk_error (Out_Of_Core);
|
return mk_error (Out_Of_Core);
|
||||||
fd_data_map = xtrycalloc ( datac+1, sizeof *fd_data_map );
|
fd_data_map = xtrycalloc (datac + 1, sizeof *fd_data_map);
|
||||||
if (!fd_data_map) {
|
if (!fd_data_map)
|
||||||
|
{
|
||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Out_Of_Core);
|
return mk_error (Out_Of_Core);
|
||||||
}
|
}
|
||||||
|
|
||||||
argc = datac = 0;
|
argc = datac = 0;
|
||||||
argv[argc] = xtrystrdup ( "gpg" ); /* argv[0] */
|
argv[argc] = xtrystrdup ("gpg"); /* argv[0] */
|
||||||
if (!argv[argc]) {
|
if (!argv[argc])
|
||||||
|
{
|
||||||
xfree (fd_data_map);
|
xfree (fd_data_map);
|
||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Out_Of_Core);
|
return mk_error (Out_Of_Core);
|
||||||
}
|
}
|
||||||
argc++;
|
argc++;
|
||||||
if ( need_special ) {
|
if (need_special)
|
||||||
argv[argc] = xtrystrdup ( "--enable-special-filenames" );
|
{
|
||||||
if (!argv[argc]) {
|
argv[argc] = xtrystrdup ("--enable-special-filenames");
|
||||||
|
if (!argv[argc])
|
||||||
|
{
|
||||||
xfree (fd_data_map);
|
xfree (fd_data_map);
|
||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Out_Of_Core);
|
return mk_error (Out_Of_Core);
|
||||||
}
|
}
|
||||||
argc++;
|
argc++;
|
||||||
}
|
}
|
||||||
if ( use_agent ) {
|
if (use_agent)
|
||||||
argv[argc] = xtrystrdup ( "--use-agent" );
|
{
|
||||||
if (!argv[argc]) {
|
argv[argc] = xtrystrdup ("--use-agent");
|
||||||
|
if (!argv[argc])
|
||||||
|
{
|
||||||
xfree (fd_data_map);
|
xfree (fd_data_map);
|
||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Out_Of_Core);
|
return mk_error (Out_Of_Core);
|
||||||
}
|
}
|
||||||
argc++;
|
argc++;
|
||||||
}
|
}
|
||||||
if ( !gpg->cmd.used ) {
|
if (!gpg->cmd.used)
|
||||||
argv[argc] = xtrystrdup ( "--batch" );
|
{
|
||||||
if (!argv[argc]) {
|
argv[argc] = xtrystrdup ("--batch");
|
||||||
|
if (!argv[argc])
|
||||||
|
{
|
||||||
xfree (fd_data_map);
|
xfree (fd_data_map);
|
||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Out_Of_Core);
|
return mk_error (Out_Of_Core);
|
||||||
}
|
}
|
||||||
argc++;
|
argc++;
|
||||||
}
|
}
|
||||||
argv[argc] = xtrystrdup ( "--comment" );
|
argv[argc] = xtrystrdup ("--comment");
|
||||||
if (!argv[argc]) {
|
if (!argv[argc])
|
||||||
|
{
|
||||||
xfree (fd_data_map);
|
xfree (fd_data_map);
|
||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Out_Of_Core);
|
return mk_error (Out_Of_Core);
|
||||||
}
|
}
|
||||||
argc++;
|
argc++;
|
||||||
argv[argc] = xtrystrdup ( "" );
|
argv[argc] = xtrystrdup ("");
|
||||||
if (!argv[argc]) {
|
if (!argv[argc])
|
||||||
|
{
|
||||||
xfree (fd_data_map);
|
xfree (fd_data_map);
|
||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Out_Of_Core);
|
return mk_error (Out_Of_Core);
|
||||||
}
|
}
|
||||||
argc++;
|
argc++;
|
||||||
for ( a=gpg->arglist; a; a = a->next ) {
|
for (a = gpg->arglist; a; a = a->next)
|
||||||
if ( a->data ) {
|
{
|
||||||
switch ( _gpgme_data_get_mode (a->data) ) {
|
if (a->data)
|
||||||
|
{
|
||||||
|
switch (_gpgme_data_get_mode (a->data))
|
||||||
|
{
|
||||||
case GPGME_DATA_MODE_NONE:
|
case GPGME_DATA_MODE_NONE:
|
||||||
case GPGME_DATA_MODE_INOUT:
|
case GPGME_DATA_MODE_INOUT:
|
||||||
xfree (fd_data_map);
|
xfree (fd_data_map);
|
||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Invalid_Mode);
|
return mk_error (Invalid_Mode);
|
||||||
case GPGME_DATA_MODE_IN:
|
case GPGME_DATA_MODE_IN:
|
||||||
/* create a pipe to read from gpg */
|
/* Create a pipe to read from gpg. */
|
||||||
fd_data_map[datac].inbound = 1;
|
fd_data_map[datac].inbound = 1;
|
||||||
break;
|
break;
|
||||||
case GPGME_DATA_MODE_OUT:
|
case GPGME_DATA_MODE_OUT:
|
||||||
/* create a pipe to pass it down to gpg */
|
/* Create a pipe to pass it down to gpg. */
|
||||||
fd_data_map[datac].inbound = 0;
|
fd_data_map[datac].inbound = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ( gpgme_data_get_type (a->data) ) {
|
switch (gpgme_data_get_type (a->data))
|
||||||
|
{
|
||||||
case GPGME_DATA_TYPE_NONE:
|
case GPGME_DATA_TYPE_NONE:
|
||||||
if ( fd_data_map[datac].inbound )
|
if (fd_data_map[datac].inbound)
|
||||||
break; /* allowed */
|
break; /* Allowed. */
|
||||||
xfree (fd_data_map);
|
xfree (fd_data_map);
|
||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Invalid_Type);
|
return mk_error (Invalid_Type);
|
||||||
@ -644,59 +721,68 @@ build_argv ( GpgObject gpg )
|
|||||||
return mk_error (Not_Implemented);
|
return mk_error (Not_Implemented);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create a pipe */
|
/* Create a pipe. */
|
||||||
{
|
{
|
||||||
int fds[2];
|
int fds[2];
|
||||||
|
|
||||||
if (_gpgme_io_pipe (fds, fd_data_map[datac].inbound?1:0 )
|
if (_gpgme_io_pipe (fds, fd_data_map[datac].inbound ? 1 : 0)
|
||||||
== -1) {
|
== -1)
|
||||||
|
{
|
||||||
xfree (fd_data_map);
|
xfree (fd_data_map);
|
||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Pipe_Error);
|
return mk_error (Pipe_Error);
|
||||||
}
|
}
|
||||||
if ( _gpgme_io_set_close_notify (fds[0],
|
if (_gpgme_io_set_close_notify (fds[0],
|
||||||
close_notify_handler, gpg)
|
close_notify_handler, gpg)
|
||||||
|| _gpgme_io_set_close_notify (fds[1],
|
|| _gpgme_io_set_close_notify (fds[1],
|
||||||
close_notify_handler,
|
close_notify_handler,
|
||||||
gpg)) {
|
gpg))
|
||||||
|
{
|
||||||
return mk_error (General_Error);
|
return mk_error (General_Error);
|
||||||
}
|
}
|
||||||
/* if the data_type is FD, we have to do a dup2 here */
|
/* If the data_type is FD, we have to do a dup2 here. */
|
||||||
if (fd_data_map[datac].inbound) {
|
if (fd_data_map[datac].inbound)
|
||||||
|
{
|
||||||
fd_data_map[datac].fd = fds[0];
|
fd_data_map[datac].fd = fds[0];
|
||||||
fd_data_map[datac].peer_fd = fds[1];
|
fd_data_map[datac].peer_fd = fds[1];
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
fd_data_map[datac].fd = fds[1];
|
fd_data_map[datac].fd = fds[1];
|
||||||
fd_data_map[datac].peer_fd = fds[0];
|
fd_data_map[datac].peer_fd = fds[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hack to get hands on the fd later */
|
/* Hack to get hands on the fd later. */
|
||||||
if ( gpg->cmd.used && gpg->cmd.cb_data == a->data ) {
|
if (gpg->cmd.used && gpg->cmd.cb_data == a->data)
|
||||||
assert (gpg->cmd.fd == -1);
|
{
|
||||||
gpg->cmd.fd = fd_data_map[datac].fd;
|
assert (gpg->cmd.idx == -1);
|
||||||
|
gpg->cmd.idx = datac;
|
||||||
}
|
}
|
||||||
|
|
||||||
fd_data_map[datac].data = a->data;
|
fd_data_map[datac].data = a->data;
|
||||||
fd_data_map[datac].dup_to = a->dup_to;
|
fd_data_map[datac].dup_to = a->dup_to;
|
||||||
if ( a->dup_to == -1 ) {
|
if (a->dup_to == -1)
|
||||||
argv[argc] = xtrymalloc ( 25 );
|
{
|
||||||
if (!argv[argc]) {
|
argv[argc] = xtrymalloc (25);
|
||||||
|
if (!argv[argc])
|
||||||
|
{
|
||||||
xfree (fd_data_map);
|
xfree (fd_data_map);
|
||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Out_Of_Core);
|
return mk_error (Out_Of_Core);
|
||||||
}
|
}
|
||||||
sprintf ( argv[argc],
|
sprintf (argv[argc],
|
||||||
a->print_fd? "%d" : "-&%d",
|
a->print_fd ? "%d" : "-&%d",
|
||||||
fd_data_map[datac].peer_fd );
|
fd_data_map[datac].peer_fd);
|
||||||
argc++;
|
argc++;
|
||||||
}
|
}
|
||||||
datac++;
|
datac++;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
argv[argc] = xtrystrdup ( a->arg );
|
{
|
||||||
if (!argv[argc]) {
|
argv[argc] = xtrystrdup (a->arg);
|
||||||
|
if (!argv[argc])
|
||||||
|
{
|
||||||
xfree (fd_data_map);
|
xfree (fd_data_map);
|
||||||
free_argv (argv);
|
free_argv (argv);
|
||||||
return mk_error (Out_Of_Core);
|
return mk_error (Out_Of_Core);
|
||||||
@ -710,10 +796,25 @@ build_argv ( GpgObject gpg )
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
GpgmeError
|
static GpgmeError
|
||||||
_gpgme_gpg_spawn( GpgObject gpg, void *opaque )
|
_gpgme_gpg_add_io_cb (GpgObject gpg, int fd, int dir,
|
||||||
|
GpgmeIOCb handler, void *data, void **tag)
|
||||||
{
|
{
|
||||||
int rc;
|
GpgmeError err = 0;
|
||||||
|
|
||||||
|
*tag = (*gpg->io_cbs.add) (gpg->io_cbs.add_priv, fd, dir, handler, data);
|
||||||
|
if (!tag)
|
||||||
|
err = mk_error (General_Error);
|
||||||
|
if (!err && !dir)
|
||||||
|
/* FIXME Kludge around poll() problem. */
|
||||||
|
err = _gpgme_io_set_nonblocking (fd);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
GpgmeError
|
||||||
|
_gpgme_gpg_spawn (GpgObject gpg, void *opaque)
|
||||||
|
{
|
||||||
|
GpgmeError rc;
|
||||||
int i, n;
|
int i, n;
|
||||||
int pid;
|
int pid;
|
||||||
struct spawn_fd_item_s *fd_child_list, *fd_parent_list;
|
struct spawn_fd_item_s *fd_child_list, *fd_parent_list;
|
||||||
@ -724,35 +825,38 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque )
|
|||||||
if (! _gpgme_get_gpg_path ())
|
if (! _gpgme_get_gpg_path ())
|
||||||
return mk_error (Invalid_Engine);
|
return mk_error (Invalid_Engine);
|
||||||
|
|
||||||
/* Kludge, so that we don't need to check the return code of
|
/* Kludge, so that we don't need to check the return code of all the
|
||||||
* all the gpgme_gpg_add_arg(). we bail out here instead */
|
gpgme_gpg_add_arg(). we bail out here instead */
|
||||||
if ( gpg->arg_error )
|
if (gpg->arg_error)
|
||||||
return mk_error (Out_Of_Core);
|
return mk_error (Out_Of_Core);
|
||||||
|
|
||||||
if (gpg->pm.active)
|
if (gpg->pm.active)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rc = build_argv ( gpg );
|
rc = build_argv (gpg);
|
||||||
if ( rc )
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
n = 3; /* status_fd, colon_fd and end of list */
|
n = 3; /* status_fd, colon_fd and end of list */
|
||||||
for (i=0; gpg->fd_data_map[i].data; i++ )
|
for (i = 0; gpg->fd_data_map[i].data; i++)
|
||||||
n++;
|
n++;
|
||||||
fd_child_list = xtrycalloc ( n+n, sizeof *fd_child_list );
|
fd_child_list = xtrycalloc (n + n, sizeof *fd_child_list);
|
||||||
if (!fd_child_list)
|
if (!fd_child_list)
|
||||||
return mk_error (Out_Of_Core);
|
return mk_error (Out_Of_Core);
|
||||||
fd_parent_list = fd_child_list + n;
|
fd_parent_list = fd_child_list + n;
|
||||||
|
|
||||||
/* build the fd list for the child */
|
/* build the fd list for the child */
|
||||||
n=0;
|
n = 0;
|
||||||
if ( gpg->colon.fnc ) {
|
if (gpg->colon.fnc)
|
||||||
|
{
|
||||||
fd_child_list[n].fd = gpg->colon.fd[1];
|
fd_child_list[n].fd = gpg->colon.fd[1];
|
||||||
fd_child_list[n].dup_to = 1; /* dup to stdout */
|
fd_child_list[n].dup_to = 1; /* dup to stdout */
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
for (i=0; gpg->fd_data_map[i].data; i++ ) {
|
for (i = 0; gpg->fd_data_map[i].data; i++)
|
||||||
if (gpg->fd_data_map[i].dup_to != -1) {
|
{
|
||||||
|
if (gpg->fd_data_map[i].dup_to != -1)
|
||||||
|
{
|
||||||
fd_child_list[n].fd = gpg->fd_data_map[i].peer_fd;
|
fd_child_list[n].fd = gpg->fd_data_map[i].peer_fd;
|
||||||
fd_child_list[n].dup_to = gpg->fd_data_map[i].dup_to;
|
fd_child_list[n].dup_to = gpg->fd_data_map[i].dup_to;
|
||||||
n++;
|
n++;
|
||||||
@ -761,21 +865,24 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque )
|
|||||||
fd_child_list[n].fd = -1;
|
fd_child_list[n].fd = -1;
|
||||||
fd_child_list[n].dup_to = -1;
|
fd_child_list[n].dup_to = -1;
|
||||||
|
|
||||||
/* build the fd list for the parent */
|
/* Build the fd list for the parent. */
|
||||||
n=0;
|
n = 0;
|
||||||
if ( gpg->status.fd[1] != -1 ) {
|
if (gpg->status.fd[1] != -1)
|
||||||
|
{
|
||||||
fd_parent_list[n].fd = gpg->status.fd[1];
|
fd_parent_list[n].fd = gpg->status.fd[1];
|
||||||
fd_parent_list[n].dup_to = -1;
|
fd_parent_list[n].dup_to = -1;
|
||||||
n++;
|
n++;
|
||||||
gpg->status.fd[1] = -1;
|
gpg->status.fd[1] = -1;
|
||||||
}
|
}
|
||||||
if ( gpg->colon.fd[1] != -1 ) {
|
if (gpg->colon.fd[1] != -1)
|
||||||
|
{
|
||||||
fd_parent_list[n].fd = gpg->colon.fd[1];
|
fd_parent_list[n].fd = gpg->colon.fd[1];
|
||||||
fd_parent_list[n].dup_to = -1;
|
fd_parent_list[n].dup_to = -1;
|
||||||
n++;
|
n++;
|
||||||
gpg->colon.fd[1] = -1;
|
gpg->colon.fd[1] = -1;
|
||||||
}
|
}
|
||||||
for (i=0; gpg->fd_data_map[i].data; i++ ) {
|
for (i = 0; gpg->fd_data_map[i].data; i++)
|
||||||
|
{
|
||||||
fd_parent_list[n].fd = gpg->fd_data_map[i].peer_fd;
|
fd_parent_list[n].fd = gpg->fd_data_map[i].peer_fd;
|
||||||
fd_parent_list[n].dup_to = -1;
|
fd_parent_list[n].dup_to = -1;
|
||||||
n++;
|
n++;
|
||||||
@ -784,13 +891,11 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque )
|
|||||||
fd_parent_list[n].fd = -1;
|
fd_parent_list[n].fd = -1;
|
||||||
fd_parent_list[n].dup_to = -1;
|
fd_parent_list[n].dup_to = -1;
|
||||||
|
|
||||||
|
|
||||||
pid = _gpgme_io_spawn (_gpgme_get_gpg_path (),
|
pid = _gpgme_io_spawn (_gpgme_get_gpg_path (),
|
||||||
gpg->argv, fd_child_list, fd_parent_list);
|
gpg->argv, fd_child_list, fd_parent_list);
|
||||||
xfree (fd_child_list);
|
xfree (fd_child_list);
|
||||||
if (pid == -1) {
|
if (pid == -1)
|
||||||
return mk_error (Exec_Error);
|
return mk_error (Exec_Error);
|
||||||
}
|
|
||||||
|
|
||||||
gpg->pid = pid;
|
gpg->pid = pid;
|
||||||
if (gpg->pm.used)
|
if (gpg->pm.used)
|
||||||
@ -798,55 +903,54 @@ _gpgme_gpg_spawn( GpgObject gpg, void *opaque )
|
|||||||
|
|
||||||
/*_gpgme_register_term_handler ( closure, closure_value, pid );*/
|
/*_gpgme_register_term_handler ( closure, closure_value, pid );*/
|
||||||
|
|
||||||
if ( _gpgme_register_pipe_handler ( opaque, gpg_status_handler,
|
rc = _gpgme_gpg_add_io_cb (gpg, gpg->status.fd[0], 1,
|
||||||
gpg, pid, gpg->status.fd[0], 1 ) ) {
|
gpg_status_handler, gpg, &gpg->status.tag);
|
||||||
|
if (rc)
|
||||||
/* FIXME: kill the child */
|
/* FIXME: kill the child */
|
||||||
return mk_error (General_Error);
|
return rc;
|
||||||
|
|
||||||
}
|
if (gpg->colon.fnc)
|
||||||
|
{
|
||||||
if ( gpg->colon.fnc ) {
|
assert (gpg->colon.fd[0] != -1);
|
||||||
assert ( gpg->colon.fd[0] != -1 );
|
rc = _gpgme_gpg_add_io_cb (gpg, gpg->colon.fd[0], 1,
|
||||||
if ( _gpgme_register_pipe_handler ( opaque, gpg_colon_line_handler,
|
gpg_colon_line_handler, gpg,
|
||||||
gpg, pid, gpg->colon.fd[0], 1 ) ) {
|
&gpg->colon.tag);
|
||||||
|
if (rc)
|
||||||
/* FIXME: kill the child */
|
/* FIXME: kill the child */
|
||||||
return mk_error (General_Error);
|
return rc;
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; gpg->fd_data_map[i].data; i++ ) {
|
for (i = 0; gpg->fd_data_map[i].data; i++)
|
||||||
/* Due to problems with select and write we set outbound pipes
|
{
|
||||||
* to non-blocking */
|
if (gpg->cmd.used && i == gpg->cmd.idx)
|
||||||
if (!gpg->fd_data_map[i].inbound) {
|
{
|
||||||
_gpgme_io_set_nonblocking (gpg->fd_data_map[i].fd);
|
/* Park the cmd fd. */
|
||||||
|
gpg->cmd.fd = gpg->fd_data_map[i].fd;
|
||||||
|
gpg->fd_data_map[i].fd = -1;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if ( _gpgme_register_pipe_handler (
|
{
|
||||||
opaque,
|
rc = _gpgme_gpg_add_io_cb (gpg, gpg->fd_data_map[i].fd,
|
||||||
gpg->fd_data_map[i].inbound?
|
gpg->fd_data_map[i].inbound,
|
||||||
_gpgme_data_inbound_handler:_gpgme_data_outbound_handler,
|
gpg->fd_data_map[i].inbound
|
||||||
|
? _gpgme_data_inbound_handler
|
||||||
|
: _gpgme_data_outbound_handler,
|
||||||
gpg->fd_data_map[i].data,
|
gpg->fd_data_map[i].data,
|
||||||
pid, gpg->fd_data_map[i].fd,
|
&gpg->fd_data_map[i].tag);
|
||||||
gpg->fd_data_map[i].inbound )
|
|
||||||
) {
|
|
||||||
/* FIXME: kill the child */
|
|
||||||
return mk_error (General_Error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( gpg->cmd.used )
|
if (rc)
|
||||||
_gpgme_freeze_fd ( gpg->cmd.fd );
|
/* FIXME: kill the child */
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* fixme: check what data we can release here */
|
/* fixme: check what data we can release here */
|
||||||
|
|
||||||
gpg->running = 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static void
|
||||||
gpg_status_handler (void *opaque, int pid, int fd)
|
gpg_status_handler (void *opaque, int fd)
|
||||||
{
|
{
|
||||||
GpgObject gpg = opaque;
|
GpgObject gpg = opaque;
|
||||||
int err;
|
int err;
|
||||||
@ -860,9 +964,11 @@ gpg_status_handler (void *opaque, int pid, int fd)
|
|||||||
GpgmeCtx ctx = (GpgmeCtx) gpg->status.fnc_value;
|
GpgmeCtx ctx = (GpgmeCtx) gpg->status.fnc_value;
|
||||||
ctx->error = err;
|
ctx->error = err;
|
||||||
DEBUG1 ("gpg_handler: read_status problem %d\n - stop", err);
|
DEBUG1 ("gpg_handler: read_status problem %d\n - stop", err);
|
||||||
return 1;
|
_gpgme_io_close (fd);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
return gpg->status.eof;
|
if (gpg->status.eof)
|
||||||
|
_gpgme_io_close (fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -951,7 +1057,14 @@ read_status ( GpgObject gpg )
|
|||||||
* handler does its action */
|
* handler does its action */
|
||||||
if ( nread > 1 )
|
if ( nread > 1 )
|
||||||
DEBUG0 ("ERROR, unexpected data in read_status");
|
DEBUG0 ("ERROR, unexpected data in read_status");
|
||||||
_gpgme_thaw_fd (gpg->cmd.fd);
|
|
||||||
|
_gpgme_gpg_add_io_cb
|
||||||
|
(gpg, gpg->cmd.fd,
|
||||||
|
0, _gpgme_data_outbound_handler,
|
||||||
|
gpg->fd_data_map[gpg->cmd.idx].data,
|
||||||
|
&gpg->fd_data_map[gpg->cmd.idx].tag);
|
||||||
|
gpg->fd_data_map[gpg->cmd.idx].fd = gpg->cmd.fd;
|
||||||
|
gpg->cmd.fd = -1;
|
||||||
}
|
}
|
||||||
else if ( gpg->status.fnc ) {
|
else if ( gpg->status.fnc ) {
|
||||||
gpg->status.fnc ( gpg->status.fnc_value,
|
gpg->status.fnc ( gpg->status.fnc_value,
|
||||||
@ -959,8 +1072,13 @@ read_status ( GpgObject gpg )
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( r->code == STATUS_END_STREAM ) {
|
if ( r->code == STATUS_END_STREAM ) {
|
||||||
if ( gpg->cmd.used )
|
if (gpg->cmd.used)
|
||||||
_gpgme_freeze_fd ( gpg->cmd.fd );
|
{
|
||||||
|
(*gpg->io_cbs.remove)
|
||||||
|
(gpg->fd_data_map[gpg->cmd.idx].tag);
|
||||||
|
gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd;
|
||||||
|
gpg->fd_data_map[gpg->cmd.idx].fd = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -995,21 +1113,23 @@ read_status ( GpgObject gpg )
|
|||||||
* a wrapper for a callback. Same goes for the status thing.
|
* a wrapper for a callback. Same goes for the status thing.
|
||||||
* For now we use this thing here becuase it is easier to implement.
|
* For now we use this thing here becuase it is easier to implement.
|
||||||
*/
|
*/
|
||||||
static int
|
static void
|
||||||
gpg_colon_line_handler ( void *opaque, int pid, int fd )
|
gpg_colon_line_handler (void *opaque, int fd)
|
||||||
{
|
{
|
||||||
GpgObject gpg = opaque;
|
GpgObject gpg = opaque;
|
||||||
GpgmeError rc = 0;
|
GpgmeError rc = 0;
|
||||||
|
|
||||||
assert ( fd == gpg->colon.fd[0] );
|
assert (fd == gpg->colon.fd[0]);
|
||||||
rc = read_colon_line ( gpg );
|
rc = read_colon_line (gpg);
|
||||||
if ( rc ) {
|
if (rc)
|
||||||
|
{
|
||||||
DEBUG1 ("gpg_colon_line_handler: "
|
DEBUG1 ("gpg_colon_line_handler: "
|
||||||
"read problem %d\n - stop", rc);
|
"read problem %d\n - stop", rc);
|
||||||
return 1;
|
_gpgme_io_close (fd);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
if (gpg->colon.eof)
|
||||||
return gpg->colon.eof;
|
_gpgme_io_close (fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static GpgmeError
|
static GpgmeError
|
||||||
@ -1167,7 +1287,7 @@ pipemode_cb ( void *opaque, char *buffer, size_t length, size_t *nread )
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
static int
|
static int
|
||||||
command_cb ( void *opaque, char *buffer, size_t length, size_t *nread )
|
command_cb (void *opaque, char *buffer, size_t length, size_t *nread)
|
||||||
{
|
{
|
||||||
GpgObject gpg = opaque;
|
GpgObject gpg = opaque;
|
||||||
const char *value;
|
const char *value;
|
||||||
@ -1175,43 +1295,50 @@ command_cb ( void *opaque, char *buffer, size_t length, size_t *nread )
|
|||||||
|
|
||||||
DEBUG0 ("command_cb: enter\n");
|
DEBUG0 ("command_cb: enter\n");
|
||||||
assert (gpg->cmd.used);
|
assert (gpg->cmd.used);
|
||||||
if ( !buffer || !length || !nread )
|
if (!buffer || !length || !nread)
|
||||||
return 0; /* those values are reserved for extensions */
|
return 0; /* These values are reserved for extensions. */
|
||||||
*nread =0;
|
*nread = 0;
|
||||||
if ( !gpg->cmd.code ) {
|
if (!gpg->cmd.code)
|
||||||
|
{
|
||||||
DEBUG0 ("command_cb: no code\n");
|
DEBUG0 ("command_cb: no code\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !gpg->cmd.fnc ) {
|
if (!gpg->cmd.fnc)
|
||||||
|
{
|
||||||
DEBUG0 ("command_cb: no user cb\n");
|
DEBUG0 ("command_cb: no user cb\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
value = gpg->cmd.fnc ( gpg->cmd.fnc_value,
|
value = gpg->cmd.fnc (gpg->cmd.fnc_value,
|
||||||
gpg->cmd.code, gpg->cmd.keyword );
|
gpg->cmd.code, gpg->cmd.keyword);
|
||||||
if ( !value ) {
|
if (!value)
|
||||||
|
{
|
||||||
DEBUG0 ("command_cb: no data from user cb\n");
|
DEBUG0 ("command_cb: no data from user cb\n");
|
||||||
gpg->cmd.fnc ( gpg->cmd.fnc_value, 0, value);
|
gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_len = strlen (value);
|
value_len = strlen (value);
|
||||||
if ( value_len+1 > length ) {
|
if (value_len + 1 > length)
|
||||||
|
{
|
||||||
DEBUG0 ("command_cb: too much data from user cb\n");
|
DEBUG0 ("command_cb: too much data from user cb\n");
|
||||||
gpg->cmd.fnc ( gpg->cmd.fnc_value, 0, value);
|
gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy ( buffer, value, value_len );
|
memcpy (buffer, value, value_len);
|
||||||
if ( !value_len || (value_len && value[value_len-1] != '\n') )
|
if (!value_len || (value_len && value[value_len-1] != '\n'))
|
||||||
buffer[value_len++] = '\n';
|
buffer[value_len++] = '\n';
|
||||||
*nread = value_len;
|
*nread = value_len;
|
||||||
|
|
||||||
gpg->cmd.fnc ( gpg->cmd.fnc_value, 0, value);
|
gpg->cmd.fnc (gpg->cmd.fnc_value, 0, value);
|
||||||
gpg->cmd.code = 0;
|
gpg->cmd.code = 0;
|
||||||
/* and sleep again until read_status will wake us up again */
|
/* And sleep again until read_status will wake us up again. */
|
||||||
_gpgme_freeze_fd ( gpg->cmd.fd );
|
(*gpg->io_cbs.remove) (gpg->fd_data_map[gpg->cmd.idx].tag);
|
||||||
|
gpg->cmd.fd = gpg->fd_data_map[gpg->cmd.idx].fd;
|
||||||
|
gpg->fd_data_map[gpg->cmd.idx].fd = -1;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1603,3 +1730,10 @@ _gpgme_gpg_op_verify (GpgObject gpg, GpgmeData sig, GpgmeData text)
|
|||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
_gpgme_gpg_set_io_cbs (GpgObject gpg, struct GpgmeIOCbs *io_cbs)
|
||||||
|
{
|
||||||
|
gpg->io_cbs = *io_cbs;
|
||||||
|
}
|
||||||
|
@ -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_trustlist (GpgObject gpg, const char *pattern);
|
||||||
GpgmeError _gpgme_gpg_op_verify (GpgObject gpg, GpgmeData sig, GpgmeData text);
|
GpgmeError _gpgme_gpg_op_verify (GpgObject gpg, GpgmeData sig, GpgmeData text);
|
||||||
GpgmeError _gpgme_gpg_spawn (GpgObject gpg, void *opaque);
|
GpgmeError _gpgme_gpg_spawn (GpgObject gpg, void *opaque);
|
||||||
|
void _gpgme_gpg_set_io_cbs (GpgObject gpg, struct GpgmeIOCbs *io_cbs);
|
||||||
|
|
||||||
#endif /* RUNGPG_H */
|
#endif /* RUNGPG_H */
|
||||||
|
27
gpgme/sign.c
27
gpgme/sign.c
@ -168,27 +168,19 @@ _gpgme_sign_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GpgmeError
|
static GpgmeError
|
||||||
gpgme_op_sign_start (GpgmeCtx ctx, GpgmeData in, GpgmeData out,
|
_gpgme_op_sign_start (GpgmeCtx ctx, int synchronous,
|
||||||
|
GpgmeData in, GpgmeData out,
|
||||||
GpgmeSigMode mode)
|
GpgmeSigMode mode)
|
||||||
{
|
{
|
||||||
GpgmeError err = 0;
|
GpgmeError err = 0;
|
||||||
|
|
||||||
fail_on_pending_request (ctx);
|
|
||||||
ctx->pending = 1;
|
|
||||||
|
|
||||||
_gpgme_release_result (ctx);
|
|
||||||
|
|
||||||
if (mode != GPGME_SIG_MODE_NORMAL
|
if (mode != GPGME_SIG_MODE_NORMAL
|
||||||
&& mode != GPGME_SIG_MODE_DETACH
|
&& mode != GPGME_SIG_MODE_DETACH
|
||||||
&& mode != GPGME_SIG_MODE_CLEAR)
|
&& mode != GPGME_SIG_MODE_CLEAR)
|
||||||
return mk_error (Invalid_Value);
|
return mk_error (Invalid_Value);
|
||||||
|
|
||||||
/* Create a process object. */
|
err = _gpgme_op_reset (ctx, synchronous);
|
||||||
_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)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
@ -231,6 +223,13 @@ gpgme_op_sign_start (GpgmeCtx ctx, GpgmeData in, GpgmeData out,
|
|||||||
return err;
|
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:
|
* gpgme_op_sign:
|
||||||
* @ctx: The context
|
* @ctx: The context
|
||||||
@ -255,8 +254,8 @@ gpgme_op_sign_start (GpgmeCtx ctx, GpgmeData in, GpgmeData out,
|
|||||||
GpgmeError
|
GpgmeError
|
||||||
gpgme_op_sign (GpgmeCtx ctx, GpgmeData in, GpgmeData out, GpgmeSigMode mode)
|
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)
|
if (!err)
|
||||||
gpgme_wait (ctx, &err, 1);
|
err = _gpgme_wait_one (ctx);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -164,26 +164,13 @@ gpgme_op_trustlist_start (GpgmeCtx ctx, const char *pattern, int max_level)
|
|||||||
{
|
{
|
||||||
GpgmeError err = 0;
|
GpgmeError err = 0;
|
||||||
|
|
||||||
fail_on_pending_request (ctx);
|
|
||||||
if (!pattern || !*pattern)
|
if (!pattern || !*pattern)
|
||||||
return mk_error (Invalid_Value);
|
return mk_error (Invalid_Value);
|
||||||
|
|
||||||
ctx->pending = 1;
|
err = _gpgme_op_reset (ctx, 0);
|
||||||
|
|
||||||
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);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
_gpgme_engine_set_status_handler (ctx->engine, trustlist_status_handler, ctx);
|
|
||||||
err = _gpgme_engine_set_colon_line_handler (ctx->engine,
|
err = _gpgme_engine_set_colon_line_handler (ctx->engine,
|
||||||
trustlist_colon_handler, ctx);
|
trustlist_colon_handler, ctx);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -282,26 +282,18 @@ _gpgme_verify_status_handler (GpgmeCtx ctx, GpgStatusCode code, char *args)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GpgmeError
|
static GpgmeError
|
||||||
gpgme_op_verify_start (GpgmeCtx ctx, GpgmeData sig, GpgmeData text)
|
_gpgme_op_verify_start (GpgmeCtx ctx, int synchronous,
|
||||||
|
GpgmeData sig, GpgmeData text)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int pipemode = 0; /* !!text; use pipemode for detached sigs. */
|
int pipemode = 0; /* !!text; use pipemode for detached sigs. */
|
||||||
|
|
||||||
fail_on_pending_request (ctx);
|
|
||||||
ctx->pending = 1;
|
|
||||||
|
|
||||||
_gpgme_release_result (ctx);
|
|
||||||
|
|
||||||
if (!pipemode)
|
if (!pipemode)
|
||||||
{
|
; /* XXX I am not sure what should happen/not happen in
|
||||||
_gpgme_engine_release (ctx->engine);
|
pipemode. */
|
||||||
ctx->engine = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ctx->engine)
|
err = _gpgme_op_reset (ctx, synchronous);
|
||||||
err = _gpgme_engine_new (ctx->use_cms ? GPGME_PROTOCOL_CMS
|
|
||||||
: GPGME_PROTOCOL_OpenPGP, &ctx->engine);
|
|
||||||
if (err)
|
if (err)
|
||||||
goto leave;
|
goto leave;
|
||||||
|
|
||||||
@ -347,6 +339,12 @@ gpgme_op_verify_start (GpgmeCtx ctx, GpgmeData sig, GpgmeData text)
|
|||||||
return err;
|
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
|
* 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;
|
ctx->notation = NULL;
|
||||||
|
|
||||||
*r_stat = GPGME_SIG_STAT_NONE;
|
*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)
|
if (!err)
|
||||||
{
|
{
|
||||||
gpgme_wait (ctx, &err, 1);
|
err = _gpgme_wait_one (ctx);
|
||||||
if (!err)
|
if (!err)
|
||||||
*r_stat = _gpgme_intersect_stati (ctx->result.verify);
|
*r_stat = _gpgme_intersect_stati (ctx->result.verify);
|
||||||
}
|
}
|
||||||
|
634
gpgme/wait.c
634
gpgme/wait.c
@ -35,389 +35,84 @@
|
|||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "engine.h"
|
#include "engine.h"
|
||||||
|
|
||||||
struct wait_item_s;
|
struct fd_table fdt_global;
|
||||||
struct proc_s;
|
|
||||||
|
|
||||||
static struct proc_s *proc_queue;
|
static GpgmeCtx *ctx_done_list;
|
||||||
DEFINE_STATIC_LOCK (proc_queue_lock);
|
static int ctx_done_list_size;
|
||||||
|
static int ctx_done_list_length;
|
||||||
static int fd_table_size;
|
DEFINE_STATIC_LOCK (ctx_done_list_lock);
|
||||||
static struct io_select_fd_s *fd_table;
|
|
||||||
DEFINE_STATIC_LOCK (fd_table_lock);
|
|
||||||
|
|
||||||
static GpgmeIdleFunc idle_function;
|
static GpgmeIdleFunc idle_function;
|
||||||
|
|
||||||
|
struct wait_item_s
|
||||||
struct proc_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 {
|
|
||||||
struct wait_item_s *next;
|
struct wait_item_s *next;
|
||||||
int (*handler)(void*,int,int);
|
GpgmeIOCb handler;
|
||||||
void *handler_value;
|
void *handler_value;
|
||||||
int inbound; /* this is an inbound data handler fd */
|
int dir;
|
||||||
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);
|
static void run_idle (void);
|
||||||
|
|
||||||
|
|
||||||
/* only to be called with a locked proc_queue */
|
void
|
||||||
static int
|
_gpgme_fd_table_init (fd_table_t fdt)
|
||||||
count_running_fds (struct proc_s *proc)
|
|
||||||
{
|
{
|
||||||
struct wait_item_s *q;
|
INIT_LOCK (fdt->lock);
|
||||||
int count = 0;
|
fdt->fds = NULL;
|
||||||
|
fdt->size = 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
_gpgme_remove_proc_from_wait_queue (int pid)
|
_gpgme_fd_table_deinit (fd_table_t fdt)
|
||||||
{
|
{
|
||||||
struct proc_s *proc, *last;
|
DESTROY_LOCK (fdt->lock);
|
||||||
|
if (fdt->fds)
|
||||||
DEBUG1 ("removing process %d", pid);
|
xfree (fdt->fds);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XXX We should keep a marker and roll over for speed. */
|
||||||
/**
|
|
||||||
* 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()
|
|
||||||
*/
|
|
||||||
GpgmeError
|
GpgmeError
|
||||||
_gpgme_register_pipe_handler (void *opaque,
|
_gpgme_fd_table_put (fd_table_t fdt, int fd, int dir, void *opaque, int *idx)
|
||||||
int (*handler)(void*,int,int),
|
|
||||||
void *handler_value,
|
|
||||||
int pid, int fd, int inbound)
|
|
||||||
{
|
{
|
||||||
GpgmeCtx ctx = opaque;
|
int i, j;
|
||||||
struct wait_item_s *q;
|
struct io_select_fd_s *new_fds;
|
||||||
struct proc_s *proc;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
assert (opaque);
|
LOCK (fdt->lock);
|
||||||
assert (handler);
|
for (i = 0; i < fdt->size; i++)
|
||||||
|
|
||||||
/* 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)
|
|
||||||
{
|
{
|
||||||
/* A new process. */
|
if (fdt->fds[i].fd == -1)
|
||||||
proc = xtrycalloc (1, sizeof *proc);
|
break;
|
||||||
if (!proc)
|
}
|
||||||
|
if (i == fdt->size)
|
||||||
{
|
{
|
||||||
UNLOCK (proc_queue_lock);
|
#define FDT_ALLOCSIZE 10
|
||||||
|
new_fds = xtryrealloc (fdt->fds, (fdt->size + FDT_ALLOCSIZE)
|
||||||
|
* sizeof (*new_fds));
|
||||||
|
if (!new_fds)
|
||||||
|
{
|
||||||
|
UNLOCK (fdt->lock);
|
||||||
return mk_error (Out_Of_Core);
|
return mk_error (Out_Of_Core);
|
||||||
}
|
}
|
||||||
proc->pid = pid;
|
|
||||||
proc->ctx = ctx;
|
|
||||||
proc->next = proc_queue;
|
|
||||||
proc_queue = proc;
|
|
||||||
}
|
|
||||||
assert (proc->ctx == ctx);
|
|
||||||
q->proc = proc;
|
|
||||||
q->next = proc->handler_list;
|
|
||||||
proc->handler_list = q;
|
|
||||||
UNLOCK (proc_queue_lock);
|
|
||||||
|
|
||||||
LOCK (fd_table_lock);
|
fdt->fds = new_fds;
|
||||||
again:
|
fdt->size += FDT_ALLOCSIZE;
|
||||||
for (i=0; i < fd_table_size; i++)
|
for (j = 0; j < FDT_ALLOCSIZE; j++)
|
||||||
{
|
fdt->fds[i + j].fd = -1;
|
||||||
if (fd_table[i].fd == -1)
|
}
|
||||||
{
|
|
||||||
fd_table[i].fd = fd;
|
fdt->fds[i].fd = fd;
|
||||||
fd_table[i].for_read = inbound;
|
fdt->fds[i].for_read = (dir == 1);
|
||||||
fd_table[i].for_write = !inbound;
|
fdt->fds[i].for_write = (dir == 0);
|
||||||
fd_table[i].signaled = 0;
|
fdt->fds[i].frozen = 0;
|
||||||
fd_table[i].frozen = 0;
|
fdt->fds[i].signaled = 0;
|
||||||
fd_table[i].opaque = q;
|
fdt->fds[i].opaque = opaque;
|
||||||
UNLOCK (fd_table_lock);
|
UNLOCK (fdt->lock);
|
||||||
|
*idx = i;
|
||||||
return 0;
|
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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:
|
* gpgme_register_idle:
|
||||||
* @fnc: Callers idle function
|
* @fnc: Callers idle function
|
||||||
@ -438,7 +133,6 @@ gpgme_register_idle (GpgmeIdleFunc idle)
|
|||||||
return old_idle;
|
return old_idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
run_idle ()
|
run_idle ()
|
||||||
{
|
{
|
||||||
@ -446,3 +140,233 @@ run_idle ()
|
|||||||
if (idle_function)
|
if (idle_function)
|
||||||
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
|
#define WAIT_H
|
||||||
|
|
||||||
#include "gpgme.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,
|
void _gpgme_fd_table_init (fd_table_t fdt);
|
||||||
int (*handler) (void*, int, int),
|
void _gpgme_fd_table_deinit (fd_table_t fdt);
|
||||||
void *handler_value,
|
|
||||||
int pid, int fd, int inbound);
|
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 */
|
#endif /* WAIT_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user