From 18ff159c38b7d919bafbdcc46d03c3f83c17476f Mon Sep 17 00:00:00 2001 From: oetiker Date: Fri, 10 Apr 2009 08:52:34 +0000 Subject: [PATCH] This patch consolidates several aspects of the command handling in rrdcached: * all commands, help, and context information is reduced to a single data structure. * all checks for command validity (context and permission) are handled in the main dispatch routine This removes duplicate help/syntax text, and long if..elseif..else chains. It facilitates the addition of new commands. -- kevin git-svn-id: svn://svn.oetiker.ch/rrdtool/trunk/program@1788 a5681a0c-68f1-0310-ab6d-d61299d08faa --- src/rrd_daemon.c | 512 +++++++++++++++++++++++++---------------------- 1 file changed, 278 insertions(+), 234 deletions(-) diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c index 1e53175..dcca55d 100644 --- a/src/rrd_daemon.c +++ b/src/rrd_daemon.c @@ -144,6 +144,31 @@ struct listen_socket_s }; typedef struct listen_socket_s listen_socket_t; +struct command; +/* note: guard against "unused" warnings in the handlers */ +#define DISPATCH_PROTO listen_socket_t *sock __attribute__((unused)),\ + time_t now __attribute__((unused)),\ + char *buffer __attribute__((unused)),\ + size_t buffer_size __attribute__((unused)) + +#define HANDLER_PROTO struct command *cmd __attribute__((unused)),\ + DISPATCH_PROTO + +struct command { + char *cmd; + int (*handler)(HANDLER_PROTO); + socket_privilege min_priv; + + char context; /* where we expect to see it */ +#define CMD_CONTEXT_CLIENT (1<<0) +#define CMD_CONTEXT_BATCH (1<<1) +#define CMD_CONTEXT_JOURNAL (1<<2) +#define CMD_CONTEXT_ANY (0x7f) + + char *syntax; + char *help; +}; + struct cache_item_s; typedef struct cache_item_s cache_item_t; struct cache_item_s @@ -239,6 +264,9 @@ static int journal_write(char *cmd, char *args); static void journal_done(void); static void journal_rotate(void); +/* prototypes for forward refernces */ +static int handle_request_help (HANDLER_PROTO); + /* * Functions */ @@ -1067,166 +1095,17 @@ static int flush_file (const char *filename) /* {{{ */ return (0); } /* }}} int flush_file */ -static int handle_request_help (listen_socket_t *sock, /* {{{ */ - char *buffer, size_t buffer_size) +static int syntax_error(listen_socket_t *sock, struct command *cmd) /* {{{ */ { - int status; - char **help_text; - char *command; - - char *help_help[2] = - { - "Command overview\n" - , - "HELP []\n" - "FLUSH \n" - "FLUSHALL\n" - "PENDING \n" - "FORGET \n" - "QUEUE\n" - "UPDATE [ ...]\n" - "BATCH\n" - "STATS\n" - "QUIT\n" - }; + char *err = "Syntax error.\n"; - char *help_flush[2] = - { - "Help for FLUSH\n" - , - "Usage: FLUSH \n" - "\n" - "Adds the given filename to the head of the update queue and returns\n" - "after it has been dequeued.\n" - }; + if (cmd && cmd->syntax) + err = cmd->syntax; - char *help_flushall[2] = - { - "Help for FLUSHALL\n" - , - "Usage: FLUSHALL\n" - "\n" - "Triggers writing of all pending updates. Returns immediately.\n" - }; + return send_response(sock, RESP_ERR, "Usage: %s", err); +} /* }}} static int syntax_error() */ - char *help_pending[2] = - { - "Help for PENDING\n" - , - "Usage: PENDING \n" - "\n" - "Shows any 'pending' updates for a file, in order.\n" - "The updates shown have not yet been written to the underlying RRD file.\n" - }; - - char *help_forget[2] = - { - "Help for FORGET\n" - , - "Usage: FORGET \n" - "\n" - "Removes the file completely from the cache.\n" - "Any pending updates for the file will be lost.\n" - }; - - char *help_queue[2] = - { - "Help for QUEUE\n" - , - "Shows all files in the output queue.\n" - "The output is zero or more lines in the following format:\n" - "(where is the number of values to be written)\n" - "\n" - " \n" - "\n" - }; - - char *help_update[2] = - { - "Help for UPDATE\n" - , - "Usage: UPDATE [ ...]\n" - "\n" - "Adds the given file to the internal cache if it is not yet known and\n" - "appends the given value(s) to the entry. See the rrdcached(1) manpage\n" - "for details.\n" - "\n" - "Each has the following form:\n" - " =