From de569025d2a282444293d56d4a1209d70f8b7e33 Mon Sep 17 00:00:00 2001 From: Gerrit Renker Date: Sun, 13 Jun 2010 11:30:47 +0200 Subject: [PATCH] sender: add a hook to resolve target names This adds a function pointer to interpret and resolve a given URL string in a target-specific manner, filling in the target's defaults if omitted. The hook is used for the add/delete commands, currently implemented for UDP. --- command.c | 13 +++++++++++-- dccp_send.c | 1 + http_send.c | 1 + send.h | 9 +++++++++ udp_send.c | 23 +++++++++++++++++++++++ 5 files changed, 45 insertions(+), 2 deletions(-) diff --git a/command.c b/command.c index 42fa3e75..bcbbc340 100644 --- a/command.c +++ b/command.c @@ -191,10 +191,10 @@ static int check_sender_args(int argc, char * const * argv, struct sender_comman int com_sender(struct rc4_context *rc4c, int argc, char * const * argv) { int i, ret; + char *msg = NULL; struct sender_command_data scd; if (argc < 2) { - char *msg = NULL; for (i = 0; senders[i].name; i++) { char *tmp = make_message("%s%s\n", msg? msg : "", senders[i].name); @@ -207,7 +207,6 @@ int com_sender(struct rc4_context *rc4c, int argc, char * const * argv) } ret = check_sender_args(argc, argv, &scd); if (ret < 0) { - char *msg; if (scd.sender_num < 0) return ret; msg = senders[scd.sender_num].help(); @@ -215,6 +214,16 @@ int com_sender(struct rc4_context *rc4c, int argc, char * const * argv) free(msg); return ret; } + + switch (scd.cmd_num) { + case SENDER_ADD: + case SENDER_DELETE: + assert(senders[scd.sender_num].resolve_target); + ret = senders[scd.sender_num].resolve_target(argv[3], &scd); + if (ret < 0) + return ret; + } + for (i = 0; i < 10; i++) { mutex_lock(mmd_mutex); if (mmd->sender_cmd_data.cmd_num >= 0) { diff --git a/dccp_send.c b/dccp_send.c index 6cfdfbbe..41aaf234 100644 --- a/dccp_send.c +++ b/dccp_send.c @@ -219,6 +219,7 @@ void dccp_send_init(struct sender *s) s->pre_select = dccp_pre_select; s->post_select = dccp_post_select; s->shutdown_clients = dccp_shutdown_clients; + s->resolve_target = NULL; s->help = generic_sender_help; s->client_cmds[SENDER_ON] = dccp_com_on; s->client_cmds[SENDER_OFF] = dccp_com_off; diff --git a/http_send.c b/http_send.c index e8b22cf9..e376c464 100644 --- a/http_send.c +++ b/http_send.c @@ -251,6 +251,7 @@ void http_send_init(struct sender *s) s->pre_select = http_pre_select; s->post_select = http_post_select; s->shutdown_clients = http_shutdown_clients; + s->resolve_target = NULL; s->help = generic_sender_help; s->client_cmds[SENDER_ON] = http_com_on; s->client_cmds[SENDER_OFF] = http_com_off; diff --git a/send.h b/send.h index df0cd1cb..5f874521 100644 --- a/send.h +++ b/send.h @@ -87,6 +87,15 @@ struct sender { * pointer means this command is not implemented by this sender. */ int (*client_cmds[NUM_SENDER_CMDS])(struct sender_command_data*); + /** + * Resolve target-specific URL string + * + * This method must be defined if the sender supports the add/delete + * subcommands. It interprets a string specifying a target URL in a + * sender-specific fashion (e.g. embedded FEC string). It can also + * fill in sender-specific defaults if necessary. + */ + int (*resolve_target)(const char *, struct sender_command_data *); }; /** Describes one client, connected to a paraslash sender. */ diff --git a/udp_send.c b/udp_send.c index 24ebf584..adac6a8d 100644 --- a/udp_send.c +++ b/udp_send.c @@ -187,6 +187,28 @@ static void udp_shutdown_targets(void) } } +static int udp_resolve_target(const char *url, struct sender_command_data *scd) +{ + const char *result; + int ret, port; + + ret = parse_fec_url(url, scd); + if (ret) + return ret; + port = scd->port > 0 ? scd->port : conf.udp_default_port_arg; + + ret = para_connect_simple(IPPROTO_UDP, scd->host, port); + if (ret < 0) + return ret; + + result = remote_name(ret); + close(ret); + + if (!parse_url(result, scd->host, sizeof(scd->host), &scd->port)) + return -E_ADDRESS_LOOKUP; + return 1; +} + static int udp_com_on(__a_unused struct sender_command_data *scd) { sender_status = SENDER_ON; @@ -427,6 +449,7 @@ void udp_send_init(struct sender *s) s->pre_select = NULL; s->post_select = NULL; s->shutdown_clients = udp_shutdown_targets; + s->resolve_target = udp_resolve_target; s->client_cmds[SENDER_ON] = udp_com_on; s->client_cmds[SENDER_OFF] = udp_com_off; s->client_cmds[SENDER_DENY] = NULL; -- 2.39.2