diff --git a/client/client_shared.c b/client/client_shared.c index 212b7301..2ec57fb9 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -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; } diff --git a/client/pub_client.c b/client/pub_client.c index c8ca981a..bd550bfb 100644 --- a/client/pub_client.c +++ b/client/pub_client.c @@ -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"); diff --git a/client/sub_client.c b/client/sub_client.c index a1a3bf04..523936d5 100644 --- a/client/sub_client.c +++ b/client/sub_client.c @@ -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"); diff --git a/man/mosquitto_pub.1.xml b/man/mosquitto_pub.1.xml index 567111d5..f2896951 100644 --- a/man/mosquitto_pub.1.xml +++ b/man/mosquitto_pub.1.xml @@ -25,6 +25,7 @@ keepalive time port number message QoS + URL @@ -254,7 +255,7 @@ - Connect to the port specified instead of the default 1883. + Connect to the port specified instead of the default 1883 for plain MQTT and 8883 for MQTT over TLS. @@ -368,6 +369,15 @@ broker. + + + + + 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 + + diff --git a/man/mosquitto_sub.1.xml b/man/mosquitto_sub.1.xml index 7b1e5d2e..bb068f09 100644 --- a/man/mosquitto_sub.1.xml +++ b/man/mosquitto_sub.1.xml @@ -25,6 +25,7 @@ client_id client id prefix keepalive time + URL port number message QoS @@ -271,7 +272,7 @@ - Connect to the port specified instead of the default 1883. + Connect to the port specified instead of the default 1883 for plain MQTT and 8883 for MQTT over TLS. @@ -420,6 +421,15 @@ broker. + + + + + 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 + +