From: Alan T. DeKok Date: Wed, 11 Jul 2018 20:26:41 +0000 (-0400) Subject: add preliminary support for partial commands X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d7b40f960c0f03cb370a9cc169ca3b8eee21dcd6;p=thirdparty%2Ffreeradius-server.git add preliminary support for partial commands --- diff --git a/src/main/radmin.c b/src/main/radmin.c index 0db63216588..0f655031f3d 100644 --- a/src/main/radmin.c +++ b/src/main/radmin.c @@ -658,7 +658,10 @@ int fr_radmin_run(fr_cmd_info_t *info, FILE *fp, FILE *fp_err, char *str, bool r int argc, rcode; argc = fr_command_str_to_argv(radmin_cmd, info, str); - if (argc < 0) return -1; + if (argc < 0) { + fprintf(fp_err, "%s\n", fr_strerror()); + return -1; + } if (!info->runnable) { return 0; diff --git a/src/modules/proto_control/conduit.h b/src/modules/proto_control/conduit.h index bc52a00bc51..2bee03b27f2 100644 --- a/src/modules/proto_control/conduit.h +++ b/src/modules/proto_control/conduit.h @@ -50,6 +50,7 @@ typedef enum fr_conduit_origin_t { typedef enum fr_conduit_result_t { FR_CONDUIT_FAIL = 0, + FR_CONDUIT_PARTIAL, FR_CONDUIT_SUCCESS } fr_conduit_result_t; diff --git a/src/modules/proto_control/proto_control_unix.c b/src/modules/proto_control/proto_control_unix.c index feeb8509e16..d43f4365a21 100644 --- a/src/modules/proto_control/proto_control_unix.c +++ b/src/modules/proto_control/proto_control_unix.c @@ -122,8 +122,9 @@ static ssize_t mod_read_command(void *instance, UNUSED void **packet_ctx, UNUSED { proto_control_unix_t *inst = talloc_get_type_abort(instance, proto_control_unix_t); fr_conduit_hdr_t *hdr = (fr_conduit_hdr_t *) buffer; - uint32_t status = FR_CONDUIT_FAIL; + uint32_t status; uint8_t *cmd = buffer + sizeof(*hdr); + int rcode; char string[1024]; hdr->length = ntohl(hdr->length); @@ -136,12 +137,23 @@ static ssize_t mod_read_command(void *instance, UNUSED void **packet_ctx, UNUSED memcpy(string, cmd, hdr->length); string[hdr->length] = '\0'; - if (fr_radmin_run(inst->info, inst->stdout, inst->stderr, string, inst->read_only) == 1) { + rcode = fr_radmin_run(inst->info, inst->stdout, inst->stderr, string, inst->read_only); + if (rcode < 0) { + status = FR_CONDUIT_FAIL; + } else if (rcode == 0) { + /* + * The other end should keep track of it's + * context, and send us full lines. + */ + (void) fr_command_clear(0, inst->info); + status = FR_CONDUIT_PARTIAL; + } else { status = FR_CONDUIT_SUCCESS; } fr_conduit_write(inst->sockfd, FR_CONDUIT_STDOUT, "\n", 1); + status = htonl(status); (void) fr_conduit_write(inst->sockfd, FR_CONDUIT_CMD_STATUS, &status, sizeof(status)); return 0; diff --git a/src/modules/proto_control/radmin.c b/src/modules/proto_control/radmin.c index a4dce1fa8a6..4c1e3013210 100644 --- a/src/modules/proto_control/radmin.c +++ b/src/modules/proto_control/radmin.c @@ -856,7 +856,10 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } else if (len == FR_CONDUIT_SUCCESS) { - break; + continue; + + } else if (len == FR_CONDUIT_PARTIAL) { + continue; } else if (len == FR_CONDUIT_FAIL) { exit_status = EXIT_FAILURE;