* @brief Client code for event-driven programs
*/
-#include <config.h>
-#include "types.h"
+#include "common.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
-#include <string.h>
-#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <netdb.h>
-#include <stdlib.h>
-#include <assert.h>
#include <inttypes.h>
#include <stddef.h>
#include <time.h>
/* Authentication ************************************************************/
+/** @brief Called with the greeting from the server */
static void authbanner_opcallback(disorder_eclient *c,
struct operation *op) {
size_t nonce_len;
(char *)0);
}
+/** @brief Called with the response to the @c user command */
static void authuser_opcallback(disorder_eclient *c,
struct operation *op) {
char *r;
/* Command support ***********************************************************/
+static const char *errorstring(disorder_eclient *c) {
+ char *s;
+
+ byte_xasprintf(&s, "%s: %s: %d", c->ident, c->line, c->rc);
+ return s;
+}
+
/* for commands with a quoted string response */
static void string_response_opcallback(disorder_eclient *c,
struct operation *op) {
+ disorder_eclient_string_response *completed
+ = (disorder_eclient_string_response *)op->completed;
+
D(("string_response_callback"));
if(c->rc / 100 == 2 || c->rc == 555) {
if(op->completed) {
if(c->rc == 555)
- ((disorder_eclient_string_response *)op->completed)(op->v, NULL);
+ completed(op->v, NULL, NULL);
else if(c->protocol >= 2) {
char **rr = split(c->line + 4, 0, SPLIT_QUOTES, 0, 0);
if(rr && *rr)
- ((disorder_eclient_string_response *)op->completed)(op->v, *rr);
+ completed(op->v, NULL, *rr);
else
- protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
+ /* TODO error message a is bit lame but generally indicates a server
+ * bug rather than anything the user can address */
+ completed(op->v, "error parsing response", NULL);
} else
- ((disorder_eclient_string_response *)op->completed)(op->v,
- c->line + 4);
+ completed(op->v, NULL, c->line + 4);
}
} else
- protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
+ completed(op->v, errorstring(c), NULL);
}
/* for commands with a simple integer response */
((disorder_eclient_integer_response *)op->completed)
(op->v, strtol(c->line + 4, 0, 10));
} else
+ /* TODO don't use protocol_error here */
protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
}
/* for commands with no response */
static void no_response_opcallback(disorder_eclient *c,
struct operation *op) {
+ disorder_eclient_no_response *completed
+ = (disorder_eclient_no_response *)op->completed;
+
D(("no_response_callback"));
- if(c->rc / 100 == 2) {
- if(op->completed)
- ((disorder_eclient_no_response *)op->completed)(op->v);
- } else
- protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
+ if(c->rc / 100 == 2)
+ completed(op->v, NULL);
+ else
+ completed(op->v, errorstring(c));
}
/* error callback for queue_unmarshall */
void *u) {
struct operation *op = u;
+ /* TODO don't use protocol_error here */
protocol_error(op->client, op, -1, "error parsing queue entry: %s", msg);
}
if(op->completed)
((disorder_eclient_queue_response *)op->completed)(op->v, qh);
} else
+ /* TODO don't use protocol_error here */
protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
}
q = 0;
break;
default:
+ /* TODO don't use protocol_error here */
protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
return;
}
if(op->completed)
((disorder_eclient_queue_response *)op->completed)(op->v, q);
} else
+ /* TODO don't use protocol_error here */
protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
}
c->vec.nvec,
c->vec.vec);
} else
+ /* TODO don't use protocol_error here */
protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
}
if(c->rc / 100 == 2) {
if(op->completed) {
if(sscanf(c->line + 4, "%d %d", &l, &r) != 2 || l < 0 || r < 0)
+ /* TODO don't use protocol_error here */
protocol_error(c, op, -1, "%s: invalid volume response: %s",
c->ident, c->line);
else
((disorder_eclient_volume_response *)op->completed)(op->v, l, r);
}
} else
+ /* TODO don't use protocol_error here */
protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
}
((disorder_eclient_list_response *)op->completed)(op->v, nvec, vec);
}
} else
+ /* TODO don't use protocol_error here */
protocol_error(c, op, c->rc, "%s: %s", c->ident, c->line);
}
/* error callback for log line parsing */
static void logline_error(const char *msg, void *u) {
disorder_eclient *c = u;
+ /* TODO don't use protocol_error here */
protocol_error(c, c->ops, -1, "error parsing log line: %s", msg);
}
* reported */
if(sscanf(vec[0], "%"SCNxMAX, &when) != 1) {
/* probably the wrong side of a format change */
+ /* TODO don't use protocol_error here */
protocol_error(c, c->ops, -1, "invalid log timestamp '%s'", vec[0]);
return;
}
/* TODO: do something with the time */
- n = TABLE_FIND(logentry_handlers, struct logentry_handler, name, vec[1]);
+ n = TABLE_FIND(logentry_handlers, name, vec[1]);
if(n < 0) return; /* probably a future command */
vec += 2;
nvec -= 2;