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