diff options
Diffstat (limited to 'assuan/assuan-handler.c')
| -rw-r--r-- | assuan/assuan-handler.c | 161 | 
1 files changed, 69 insertions, 92 deletions
| diff --git a/assuan/assuan-handler.c b/assuan/assuan-handler.c index 6ddfe889..f8b85dbb 100644 --- a/assuan/assuan-handler.c +++ b/assuan/assuan-handler.c @@ -1,5 +1,5 @@  /* assuan-handler.c - dispatch commands  - *	Copyright (C) 2001, 2002 Free Software Foundation, Inc. + *	Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.   *   * This file is part of Assuan.   * @@ -25,27 +25,12 @@  #include "assuan-defs.h" -#define spacep(p)  (*(p) == ' ' || *(p) == '\t') -#define digitp(a) ((a) >= '0' && (a) <= '9') -#if !HAVE_FOPENCOOKIE -/* Provide structure for our dummy replacement function.  Usually this -   is defined in ../common/util.h but assuan should be self -   contained. */ -/* Fixme: Remove fopencoookie :-(( */ -typedef struct -{ -  ssize_t (*read)(void*,char*,size_t); -  ssize_t (*write)(void*,const char*,size_t); -  int (*seek)(void*,off_t*,int); -  int (*close)(void*); -} _IO_cookie_io_functions_t; -typedef _IO_cookie_io_functions_t cookie_io_functions_t; -FILE *fopencookie (void *cookie, const char *opentype, -                   cookie_io_functions_t funclist); -#endif /*!HAVE_FOPENCOOKIE*/ +#define spacep(p)  (*(p) == ' ' || *(p) == '\t') +#define digitp(a) ((a) >= '0' && (a) <= '9') +static int my_strcasecmp (const char *a, const char *b); @@ -149,25 +134,32 @@ std_handler_end (ASSUAN_CONTEXT ctx, char *line)    return set_error (ctx, Not_Implemented, NULL);   } -static int -parse_cmd_input_output (ASSUAN_CONTEXT ctx, char *line, int *rfd) +AssuanError +assuan_command_parse_fd (ASSUAN_CONTEXT ctx, char *line, int *rfd)  {    char *endp; -  if (strncmp (line, "FD=", 3)) -    return set_error (ctx, Syntax_Error, "FD=<n> expected"); -  line += 3; -  if (!digitp (*line)) -    return set_error (ctx, Syntax_Error, "number required"); -  *rfd = strtoul (line, &endp, 10); -  /* remove that argument so that a notify handler won't see it */ -  memset (line, ' ', endp? (endp-line):strlen(line)); - -  if (*rfd == ctx->inbound.fd) -    return set_error (ctx, Parameter_Conflict, "fd same as inbound fd"); -  if (*rfd == ctx->outbound.fd) -    return set_error (ctx, Parameter_Conflict, "fd same as outbound fd"); -  return 0; +  if (strncmp (line, "FD", 2) != 0 || (line[2] != '=' && line[2] != '\0')) +    return set_error (ctx, Syntax_Error, "FD[=<n>] expected"); +  line += 2; +  if (*line == '=') +    { +      line ++; +      if (!digitp (*line)) +	return set_error (ctx, Syntax_Error, "number required"); +      *rfd = strtoul (line, &endp, 10); +      /* remove that argument so that a notify handler won't see it */ +      memset (line, ' ', endp? (endp-line):strlen(line)); + +      if (*rfd == ctx->inbound.fd) +	return set_error (ctx, Parameter_Conflict, "fd same as inbound fd"); +      if (*rfd == ctx->outbound.fd) +	return set_error (ctx, Parameter_Conflict, "fd same as outbound fd"); +      return 0; +    } +  else +    /* Our peer has sent the file descriptor.  */ +    return assuan_receivefd (ctx, rfd);  }  /* Format is INPUT FD=<n> */ @@ -176,7 +168,7 @@ std_handler_input (ASSUAN_CONTEXT ctx, char *line)  {    int rc, fd; -  rc = parse_cmd_input_output (ctx, line, &fd); +  rc = assuan_command_parse_fd (ctx, line, &fd);    if (rc)      return rc;    ctx->input_fd = fd; @@ -191,7 +183,7 @@ std_handler_output (ASSUAN_CONTEXT ctx, char *line)  {    int rc, fd; -  rc = parse_cmd_input_output (ctx, line, &fd); +  rc = assuan_command_parse_fd (ctx, line, &fd);    if (rc)      return rc;    ctx->output_fd = fd; @@ -205,25 +197,24 @@ std_handler_output (ASSUAN_CONTEXT ctx, char *line)  /* This is a table with the standard commands and handler for them. -   The table is used to initialize a new context and assuciate strings -   and handlers with cmd_ids */ +   The table is used to initialize a new context and associate strings +   with default handlers */  static struct {    const char *name; -  int cmd_id;    int (*handler)(ASSUAN_CONTEXT, char *line);    int always; /* always initialize this command */  } std_cmd_table[] = { -  { "NOP",    ASSUAN_CMD_NOP,    std_handler_nop, 1 }, -  { "CANCEL", ASSUAN_CMD_CANCEL, std_handler_cancel, 1 }, -  { "OPTION", ASSUAN_CMD_OPTION, std_handler_option, 1 }, -  { "BYE",    ASSUAN_CMD_BYE,    std_handler_bye, 1 }, -  { "AUTH",   ASSUAN_CMD_AUTH,   std_handler_auth, 1 }, -  { "RESET",  ASSUAN_CMD_RESET,  std_handler_reset, 1 }, -  { "END",    ASSUAN_CMD_END,    std_handler_end, 1 }, - -  { "INPUT",  ASSUAN_CMD_INPUT,  std_handler_input }, -  { "OUTPUT", ASSUAN_CMD_OUTPUT, std_handler_output }, -  { "OPTION", ASSUAN_CMD_OPTION, std_handler_option, 1 }, +  { "NOP",    std_handler_nop, 1 }, +  { "CANCEL", std_handler_cancel, 1 }, +  { "OPTION", std_handler_option, 1 }, +  { "BYE",    std_handler_bye, 1 }, +  { "AUTH",   std_handler_auth, 1 }, +  { "RESET",  std_handler_reset, 1 }, +  { "END",    std_handler_end, 1 }, +               +  { "INPUT",  std_handler_input }, +  { "OUTPUT", std_handler_output }, +  { "OPTION", std_handler_option, 1 },    { NULL }  }; @@ -231,54 +222,46 @@ static struct {  /**   * assuan_register_command:   * @ctx: the server context - * @cmd_id: An ID value for the command   * @cmd_name: A string with the command name - * @handler: The handler function to be called - *  - * Register a handler to be used for a given command. + * @handler: The handler function to be called or NULL to use a default + *           handler.   *  - * The @cmd_name must be %NULL or an empty string for all @cmd_ids - * below %ASSUAN_CMD_USER because predefined values are used. + * Register a handler to be used for a given command.  Note that + * several default handlers are already regsitered with a new context. + * This function however allows to override them.   *  - * Return value:  + * Return value: 0 on success or an error code   **/  int  assuan_register_command (ASSUAN_CONTEXT ctx, -                         int cmd_id, const char *cmd_name, +                         const char *cmd_name,                           int (*handler)(ASSUAN_CONTEXT, char *))  {    int i; +  const char *s;    if (cmd_name && !*cmd_name)      cmd_name = NULL; -  if (cmd_id < ASSUAN_CMD_USER) -    {  -      if (cmd_name) -        return ASSUAN_Invalid_Value; /* must be NULL for these values*/ +  if (!cmd_name) +    return ASSUAN_Invalid_Value; -      for (i=0; std_cmd_table[i].name; i++) -        { -          if (std_cmd_table[i].cmd_id == cmd_id) -            { -              cmd_name = std_cmd_table[i].name; -              if (!handler) -                handler = std_cmd_table[i].handler; -              break; -            } +  if (!handler) +    { /* find a default handler. */ +      for (i=0; (s=std_cmd_table[i].name) && strcmp (cmd_name, s); i++) +        ; +      if (!s) +        { /* Try again but case insensitive. */ +          for (i=0; (s=std_cmd_table[i].name) +                    && my_strcasecmp (cmd_name, s); i++) +            ;          } -      if (!std_cmd_table[i].name) -        return ASSUAN_Invalid_Value; /* not a pre-registered one */ +      if (s) +        handler = std_cmd_table[i].handler; +      if (!handler) +        handler = dummy_handler; /* Last resort is the dummy handler. */      } -  if (!handler) -    handler = dummy_handler; - -  if (!cmd_name) -    return ASSUAN_Invalid_Value; - -/*    fprintf (stderr, "DBG-assuan: registering %d as `%s'\n", cmd_id, cmd_name); */ -    if (!ctx->cmdtbl)      {        ctx->cmdtbl_size = 50; @@ -299,7 +282,6 @@ assuan_register_command (ASSUAN_CONTEXT ctx,      }    ctx->cmdtbl[ctx->cmdtbl_used].name = cmd_name; -  ctx->cmdtbl[ctx->cmdtbl_used].cmd_id = cmd_id;    ctx->cmdtbl[ctx->cmdtbl_used].handler = handler;    ctx->cmdtbl_used++;    return 0; @@ -374,8 +356,7 @@ _assuan_register_std_commands (ASSUAN_CONTEXT ctx)      {        if (std_cmd_table[i].always)          { -          rc = assuan_register_command (ctx, std_cmd_table[i].cmd_id, -                                        NULL, NULL); +          rc = assuan_register_command (ctx, std_cmd_table[i].name, NULL);            if (rc)              return rc;          } @@ -624,17 +605,13 @@ assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what,  FILE *  assuan_get_data_fp (ASSUAN_CONTEXT ctx)  { -  cookie_io_functions_t cookie_fnc; -    if (ctx->outbound.data.fp)      return ctx->outbound.data.fp; -  cookie_fnc.read = NULL;  -  cookie_fnc.write = _assuan_cookie_write_data; -  cookie_fnc.seek = NULL; -  cookie_fnc.close = _assuan_cookie_write_flush; -  ctx->outbound.data.fp = fopencookie (ctx, "wb", cookie_fnc); +  ctx->outbound.data.fp = funopen (ctx, 0, +				   _assuan_cookie_write_data, +				   0, _assuan_cookie_write_flush);    ctx->outbound.data.error = 0;    return ctx->outbound.data.fp;  } | 
