|
|
c896fb |
diff --git a/multipathd/cli.c b/multipathd/cli.c
|
|
|
c896fb |
index acc4249..8d26956 100644
|
|
|
c896fb |
--- a/multipathd/cli.c
|
|
|
c896fb |
+++ b/multipathd/cli.c
|
|
|
c896fb |
@@ -320,52 +320,90 @@ alloc_handlers (void)
|
|
|
c896fb |
}
|
|
|
c896fb |
|
|
|
c896fb |
static int
|
|
|
c896fb |
-genhelp_sprint_aliases (char * reply, vector keys, struct key * refkw)
|
|
|
c896fb |
+genhelp_sprint_aliases (char * reply, int maxlen, vector keys,
|
|
|
c896fb |
+ struct key * refkw)
|
|
|
c896fb |
{
|
|
|
c896fb |
- int i, fwd = 0;
|
|
|
c896fb |
+ int i, len = 0;
|
|
|
c896fb |
struct key * kw;
|
|
|
c896fb |
|
|
|
c896fb |
- vector_foreach_slot (keys, kw, i)
|
|
|
c896fb |
- if (kw->code == refkw->code && kw != refkw)
|
|
|
c896fb |
- fwd += sprintf(reply, "|%s", kw->str);
|
|
|
c896fb |
+ vector_foreach_slot (keys, kw, i) {
|
|
|
c896fb |
+ if (kw->code == refkw->code && kw != refkw) {
|
|
|
c896fb |
+ len += snprintf(reply + len, maxlen - len,
|
|
|
c896fb |
+ "|%s", kw->str);
|
|
|
c896fb |
+ if (len >= maxlen)
|
|
|
c896fb |
+ return len;
|
|
|
c896fb |
+ }
|
|
|
c896fb |
+ }
|
|
|
c896fb |
|
|
|
c896fb |
- return fwd;
|
|
|
c896fb |
+ return len;
|
|
|
c896fb |
}
|
|
|
c896fb |
|
|
|
c896fb |
-static char *
|
|
|
c896fb |
-genhelp_handler (void)
|
|
|
c896fb |
-{
|
|
|
c896fb |
+static int
|
|
|
c896fb |
+do_genhelp(char *reply, int maxlen) {
|
|
|
c896fb |
+ int len = 0;
|
|
|
c896fb |
int i, j;
|
|
|
c896fb |
unsigned long fp;
|
|
|
c896fb |
struct handler * h;
|
|
|
c896fb |
struct key * kw;
|
|
|
c896fb |
- char * reply;
|
|
|
c896fb |
- char * p;
|
|
|
c896fb |
-
|
|
|
c896fb |
- reply = MALLOC(INITIAL_REPLY_LEN);
|
|
|
c896fb |
|
|
|
c896fb |
- if (!reply)
|
|
|
c896fb |
- return NULL;
|
|
|
c896fb |
-
|
|
|
c896fb |
- p = reply;
|
|
|
c896fb |
- p += sprintf(p, VERSION_STRING);
|
|
|
c896fb |
- p += sprintf(p, "CLI commands reference:\n");
|
|
|
c896fb |
+ len += snprintf(reply + len, maxlen - len, VERSION_STRING);
|
|
|
c896fb |
+ if (len >= maxlen)
|
|
|
c896fb |
+ goto out;
|
|
|
c896fb |
+ len += snprintf(reply + len, maxlen - len, "CLI commands reference:\n");
|
|
|
c896fb |
+ if (len >= maxlen)
|
|
|
c896fb |
+ goto out;
|
|
|
c896fb |
|
|
|
c896fb |
vector_foreach_slot (handlers, h, i) {
|
|
|
c896fb |
fp = h->fingerprint;
|
|
|
c896fb |
vector_foreach_slot (keys, kw, j) {
|
|
|
c896fb |
if ((kw->code & fp)) {
|
|
|
c896fb |
fp -= kw->code;
|
|
|
c896fb |
- p += sprintf(p, " %s", kw->str);
|
|
|
c896fb |
- p += genhelp_sprint_aliases(p, keys, kw);
|
|
|
c896fb |
-
|
|
|
c896fb |
- if (kw->has_param)
|
|
|
c896fb |
- p += sprintf(p, " $%s", kw->str);
|
|
|
c896fb |
+ len += snprintf(reply + len , maxlen - len,
|
|
|
c896fb |
+ " %s", kw->str);
|
|
|
c896fb |
+ if (len >= maxlen)
|
|
|
c896fb |
+ goto out;
|
|
|
c896fb |
+ len += genhelp_sprint_aliases(reply + len,
|
|
|
c896fb |
+ maxlen - len,
|
|
|
c896fb |
+ keys, kw);
|
|
|
c896fb |
+ if (len >= maxlen)
|
|
|
c896fb |
+ goto out;
|
|
|
c896fb |
+
|
|
|
c896fb |
+ if (kw->has_param) {
|
|
|
c896fb |
+ len += snprintf(reply + len,
|
|
|
c896fb |
+ maxlen - len,
|
|
|
c896fb |
+ " $%s", kw->str);
|
|
|
c896fb |
+ if (len >= maxlen)
|
|
|
c896fb |
+ goto out;
|
|
|
c896fb |
+ }
|
|
|
c896fb |
}
|
|
|
c896fb |
}
|
|
|
c896fb |
- p += sprintf(p, "\n");
|
|
|
c896fb |
+ len += snprintf(reply + len, maxlen - len, "\n");
|
|
|
c896fb |
+ if (len >= maxlen)
|
|
|
c896fb |
+ goto out;
|
|
|
c896fb |
}
|
|
|
c896fb |
+out:
|
|
|
c896fb |
+ return len;
|
|
|
c896fb |
+}
|
|
|
c896fb |
+
|
|
|
c896fb |
|
|
|
c896fb |
+static char *
|
|
|
c896fb |
+genhelp_handler (void)
|
|
|
c896fb |
+{
|
|
|
c896fb |
+ char * reply;
|
|
|
c896fb |
+ char * p = NULL;
|
|
|
c896fb |
+ int maxlen = INITIAL_REPLY_LEN;
|
|
|
c896fb |
+ int again = 1;
|
|
|
c896fb |
+
|
|
|
c896fb |
+ reply = MALLOC(maxlen);
|
|
|
c896fb |
+
|
|
|
c896fb |
+ while (again) {
|
|
|
c896fb |
+ if (!reply)
|
|
|
c896fb |
+ return NULL;
|
|
|
c896fb |
+ p = reply;
|
|
|
c896fb |
+ p += do_genhelp(reply, maxlen);
|
|
|
c896fb |
+ again = ((p - reply) >= maxlen);
|
|
|
c896fb |
+ REALLOC_REPLY(reply, again, maxlen);
|
|
|
c896fb |
+ }
|
|
|
c896fb |
return reply;
|
|
|
c896fb |
}
|
|
|
c896fb |
|
|
|
c896fb |
diff --git a/multipathd/cli.h b/multipathd/cli.h
|
|
|
c896fb |
index 09fdc68..2e0e1da 100644
|
|
|
c896fb |
--- a/multipathd/cli.h
|
|
|
c896fb |
+++ b/multipathd/cli.h
|
|
|
c896fb |
@@ -71,7 +71,21 @@ enum {
|
|
|
c896fb |
#define SETPRSTATUS (1UL << __SETPRSTATUS)
|
|
|
c896fb |
#define UNSETPRSTATUS (1UL << __UNSETPRSTATUS)
|
|
|
c896fb |
|
|
|
c896fb |
-#define INITIAL_REPLY_LEN 1100
|
|
|
c896fb |
+#define INITIAL_REPLY_LEN 1200
|
|
|
c896fb |
+
|
|
|
c896fb |
+#define REALLOC_REPLY(r, a, m) \
|
|
|
c896fb |
+ do { \
|
|
|
c896fb |
+ if ((a)) { \
|
|
|
c896fb |
+ char *tmp = (r); \
|
|
|
c896fb |
+ (r) = REALLOC((r), (m) * 2); \
|
|
|
c896fb |
+ if ((r)) { \
|
|
|
c896fb |
+ memset((r) + (m), 0, (m)); \
|
|
|
c896fb |
+ (m) *= 2; \
|
|
|
c896fb |
+ } \
|
|
|
c896fb |
+ else \
|
|
|
c896fb |
+ free(tmp); \
|
|
|
c896fb |
+ } \
|
|
|
c896fb |
+ } while (0)
|
|
|
c896fb |
|
|
|
c896fb |
struct key {
|
|
|
c896fb |
char * str;
|
|
|
c896fb |
diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c
|
|
|
c896fb |
index e47899a..23683f2 100644
|
|
|
c896fb |
--- a/multipathd/cli_handlers.c
|
|
|
c896fb |
+++ b/multipathd/cli_handlers.c
|
|
|
c896fb |
@@ -23,20 +23,6 @@
|
|
|
c896fb |
#include "cli.h"
|
|
|
c896fb |
#include "uevent.h"
|
|
|
c896fb |
|
|
|
c896fb |
-#define REALLOC_REPLY(r, a, m) \
|
|
|
c896fb |
- do { \
|
|
|
c896fb |
- if ((a)) { \
|
|
|
c896fb |
- char *tmp = (r); \
|
|
|
c896fb |
- (r) = REALLOC((r), (m) * 2); \
|
|
|
c896fb |
- if ((r)) { \
|
|
|
c896fb |
- memset((r) + (m), 0, (m)); \
|
|
|
c896fb |
- (m) *= 2; \
|
|
|
c896fb |
- } \
|
|
|
c896fb |
- else \
|
|
|
c896fb |
- free(tmp); \
|
|
|
c896fb |
- } \
|
|
|
c896fb |
- } while (0)
|
|
|
c896fb |
-
|
|
|
c896fb |
int
|
|
|
c896fb |
show_paths (char ** r, int * len, struct vectors * vecs, char * style)
|
|
|
c896fb |
{
|