summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2002-01-20 16:49:34 +0000
committerWerner Koch <wk@gnupg.org>2002-01-20 16:49:34 +0000
commitdbcd18310d6147658d669bdaa5580f06833306a6 (patch)
tree64bba43f93a85a6f548f023f9910f9b961cbaf4d
parentc5698a48387a9b7fb252222eb40c42a7c9f76310 (diff)
downloadlibassuan-dbcd18310d6147658d669bdaa5580f06833306a6.tar.gz
* assuan.h: Added Invalid Option error code.
* assuan-handler.c (std_handler_option): New. (std_cmd_tbl): Add OPTION as standard command. (assuan_register_option_handler): New. (dispatch_command): Use case insensitive matching as a fallback. (my_strcasecmp): New.
-rw-r--r--src/ChangeLog10
-rw-r--r--src/assuan-defs.h1
-rw-r--r--src/assuan-handler.c89
-rw-r--r--src/assuan.h7
4 files changed, 105 insertions, 2 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 3c3fdcd..d12acee 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,13 @@
+2002-01-20 Werner Koch <wk@gnupg.org>
+
+ * assuan.h: Added Invalid Option error code.
+
+ * assuan-handler.c (std_handler_option): New.
+ (std_cmd_tbl): Add OPTION as standard command.
+ (assuan_register_option_handler): New.
+ (dispatch_command): Use case insensitive matching as a fallback.
+ (my_strcasecmp): New.
+
2002-01-19 Werner Koch <wk@gnupg.org>
* assuan-buffer.c (_assuan_read_line): Add output logging.
diff --git a/src/assuan-defs.h b/src/assuan-defs.h
index d19e6b9..c14b409 100644
--- a/src/assuan-defs.h
+++ b/src/assuan-defs.h
@@ -87,6 +87,7 @@ struct assuan_context_s {
void (*bye_notify_fnc)(ASSUAN_CONTEXT);
void (*reset_notify_fnc)(ASSUAN_CONTEXT);
void (*cancel_notify_fnc)(ASSUAN_CONTEXT);
+ int (*option_handler_fnc)(ASSUAN_CONTEXT,const char*, const char*);
void (*input_notify_fnc)(ASSUAN_CONTEXT, const char *);
void (*output_notify_fnc)(ASSUAN_CONTEXT, const char *);
diff --git a/src/assuan-handler.c b/src/assuan-handler.c
index db9749e..1c8aded 100644
--- a/src/assuan-handler.c
+++ b/src/assuan-handler.c
@@ -25,6 +25,7 @@
#include "assuan-defs.h"
+#define spacep(p) (*(p) == ' ' || *(p) == '\t')
#define digitp(a) ((a) >= '0' && (a) <= '9')
@@ -48,6 +49,53 @@ std_handler_cancel (ASSUAN_CONTEXT ctx, char *line)
ctx->cancel_notify_fnc (ctx);
return set_error (ctx, Not_Implemented, NULL);
}
+
+static int
+std_handler_option (ASSUAN_CONTEXT ctx, char *line)
+{
+ char *key, *value, *p;
+
+ for (key=line; spacep (key); key++)
+ ;
+ if (!*key)
+ return set_error (ctx, Syntax_Error, "argument required");
+ if (*key == '=')
+ return set_error (ctx, Syntax_Error, "no option name given");
+ for (value=key; *value && !spacep (value) && *value != '='; value++)
+ ;
+ if (*value)
+ {
+ if (spacep (value))
+ *value++ = 0; /* terminate key */
+ for (; spacep (value); value++)
+ ;
+ if (*value == '=')
+ {
+ *value++ = 0; /* terminate key */
+ for (; spacep (value); value++)
+ ;
+ if (!*value)
+ return set_error (ctx, Syntax_Error, "option argument expected");
+ }
+ if (*value)
+ {
+ for (p = value + strlen(value) - 1; p > value && spacep (p); p--)
+ ;
+ if (p > value)
+ *++p = 0; /* strip trailing spaces */
+ }
+ }
+
+ if (*key == '-' && key[1] == '-' && key[2])
+ key += 2; /* the double dashes are optional */
+ if (*key == '-')
+ return set_error (ctx, Syntax_Error,
+ "option should not begin with one dash");
+
+ if (ctx->option_handler_fnc)
+ return ctx->option_handler_fnc (ctx, key, value);
+ return 0;
+}
static int
std_handler_bye (ASSUAN_CONTEXT ctx, char *line)
@@ -147,6 +195,7 @@ static struct {
} 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 },
@@ -154,6 +203,7 @@ static struct {
{ "INPUT", ASSUAN_CMD_INPUT, std_handler_input },
{ "OUTPUT", ASSUAN_CMD_OUTPUT, std_handler_output },
+ { "OPTION", ASSUAN_CMD_OPTION, std_handler_option, 1 },
{ NULL }
};
@@ -263,6 +313,17 @@ assuan_register_cancel_notify (ASSUAN_CONTEXT ctx, void (*fnc)(ASSUAN_CONTEXT))
}
int
+assuan_register_option_handler (ASSUAN_CONTEXT ctx,
+ int (*fnc)(ASSUAN_CONTEXT,
+ const char*, const char*))
+{
+ if (!ctx)
+ return ASSUAN_Invalid_Value;
+ ctx->option_handler_fnc = fnc;
+ return 0;
+}
+
+int
assuan_register_input_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT, const char *))
{
@@ -312,6 +373,20 @@ handle_data_line (ASSUAN_CONTEXT ctx, char *line, int linelen)
return set_error (ctx, Not_Implemented, NULL);
}
+/* like ascii_strcasecmp but assume that B is already uppercase */
+static int
+my_strcasecmp (const char *a, const char *b)
+{
+ if (a == b)
+ return 0;
+
+ for (; *a && *b; a++, b++)
+ {
+ if (((*a >= 'a' && *a <= 'z')? (*a&~0x20):*a) != *b)
+ break;
+ }
+ return *a == *b? 0 : (((*a >= 'a' && *a <= 'z')? (*a&~0x20):*a) - *b);
+}
/* Parse the line, break out the command, find it in the command
table, remove leading and white spaces from the arguments, all the
@@ -339,8 +414,18 @@ dispatch_command (ASSUAN_CONTEXT ctx, char *line, int linelen)
shift = p - line;
for (i=0; (s=ctx->cmdtbl[i].name); i++)
- if (!strcmp (line, s))
- break;
+ {
+ if (!strcmp (line, s))
+ break;
+ }
+ if (!s)
+ { /* and try case insensitive */
+ for (i=0; (s=ctx->cmdtbl[i].name); i++)
+ {
+ if (!my_strcasecmp (line, s))
+ break;
+ }
+ }
if (!s)
return set_error (ctx, Unknown_Command, NULL);
line += shift;
diff --git a/src/assuan.h b/src/assuan.h
index 3382283..31d6fbd 100644
--- a/src/assuan.h
+++ b/src/assuan.h
@@ -72,6 +72,7 @@ typedef enum {
ASSUAN_Too_Much_Data = 119,
ASSUAN_Inquire_Unknown = 120,
ASSUAN_Inquire_Error = 121,
+ ASSUAN_Invalid_Option = 122,
ASSUAN_Bad_Certificate = 201,
ASSUAN_Bad_Certificate_Path = 202,
@@ -97,6 +98,7 @@ typedef enum {
ASSUAN_CMD_BYE,
ASSUAN_CMD_AUTH,
ASSUAN_CMD_RESET,
+ ASSUAN_CMD_OPTION,
ASSUAN_CMD_DATA,
ASSUAN_CMD_END,
ASSUAN_CMD_INPUT,
@@ -124,6 +126,11 @@ int assuan_register_input_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT, const char *));
int assuan_register_output_notify (ASSUAN_CONTEXT ctx,
void (*fnc)(ASSUAN_CONTEXT, const char *));
+
+int assuan_register_option_handler (ASSUAN_CONTEXT ctx,
+ int (*fnc)(ASSUAN_CONTEXT,
+ const char*, const char*));
+
int assuan_process (ASSUAN_CONTEXT ctx);
int assuan_process_next (ASSUAN_CONTEXT ctx);
int assuan_get_active_fds (ASSUAN_CONTEXT ctx, int what,