From d3341e71256d0edec074c6f180fc19dad0c21f0a Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Tue, 27 Nov 2007 20:17:03 -0500 Subject: [PATCH] Added pwmd_inquire(). This removes PWMD_OPTION_INQUIRE_FUNC and PWMD_OPTION_INQUIRE_DATA. Don't send the SAVE command after an error in pwmc. --- libpwmd.c | 18 ++++++++++++------ libpwmd.h | 52 ++++++++++++++++++++++++---------------------------- pwmc.c | 40 ++++++++++------------------------------ 3 files changed, 46 insertions(+), 64 deletions(-) diff --git a/libpwmd.c b/libpwmd.c index f2358a87..1c299db6 100644 --- a/libpwmd.c +++ b/libpwmd.c @@ -211,6 +211,7 @@ static int _inquire_cb(void *data, const char *keyword) pwm_t *pwm = (pwm_t *)data; gpg_error_t rc = 0; + /* Shouldn't get this far without a callback. */ if (!pwm->inquire_func) return GPG_ERR_INV_ARG; @@ -262,6 +263,17 @@ static gpg_error_t assuan_command(pwm_t *pwm, assuan_context_t ctx, return gpg_err_code(rc); } +gpg_error_t pwmd_inquire(pwm_t *pwm, const char *cmd, pwmd_inquire_fn fn, + void *data) +{ + if (!pwm || !cmd || !fn) + return GPG_ERR_INV_ARG; + + pwm->inquire_func = fn; + pwm->inquire_data = data; + return assuan_command(pwm, pwm->ctx, NULL, cmd); +} + gpg_error_t pwmd_terminate_pinentry(pwm_t *pwm) { #ifndef USE_PINENTRY @@ -1095,12 +1107,6 @@ gpg_error_t pwmd_setopt(pwm_t *pwm, pwmd_option_t opt, ...) va_start(ap, opt); switch (opt) { - case PWMD_OPTION_INQUIRE_FUNC: - pwm->inquire_func = va_arg(ap, pwmd_inquire_fn); - break; - case PWMD_OPTION_INQUIRE_DATA: - pwm->inquire_data = va_arg(ap, void *); - break; case PWMD_OPTION_STATUS_FUNC: pwm->status_func = va_arg(ap, pwmd_status_fn); break; diff --git a/libpwmd.h b/libpwmd.h index 7c383c5c..70c64977 100644 --- a/libpwmd.h +++ b/libpwmd.h @@ -59,21 +59,22 @@ typedef char *(*pwmd_password_fn)(pwm_t *pwm, void *data); */ typedef int (*pwmd_status_fn)(void *data, const char *line); - /* - * A callback to be set with PWMD_OPTION_INQUIRE_FUNC via pwmd_setopt(). - * 'data' is set with PWMD_OPTION_INQUIRE_DATA. 'keyword' is the command which - * the INQUIRE is related (i.e., "STORE"). 'rc' is the return code from - * assuan_send_data() and is initially 0 on the first call to the set - * callback. This gives the client a chance to cleanup and should probably - * return the same error code, if set, after doing so. + * A callback function that is passed to pwmd_inquire(). 'data' is user data + * that was passed to pwmd_inquire(). 'keyword' is the same as the 'cmd' + * argument to pwmd_inquire(). + * + * 'rc' is the return code from assuan_send_data() and is initially 0 on the + * first call to the set callback. This gives the client a chance to cleanup + * if assuan_send_data() fails and should probably return the same error code, + * if set, after doing so. * - * 'result' should be set to the data which is of 'len' bytes. The data is not - * modified. + * 'result' should be set to the data to be sent which is of 'len' bytes. The + * data is not modified. * * The function should return GPG_ERR_EOF when no more data needs to be sent, - * 0 when there is more data pending or an error code which will terminate the - * INQUIRE. See pwmc.c for example usage. + * 0 if there is more data pending or an error code which will terminate the + * INQUIRE. */ typedef gpg_error_t (*pwmd_inquire_fn)(void *data, const char *keyword, gpg_error_t rc, char **result, size_t *len); @@ -180,20 +181,6 @@ typedef enum { * Data passed to the status function. */ PWMD_OPTION_STATUS_DATA, - - /* - * PWMD_OPTION_INQUIRE_FUNC - * - * The function to retrieve data for an INQUIRE. - */ - PWMD_OPTION_INQUIRE_FUNC, - - /* - * PWMD_OPTION_INQUIRE_DATA - * - * Data passed to the inquire function. - */ - PWMD_OPTION_INQUIRE_DATA, } pwmd_option_t; /* @@ -300,9 +287,8 @@ gpg_error_t pwmd_terminate_pinentry(pwm_t *pwm) __attribute__ ((warn_unused_resu * the error to pwmd_strerror(). If successful the function returns 0 and the * 'result' is the character data of the command or NULL if there was none. * - * For commands which use an INQUIRE (i.e., "STORE"), be sure to set the - * inquire callback function with pwmd_setopt(). See pwmd_inquire_fn for more - * info. + * For commands which use an INQUIRE (i.e., "STORE"), use pwmd_inquire() and + * not pwmd_command(). * * A note about the BYE command: Client's should not send this command * directly with pwmd_command(). They should use pwmd_close() instead because @@ -312,6 +298,16 @@ gpg_error_t pwmd_terminate_pinentry(pwm_t *pwm) __attribute__ ((warn_unused_resu * descriptor resulting in a segfault. */ gpg_error_t pwmd_command(pwm_t *pwm, char **result, const char *cmd, ...) __attribute__ ((warn_unused_result)); + +/* + * Commands which use an INQUIRE to send data should use this function and not + * pwmd_command(). 'cmd' is the command to send and is also the 'keyword' + * argument to the callback function 'func'. 'data' is user data passed to the + * callback function. Returnes 0 on success or and error code which may have + * been returned from the callback function. + */ +gpg_error_t pwmd_inquire(pwm_t *pwm, const char *cmd, pwmd_inquire_fn func, + void *data) __attribute__ ((warn_unused_result)); /* * Free's the memory used by the result of pwmd_command() if any. It is diff --git a/pwmc.c b/pwmc.c index 1c551758..a9c571b8 100644 --- a/pwmc.c +++ b/pwmc.c @@ -134,10 +134,6 @@ static gpg_error_t do_inquire(void *data, const char *keyword, gpg_error_t rc, return rc; } - /* No data specified after "STORE". */ - if (!inq) - return EPWMD_COMMAND_SYNTAX; - buf[0] = 0; p = buf; @@ -320,12 +316,6 @@ int main(int argc, char *argv[]) } } - if (set_pinentry_option(PWMD_OPTION_INQUIRE_FUNC, do_inquire)) { - show_error(error); - pwmd_close(pwm); - exit(EXIT_FAILURE); - } - if (show_status) { if (set_pinentry_option(PWMD_OPTION_STATUS_FUNC, status_msg_cb)) { show_error(error); @@ -364,30 +354,21 @@ int main(int argc, char *argv[]) goto done; /* - * This is a known INQUIRE command. We need to set a callback to send the - * data. + * This is a known INQUIRE command. We use pwmd_inquire() to send the + * data from the do_inquire() callback function. */ if (strncasecmp(p, "STORE ", 6) == 0) { struct inquire_s *inq = malloc(sizeof(struct inquire_s)); - inq->data = xstrdup(p+6); - inq->fp = inquirefp; - - if (set_pinentry_option(PWMD_OPTION_INQUIRE_DATA, inq)) { - xfree(inq->data); - free(inq); - pwmd_close(pwm); - exit(EXIT_FAILURE); + if (!inq) { + show_error(gpg_error_from_errno(ENOMEM)); + ret = EXIT_FAILURE; + goto done; } - /* - * Cannot send more than the inquire command itself because we have to - * wait for the INQUIRE server response. The inquire callback will - * send the data already read from fgets(). pwmd_command() will block - * from assuan_transact() until the callback returns GPG_ERR_EOF or an - * error. - */ - error = pwmd_command(pwm, &result, "STORE"); + inq->data = xstrdup(p+6); + inq->fp = inquirefp; + error = pwmd_inquire(pwm, "STORE", do_inquire, inq); free(inq); if (error) { @@ -395,7 +376,6 @@ int main(int argc, char *argv[]) ret = EXIT_FAILURE; } - memset(command, 0, sizeof(command)); goto done; } @@ -428,7 +408,7 @@ int main(int argc, char *argv[]) done: memset(command, 0, sizeof(command)); - if (save) { + if (!error && save) { save_again: error = pwmd_save(pwm); -- 2.11.4.GIT