Add MQTT URL scheme support

Add option -L to specify user, password, hostname, port and topic at once.
The URL must provided with the -L or --url in the form:
mqtt(s)://[username[:password]@]host[:port]/topic

Change-Id: Ia626a28981a38807a254ae32c6ffb29b122b8a28
Signed-off-by: Matteo Croce <matteo@openwrt.org>
pull/139/head
Matteo Croce 10 years ago committed by Roger A. Light
parent 62fa209eeb
commit 59c80d9197

@ -240,6 +240,30 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char *
return MOSQ_ERR_SUCCESS;
}
int cfg_add_topic(struct mosq_config *cfg, int pub_or_sub, char *topic)
{
if(pub_or_sub == CLIENT_PUB){
if(mosquitto_pub_topic_check(topic) == MOSQ_ERR_INVAL){
fprintf(stderr, "Error: Invalid publish topic '%s', does it contain '+' or '#'?\n", topic);
return 1;
}
cfg->topic = strdup(topic);
} else {
if(mosquitto_sub_topic_check(topic) == MOSQ_ERR_INVAL){
fprintf(stderr, "Error: Invalid subscription topic '%s', are all '+' and '#' wildcards correct?\n", topic);
return 1;
}
cfg->topic_count++;
cfg->topics = realloc(cfg->topics, cfg->topic_count*sizeof(char *));
if(!cfg->topics){
fprintf(stderr, "Error: Out of memory.\n");
return 1;
}
cfg->topics[cfg->topic_count-1] = strdup(topic);
}
return 0;
}
/* Process a tokenised single line from a file or set of real argc/argv */
int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, char *argv[])
{
@ -525,25 +549,8 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c
fprintf(stderr, "Error: -t argument given but no topic specified.\n\n");
return 1;
}else{
if(pub_or_sub == CLIENT_PUB){
if(mosquitto_pub_topic_check(argv[i+1]) == MOSQ_ERR_INVAL){
fprintf(stderr, "Error: Invalid publish topic '%s', does it contain '+' or '#'?\n", argv[i+1]);
return 1;
}
cfg->topic = strdup(argv[i+1]);
}else{
if(mosquitto_sub_topic_check(argv[i+1]) == MOSQ_ERR_INVAL){
fprintf(stderr, "Error: Invalid subscription topic '%s', are all '+' and '#' wildcards correct?\n", argv[i+1]);
return 1;
}
cfg->topic_count++;
cfg->topics = realloc(cfg->topics, cfg->topic_count*sizeof(char *));
if(!cfg->topics){
fprintf(stderr, "Error: Out of memory.\n");
return 1;
}
cfg->topics[cfg->topic_count-1] = strdup(argv[i+1]);
}
if(cfg_add_topic(cfg, pub_or_sub, argv[i + 1]))
return 1;
i++;
}
}else if(!strcmp(argv[i], "-T") || !strcmp(argv[i], "--filter-out")){
@ -674,6 +681,50 @@ int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, c
goto unknown_option;
}
cfg->hex_output = true;
}else if(!strcmp(argv[i], "-L") || !strcmp(argv[i], "--url")){
if(i==argc-1){
fprintf(stderr, "Error: -x argument given but no URL specified.\n\n");
return 1;
} else {
char *url = argv[i+1];
char *topic;
char *tmp;
if(!strncasecmp(url, "mqtt://", 7)) {
url += 7;
} else if(!strncasecmp(url, "mqtts://", 8)) {
url += 8;
cfg->port = 8883;
} else {
fprintf(stderr, "Error: unsupported URL scheme.\n\n");
return 1;
}
topic = strchr(url, '/');
*topic++ = 0;
if(cfg_add_topic(cfg, pub_or_sub, topic))
return 1;
tmp = strchr(url, '@');
if(tmp) {
char *colon = strchr(url, ':');
*tmp++ = 0;
if(colon) {
*colon = 0;
cfg->password = colon + 1;
}
cfg->username = url;
url = tmp;
}
cfg->host = url;
tmp = strchr(url, ':');
if(tmp) {
*tmp++ = 0;
cfg->port = atoi(tmp);
}
}
i++;
}else{
goto unknown_option;
}

@ -205,7 +205,7 @@ void print_usage(void)
mosquitto_lib_version(&major, &minor, &revision);
printf("mosquitto_pub is a simple mqtt client that will publish a message on a single topic and exit.\n");
printf("mosquitto_pub version %s running on libmosquitto %d.%d.%d.\n\n", VERSION, major, minor, revision);
printf("Usage: mosquitto_pub [-h host] [-k keepalive] [-p port] [-q qos] [-r] {-f file | -l | -n | -m message} -t topic\n");
printf("Usage: mosquitto_pub [-h host] [-k keepalive] [-p port] [-q qos] [-r] {-f file | -l | -n | -m message} [-t topic]\n");
#ifdef WITH_SRV
printf(" [-A bind_address] [-S]\n");
#else
@ -214,6 +214,7 @@ void print_usage(void)
printf(" [-i id] [-I id_prefix]\n");
printf(" [-d] [--quiet]\n");
printf(" [-M max_inflight]\n");
printf(" [-L URL]\n");
printf(" [-u username [-P password]]\n");
printf(" [--will-topic [--will-payload payload] [--will-qos qos] [--will-retain]]\n");
#ifdef WITH_TLS
@ -240,7 +241,7 @@ void print_usage(void)
printf(" -m : message payload to send.\n");
printf(" -M : the maximum inflight messages for QoS 1/2..\n");
printf(" -n : send a null (zero length) message.\n");
printf(" -p : network port to connect to. Defaults to 1883.\n");
printf(" -p : network port to connect to. Defaults to 1883 for plain MQTT and 8883 for MQTT over TLS.\n");
printf(" -P : provide a password (requires MQTT 3.1 broker)\n");
printf(" -q : quality of service level to use for all messages. Defaults to 0.\n");
printf(" -r : message should be retained.\n");
@ -249,6 +250,8 @@ void print_usage(void)
printf(" -S : use SRV lookups to determine which host to connect to.\n");
#endif
printf(" -t : mqtt topic to publish to.\n");
printf(" -L : specify user, password, hostname, port and topic as a URL in the form:\n");
printf(" mqtt(s)://[username[:password]@]host[:port]/topic\n");
printf(" -u : provide a username (requires MQTT 3.1 broker)\n");
printf(" -V : specify the version of the MQTT protocol to use when connecting.\n");
printf(" Can be mqttv31 or mqttv311. Defaults to mqttv31.\n");

@ -152,7 +152,7 @@ void print_usage(void)
printf("mosquitto_sub is a simple mqtt client that will subscribe to a single topic and print all messages it receives.\n");
printf("mosquitto_sub version %s running on libmosquitto %d.%d.%d.\n\n", VERSION, major, minor, revision);
printf("Usage: mosquitto_sub [-c] [-h host] [-k keepalive] [-p port] [-q qos] [-R] {-t topic ... | -U topic ...}\n");
printf(" [-C msg_count] [--retained-only] [-T filter_out]\n");
printf(" [-L URL] [-C msg_count] [--retained-only] [-T filter_out]\n");
#ifdef WITH_SRV
printf(" [-A bind_address] [-S]\n");
#else
@ -184,7 +184,7 @@ void print_usage(void)
printf(" broker is using the clientid_prefixes option.\n");
printf(" -k : keep alive in seconds for this client. Defaults to 60.\n");
printf(" -N : do not add an end of line character when printing the payload.\n");
printf(" -p : network port to connect to. Defaults to 1883.\n");
printf(" -p : network port to connect to. Defaults to 1883 for plain MQTT and 8883 for MQTT over TLS.\n");
printf(" -P : provide a password (requires MQTT 3.1 broker)\n");
printf(" -q : quality of service level to use for the subscription. Defaults to 0.\n");
printf(" -R : do not print stale messages (those with retain set).\n");
@ -193,6 +193,8 @@ void print_usage(void)
#endif
printf(" -t : mqtt topic to subscribe to. May be repeated multiple times.\n");
printf(" -T : topic string to filter out of results. May be repeated.\n");
printf(" -L : specify user, password, hostname, port and topic as a URL in the form:\n");
printf(" mqtt(s)://[username[:password]@]host[:port]/topic\n");
printf(" -u : provide a username (requires MQTT 3.1 broker)\n");
printf(" -U : unsubscribe from a topic. May be repeated.\n");
printf(" -v : print published messages verbosely.\n");

@ -25,6 +25,7 @@
<arg><option>-k</option> <replaceable>keepalive time</replaceable></arg>
<arg><option>-p</option> <replaceable>port number</replaceable></arg>
<arg><option>-q</option> <replaceable>message QoS</replaceable></arg>
<arg><option>-L</option> <replaceable>URL</replaceable></arg>
<arg><option>--quiet</option></arg>
<arg><option>-r</option></arg>
<arg><option>-S</option></arg>
@ -254,7 +255,7 @@
<term><option>-p</option></term>
<term><option>--port</option></term>
<listitem>
<para>Connect to the port specified instead of the default 1883.</para>
<para>Connect to the port specified instead of the default 1883 for plain MQTT and 8883 for MQTT over TLS.</para>
</listitem>
</varlistentry>
<varlistentry>
@ -368,6 +369,15 @@
broker.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-L</option></term>
<term><option>--url</option></term>
<listitem>
<para>Specify specify user, password, hostname, port and topic at once as a URL.
The URL must be in the form:
mqtt(s)://[username[:password]@]host[:port]/topic</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-u</option></term>
<term><option>--username</option></term>

@ -25,6 +25,7 @@
<arg><option>-i</option> <replaceable>client_id</replaceable></arg>
<arg><option>-I</option> <replaceable>client id prefix</replaceable></arg>
<arg><option>-k</option> <replaceable>keepalive time</replaceable></arg>
<arg><option>-L</option> <replaceable>URL</replaceable></arg>
<arg><option>-p</option> <replaceable>port number</replaceable></arg>
<arg><option>-q</option> <replaceable>message QoS</replaceable></arg>
<group choice='opt'>
@ -271,7 +272,7 @@
<term><option>-p</option></term>
<term><option>--port</option></term>
<listitem>
<para>Connect to the port specified instead of the default 1883.</para>
<para>Connect to the port specified instead of the default 1883 for plain MQTT and 8883 for MQTT over TLS.</para>
</listitem>
</varlistentry>
<varlistentry>
@ -420,6 +421,15 @@
broker.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-L</option></term>
<term><option>--url</option></term>
<listitem>
<para>Specify specify user, password, hostname, port and topic at once as a URL.
The URL must be in the form:
mqtt(s)://[username[:password]@]host[:port]/topic</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>-u</option></term>
<term><option>--username</option></term>

Loading…
Cancel
Save