diff options
Diffstat (limited to 'src/assuan-handler.c')
-rw-r--r-- | src/assuan-handler.c | 204 |
1 files changed, 76 insertions, 128 deletions
diff --git a/src/assuan-handler.c b/src/assuan-handler.c index 007bba2..bc8ec51 100644 --- a/src/assuan-handler.c +++ b/src/assuan-handler.c @@ -1,23 +1,26 @@ /* assuan-handler.c - dispatch commands - * Copyright (C) 2001, 2002, 2003, 2007 Free Software Foundation, Inc. - * - * This file is part of Assuan. - * - * Assuan is free software; you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Assuan 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see <http://www.gnu.org/licenses/>. + Copyright (C) 2001, 2002, 2003, 2007, 2009 Free Software Foundation, Inc. + + This file is part of Assuan. + + Assuan is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + Assuan 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, see <http://www.gnu.org/licenses/>. */ +#ifdef HAVE_CONFIG_H #include <config.h> +#endif + #include <stdlib.h> #include <stdio.h> #include <string.h> @@ -40,7 +43,8 @@ static int dummy_handler (assuan_context_t ctx, char *line) { return - PROCESS_DONE (ctx, set_error (ctx, Server_Fault, "no handler registered")); + PROCESS_DONE (ctx, set_error (ctx, GPG_ERR_ASSUAN_SERVER_FAULT, + "no handler registered")); } @@ -55,7 +59,7 @@ std_handler_cancel (assuan_context_t ctx, char *line) { if (ctx->cancel_notify_fnc) ctx->cancel_notify_fnc (ctx); - return PROCESS_DONE (ctx, set_error (ctx, Not_Implemented, NULL)); + return PROCESS_DONE (ctx, set_error (ctx, GPG_ERR_NOT_IMPLEMENTED, NULL)); } static int @@ -67,10 +71,10 @@ std_handler_option (assuan_context_t ctx, char *line) ; if (!*key) return - PROCESS_DONE (ctx, set_error (ctx, Syntax_Error, "argument required")); + PROCESS_DONE (ctx, set_error (ctx, GPG_ERR_ASS_SYNTAX, "argument required")); if (*key == '=') return - PROCESS_DONE (ctx, set_error (ctx, Syntax_Error, + PROCESS_DONE (ctx, set_error (ctx, GPG_ERR_ASS_SYNTAX, "no option name given")); for (value=key; *value && !spacep (value) && *value != '='; value++) ; @@ -87,7 +91,7 @@ std_handler_option (assuan_context_t ctx, char *line) ; if (!*value) return - PROCESS_DONE (ctx, set_error (ctx, Syntax_Error, + PROCESS_DONE (ctx, set_error (ctx, GPG_ERR_ASS_SYNTAX, "option argument expected")); } if (*value) @@ -103,7 +107,7 @@ std_handler_option (assuan_context_t ctx, char *line) key += 2; /* the double dashes are optional */ if (*key == '-') return PROCESS_DONE (ctx, - set_error (ctx, Syntax_Error, + set_error (ctx, GPG_ERR_ASS_SYNTAX, "option should not begin with one dash")); if (ctx->option_handler_fnc) @@ -118,13 +122,14 @@ std_handler_bye (assuan_context_t ctx, char *line) ctx->bye_notify_fnc (ctx); assuan_close_input_fd (ctx); assuan_close_output_fd (ctx); - return PROCESS_DONE (ctx, _assuan_error (-1)); /* pretty simple :-) */ + /* pretty simple :-) */ + return PROCESS_DONE (ctx, _assuan_error (GPG_ERR_EOF)); } static int std_handler_auth (assuan_context_t ctx, char *line) { - return PROCESS_DONE (ctx, set_error (ctx, Not_Implemented, NULL)); + return PROCESS_DONE (ctx, set_error (ctx, GPG_ERR_NOT_IMPLEMENTED, NULL)); } static int @@ -158,24 +163,24 @@ std_handler_help (assuan_context_t ctx, char *line) static int std_handler_end (assuan_context_t ctx, char *line) { - return PROCESS_DONE (ctx, set_error (ctx, Not_Implemented, NULL)); + return PROCESS_DONE (ctx, set_error (ctx, GPG_ERR_NOT_IMPLEMENTED, NULL)); } -assuan_error_t +gpg_error_t assuan_command_parse_fd (assuan_context_t ctx, char *line, assuan_fd_t *rfd) { char *endp; if ((strncmp (line, "FD", 2) && strncmp (line, "fd", 2)) || (line[2] != '=' && line[2] != '\0' && !spacep(&line[2]))) - return set_error (ctx, Syntax_Error, "FD[=<n>] expected"); + return set_error (ctx, GPG_ERR_ASS_SYNTAX, "FD[=<n>] expected"); line += 2; if (*line == '=') { line ++; if (!digitp (*line)) - return set_error (ctx, Syntax_Error, "number required"); + return set_error (ctx, GPG_ERR_ASS_SYNTAX, "number required"); #ifdef HAVE_W32_SYSTEM /* Fixme: For a W32/64bit system we will need to change the cast and the conversion fucntion. */ @@ -187,9 +192,9 @@ assuan_command_parse_fd (assuan_context_t ctx, char *line, assuan_fd_t *rfd) memset (line, ' ', endp? (endp-line):strlen(line)); if (*rfd == ctx->inbound.fd) - return set_error (ctx, Parameter_Conflict, "fd same as inbound fd"); + return set_error (ctx, GPG_ERR_ASS_PARAMETER, "fd same as inbound fd"); if (*rfd == ctx->outbound.fd) - return set_error (ctx, Parameter_Conflict, "fd same as outbound fd"); + return set_error (ctx, GPG_ERR_ASS_PARAMETER, "fd same as outbound fd"); return 0; } else @@ -282,7 +287,7 @@ assuan_register_command (assuan_context_t ctx, cmd_name = NULL; if (!cmd_name) - return _assuan_error (ASSUAN_Invalid_Value); + return _assuan_error (GPG_ERR_ASS_INV_VALUE); if (!handler) { /* find a default handler. */ @@ -303,18 +308,18 @@ assuan_register_command (assuan_context_t ctx, if (!ctx->cmdtbl) { ctx->cmdtbl_size = 50; - ctx->cmdtbl = xtrycalloc ( ctx->cmdtbl_size, sizeof *ctx->cmdtbl); + ctx->cmdtbl = _assuan_calloc (ctx->cmdtbl_size, sizeof *ctx->cmdtbl); if (!ctx->cmdtbl) - return _assuan_error (ASSUAN_Out_Of_Core); + return _assuan_error (gpg_err_code_from_syserror ()); ctx->cmdtbl_used = 0; } else if (ctx->cmdtbl_used >= ctx->cmdtbl_size) { struct cmdtbl_s *x; - x = xtryrealloc ( ctx->cmdtbl, (ctx->cmdtbl_size+10) * sizeof *x); + x = _assuan_realloc ( ctx->cmdtbl, (ctx->cmdtbl_size+10) * sizeof *x); if (!x) - return _assuan_error (ASSUAN_Out_Of_Core); + return _assuan_error (gpg_err_code_from_syserror ()); ctx->cmdtbl = x; ctx->cmdtbl_size += 50; } @@ -330,7 +335,7 @@ assuan_register_post_cmd_notify (assuan_context_t ctx, void (*fnc)(assuan_context_t, int)) { if (!ctx) - return _assuan_error (ASSUAN_Invalid_Value); + return _assuan_error (GPG_ERR_ASS_INV_VALUE); ctx->post_cmd_notify_fnc = fnc; return 0; } @@ -340,7 +345,7 @@ assuan_register_bye_notify (assuan_context_t ctx, void (*fnc)(assuan_context_t)) { if (!ctx) - return _assuan_error (ASSUAN_Invalid_Value); + return _assuan_error (GPG_ERR_ASS_INV_VALUE); ctx->bye_notify_fnc = fnc; return 0; } @@ -350,7 +355,7 @@ assuan_register_reset_notify (assuan_context_t ctx, void (*fnc)(assuan_context_t)) { if (!ctx) - return _assuan_error (ASSUAN_Invalid_Value); + return _assuan_error (GPG_ERR_ASS_INV_VALUE); ctx->reset_notify_fnc = fnc; return 0; } @@ -360,7 +365,7 @@ assuan_register_cancel_notify (assuan_context_t ctx, void (*fnc)(assuan_context_t)) { if (!ctx) - return _assuan_error (ASSUAN_Invalid_Value); + return _assuan_error (GPG_ERR_ASS_INV_VALUE); ctx->cancel_notify_fnc = fnc; return 0; } @@ -371,7 +376,7 @@ assuan_register_option_handler (assuan_context_t ctx, const char*, const char*)) { if (!ctx) - return _assuan_error (ASSUAN_Invalid_Value); + return _assuan_error (GPG_ERR_ASS_INV_VALUE); ctx->option_handler_fnc = fnc; return 0; } @@ -381,7 +386,7 @@ assuan_register_input_notify (assuan_context_t ctx, void (*fnc)(assuan_context_t, const char *)) { if (!ctx) - return _assuan_error (ASSUAN_Invalid_Value); + return _assuan_error (GPG_ERR_ASS_INV_VALUE); ctx->input_notify_fnc = fnc; return 0; } @@ -391,7 +396,7 @@ assuan_register_output_notify (assuan_context_t ctx, void (*fnc)(assuan_context_t, const char *)) { if (!ctx) - return _assuan_error (ASSUAN_Invalid_Value); + return _assuan_error (GPG_ERR_ASS_INV_VALUE); ctx->output_notify_fnc = fnc; return 0; } @@ -422,7 +427,7 @@ _assuan_register_std_commands (assuan_context_t ctx) static int handle_data_line (assuan_context_t ctx, char *line, int linelen) { - return set_error (ctx, Not_Implemented, NULL); + return set_error (ctx, GPG_ERR_NOT_IMPLEMENTED, NULL); } /* like ascii_strcasecmp but assume that B is already uppercase */ @@ -465,7 +470,7 @@ dispatch_command (assuan_context_t ctx, char *line, int linelen) ; if (p==line) return PROCESS_DONE - (ctx, set_error (ctx, Syntax_Error, "leading white-space")); + (ctx, set_error (ctx, GPG_ERR_ASS_SYNTAX, "leading white-space")); if (*p) { /* Skip over leading WS after the keyword */ *p++ = 0; @@ -488,7 +493,7 @@ dispatch_command (assuan_context_t ctx, char *line, int linelen) } } if (!s) - return PROCESS_DONE (ctx, set_error (ctx, Unknown_Command, NULL)); + return PROCESS_DONE (ctx, set_error (ctx, GPG_ERR_ASS_UNKNOWN_CMD, NULL)); line += shift; linelen -= shift; @@ -502,7 +507,7 @@ int assuan_process_done (assuan_context_t ctx, int rc) { if (!ctx->in_command) - return _assuan_error (ASSUAN_General_Error); + return _assuan_error (GPG_ERR_ASS_GENERAL); ctx->in_command = 0; @@ -526,9 +531,9 @@ assuan_process_done (assuan_context_t ctx, int rc) /* Error handling. */ if (!rc) { - rc = assuan_write_line (ctx, ctx->okay_line? ctx->okay_line : "OK"); + rc = assuan_write_line (ctx, ctx->okay_line ? ctx->okay_line : "OK"); } - else if (err_is_eof (rc)) + else if (gpg_err_code (rc) == GPG_ERR_EOF) { /* No error checking because the peer may have already disconnect. */ assuan_write_line (ctx, "OK closing connection"); ctx->finish_handler (ctx); @@ -536,72 +541,15 @@ assuan_process_done (assuan_context_t ctx, int rc) else { char errline[300]; - - if (rc < 100) - sprintf (errline, "ERR %d server fault (%.50s)", - _assuan_error (ASSUAN_Server_Fault), assuan_strerror (rc)); - else - { - const char *text = ctx->err_no == rc? ctx->err_str:NULL; - -#if defined(HAVE_W32_SYSTEM) - unsigned int source, code; - char ebuf[50]; - const char *esrc; + + const char *text = ctx->err_no == rc ? ctx->err_str : NULL; + char ebuf[50]; - source = ((rc >> 24) & 0xff); - code = (rc & 0x00ffffff); - if (source - && !_assuan_gpg_strerror_r (rc, ebuf, sizeof ebuf) - && (esrc=_assuan_gpg_strsource (rc))) - { - /* Assume this is an libgpg-error. */ - sprintf (errline, "ERR %d %.50s <%.30s>%s%.100s", - rc, ebuf, esrc, - text? " - ":"", text?text:""); - } - else -#elif defined(__GNUC__) && defined(__ELF__) - /* If we have weak symbol support we try to use the error - strings from libgpg-error without creating a dependency. - They are used for debugging purposes only, so there is no - problem if they are not available. We need to make sure - that we are using ELF because only this guarantees that - weak symbol support is available in case GNU ld is not - used. It seems that old gcc versions don't implement the - weak attribute properly but it works with the weak - pragma. */ - - unsigned int source, code; - - int gpg_strerror_r (unsigned int err, char *buf, size_t buflen) - __attribute__ ((weak)); - const char *gpg_strsource (unsigned int err) - __attribute__ ((weak)); -#if __GNUC__ < 3 -#pragma weak gpg_strerror_r -#pragma weak gpg_strsource -#endif + gpg_strerror_r (rc, ebuf, sizeof (ebuf)); + sprintf (errline, "ERR %d %.50s <%.30s>%s%.100s", + rc, ebuf, gpg_strsource (rc), + text? " - ":"", text?text:""); - source = ((rc >> 24) & 0xff); - code = (rc & 0x00ffffff); - if (source && gpg_strsource && gpg_strerror_r) - { - /* Assume this is an libgpg-error. */ - char ebuf[50]; - - gpg_strerror_r (rc, ebuf, sizeof ebuf ); - sprintf (errline, "ERR %d %.50s <%.30s>%s%.100s", - rc, - ebuf, - gpg_strsource (rc), - text? " - ":"", text?text:""); - } - else -#endif /* __GNUC__ && __ELF__ */ - sprintf (errline, "ERR %d %.50s%s%.100s", - rc, assuan_strerror (rc), text? " - ":"", text?text:""); - } rc = assuan_write_line (ctx, errline); } @@ -611,7 +559,7 @@ assuan_process_done (assuan_context_t ctx, int rc) ctx->confidential = 0; if (ctx->okay_line) { - xfree (ctx->okay_line); + _assuan_free (ctx->okay_line); ctx->okay_line = NULL; } @@ -694,13 +642,13 @@ assuan_process_next (assuan_context_t ctx) -static int +static gpg_error_t process_request (assuan_context_t ctx) { int rc; if (ctx->in_inquire) - return _assuan_error (ASSUAN_Nested_Commands); + return _assuan_error (GPG_ERR_ASS_NESTED_COMMANDS); do { @@ -732,7 +680,7 @@ process_request (assuan_context_t ctx) * Return value: 0 on success or an error code if the assuan operation * failed. Note, that no error is returned for operational errors. **/ -int +gpg_error_t assuan_process (assuan_context_t ctx) { int rc; @@ -741,7 +689,7 @@ assuan_process (assuan_context_t ctx) rc = process_request (ctx); } while (!rc); - if (err_is_eof (rc)) + if (gpg_err_code (rc) == GPG_ERR_EOF) rc = 0; return rc; @@ -845,26 +793,26 @@ assuan_get_data_fp (assuan_context_t ctx) /* Set the text used for the next OK reponse. This string is automatically reset to NULL after the next command. */ -assuan_error_t +gpg_error_t assuan_set_okay_line (assuan_context_t ctx, const char *line) { if (!ctx) - return _assuan_error (ASSUAN_Invalid_Value); + return _assuan_error (GPG_ERR_ASS_INV_VALUE); if (!line) { - xfree (ctx->okay_line); + _assuan_free (ctx->okay_line); ctx->okay_line = NULL; } else { /* FIXME: we need to use gcry_is_secure() to test whether we should allocate the entire line in secure memory */ - char *buf = xtrymalloc (3+strlen(line)+1); + char *buf = _assuan_malloc (3 + strlen(line) + 1); if (!buf) - return _assuan_error (ASSUAN_Out_Of_Core); + return _assuan_error (gpg_err_code_from_syserror ()); strcpy (buf, "OK "); strcpy (buf+3, line); - xfree (ctx->okay_line); + _assuan_free (ctx->okay_line); ctx->okay_line = buf; } return 0; @@ -872,17 +820,17 @@ assuan_set_okay_line (assuan_context_t ctx, const char *line) -assuan_error_t +gpg_error_t assuan_write_status (assuan_context_t ctx, const char *keyword, const char *text) { char buffer[256]; char *helpbuf; size_t n; - assuan_error_t ae; + gpg_error_t ae; if ( !ctx || !keyword) - return _assuan_error (ASSUAN_Invalid_Value); + return _assuan_error (GPG_ERR_ASS_INV_VALUE); if (!text) text = ""; @@ -898,7 +846,7 @@ assuan_write_status (assuan_context_t ctx, } ae = assuan_write_line (ctx, buffer); } - else if ( (helpbuf = xtrymalloc (n)) ) + else if ( (helpbuf = _assuan_malloc (n)) ) { strcpy (helpbuf, "S "); strcat (helpbuf, keyword); @@ -908,7 +856,7 @@ assuan_write_status (assuan_context_t ctx, strcat (helpbuf, text); } ae = assuan_write_line (ctx, helpbuf); - xfree (helpbuf); + _assuan_free (helpbuf); } else ae = 0; |