You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
651 lines
19 KiB
C
651 lines
19 KiB
C
/*
|
|
Copyright (c) 2009-2014 Roger Light <roger@atchoo.org>
|
|
|
|
All rights reserved. This program and the accompanying materials
|
|
are made available under the terms of the Eclipse Public License v1.0
|
|
and Eclipse Distribution License v1.0 which accompany this distribution.
|
|
|
|
The Eclipse Public License is available at
|
|
http://www.eclipse.org/legal/epl-v10.html
|
|
and the Eclipse Distribution License is available at
|
|
http://www.eclipse.org/org/documents/edl-v10.php.
|
|
|
|
Contributors:
|
|
Roger Light - initial implementation and documentation.
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#ifndef WIN32
|
|
#include <unistd.h>
|
|
#else
|
|
#include <process.h>
|
|
#include <winsock2.h>
|
|
#define snprintf sprintf_s
|
|
#endif
|
|
|
|
#include <mosquitto.h>
|
|
|
|
/* This struct is used to pass data to callbacks.
|
|
* An instance "ud" is created in main() and populated, then passed to
|
|
* mosquitto_new(). */
|
|
struct userdata {
|
|
char **topics;
|
|
int topic_count;
|
|
int topic_qos;
|
|
char **filter_outs;
|
|
int filter_out_count;
|
|
char *username;
|
|
char *password;
|
|
int verbose;
|
|
bool quiet;
|
|
bool no_retain;
|
|
bool eol;
|
|
};
|
|
|
|
void my_message_callback(struct mosquitto *mosq, void *obj, const struct mosquitto_message *message)
|
|
{
|
|
struct userdata *ud;
|
|
int i;
|
|
bool res;
|
|
|
|
assert(obj);
|
|
ud = (struct userdata *)obj;
|
|
|
|
if(message->retain && ud->no_retain) return;
|
|
if(ud->filter_outs){
|
|
for(i=0; i<ud->filter_out_count; i++){
|
|
mosquitto_topic_matches_sub(ud->filter_outs[i], message->topic, &res);
|
|
if(res) return;
|
|
}
|
|
}
|
|
|
|
if(ud->verbose){
|
|
if(message->payloadlen){
|
|
printf("%s ", message->topic);
|
|
fwrite(message->payload, 1, message->payloadlen, stdout);
|
|
if(ud->eol){
|
|
printf("\n");
|
|
}
|
|
}else{
|
|
if(ud->eol){
|
|
printf("%s (null)\n", message->topic);
|
|
}
|
|
}
|
|
fflush(stdout);
|
|
}else{
|
|
if(message->payloadlen){
|
|
fwrite(message->payload, 1, message->payloadlen, stdout);
|
|
if(ud->eol){
|
|
printf("\n");
|
|
}
|
|
fflush(stdout);
|
|
}
|
|
}
|
|
}
|
|
|
|
void my_connect_callback(struct mosquitto *mosq, void *obj, int result)
|
|
{
|
|
int i;
|
|
struct userdata *ud;
|
|
|
|
assert(obj);
|
|
ud = (struct userdata *)obj;
|
|
|
|
if(!result){
|
|
for(i=0; i<ud->topic_count; i++){
|
|
mosquitto_subscribe(mosq, NULL, ud->topics[i], ud->topic_qos);
|
|
}
|
|
}else{
|
|
if(result && !ud->quiet){
|
|
fprintf(stderr, "%s\n", mosquitto_connack_string(result));
|
|
}
|
|
}
|
|
}
|
|
|
|
void my_subscribe_callback(struct mosquitto *mosq, void *obj, int mid, int qos_count, const int *granted_qos)
|
|
{
|
|
int i;
|
|
struct userdata *ud;
|
|
|
|
assert(obj);
|
|
ud = (struct userdata *)obj;
|
|
|
|
if(!ud->quiet) printf("Subscribed (mid: %d): %d", mid, granted_qos[0]);
|
|
for(i=1; i<qos_count; i++){
|
|
if(!ud->quiet) printf(", %d", granted_qos[i]);
|
|
}
|
|
if(!ud->quiet) printf("\n");
|
|
}
|
|
|
|
void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str)
|
|
{
|
|
printf("%s\n", str);
|
|
}
|
|
|
|
void print_usage(void)
|
|
{
|
|
int major, minor, revision;
|
|
|
|
mosquitto_lib_version(&major, &minor, &revision);
|
|
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 ...\n");
|
|
printf(" [-T filter_out]\n");
|
|
printf(" [-A bind_address] [-S]\n");
|
|
printf(" [-i id] [-I id_prefix]\n");
|
|
printf(" [-d] [-N] [--quiet] [-v]\n");
|
|
printf(" [-u username [-P password]]\n");
|
|
printf(" [--will-topic [--will-payload payload] [--will-qos qos] [--will-retain]]\n");
|
|
#ifdef WITH_TLS
|
|
printf(" [{--cafile file | --capath dir} [--cert file] [--key file]\n");
|
|
printf(" [--ciphers ciphers] [--insecure]]\n");
|
|
#ifdef WITH_TLS_PSK
|
|
printf(" [--psk hex-key --psk-identity identity [--ciphers ciphers]]\n");
|
|
#endif
|
|
#endif
|
|
printf(" mosquitto_sub --help\n\n");
|
|
printf(" -A : bind the outgoing socket to this host/ip address. Use to control which interface\n");
|
|
printf(" the client communicates over.\n");
|
|
printf(" -c : disable 'clean session' (store subscription and pending messages when client disconnects).\n");
|
|
printf(" -d : enable debug messages.\n");
|
|
printf(" -h : mqtt host to connect to. Defaults to localhost.\n");
|
|
printf(" -i : id to use for this client. Defaults to mosquitto_sub_ appended with the process id.\n");
|
|
printf(" -I : define the client id as id_prefix appended with the process id. Useful for when the\n");
|
|
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(" -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");
|
|
printf(" -S : use SRV lookups to determine which host to connect to.\n");
|
|
printf(" -t : mqtt topic to subscribe to. May be repeated multiple times.\n");
|
|
printf(" -u : provide a username (requires MQTT 3.1 broker)\n");
|
|
printf(" -v : print published messages verbosely.\n");
|
|
printf(" -P : provide a password (requires MQTT 3.1 broker)\n");
|
|
printf(" --help : display this message.\n");
|
|
printf(" --quiet : don't print error messages.\n");
|
|
printf(" --will-payload : payload for the client Will, which is sent by the broker in case of\n");
|
|
printf(" unexpected disconnection. If not given and will-topic is set, a zero\n");
|
|
printf(" length message will be sent.\n");
|
|
printf(" --will-qos : QoS level for the client Will.\n");
|
|
printf(" --will-retain : if given, make the client Will retained.\n");
|
|
printf(" --will-topic : the topic on which to publish the client Will.\n");
|
|
#ifdef WITH_TLS
|
|
printf(" --cafile : path to a file containing trusted CA certificates to enable encrypted\n");
|
|
printf(" certificate based communication.\n");
|
|
printf(" --capath : path to a directory containing trusted CA certificates to enable encrypted\n");
|
|
printf(" communication.\n");
|
|
printf(" --cert : client certificate for authentication, if required by server.\n");
|
|
printf(" --key : client private key for authentication, if required by server.\n");
|
|
printf(" --ciphers : openssl compatible list of TLS ciphers to support.\n");
|
|
printf(" --tls-version : TLS protocol version, can be one of tlsv1.2 tlsv1.1 or tlsv1.\n");
|
|
printf(" Defaults to tlsv1.2 if available.\n");
|
|
printf(" --insecure : do not check that the server certificate hostname matches the remote\n");
|
|
printf(" hostname. Using this option means that you cannot be sure that the\n");
|
|
printf(" remote host is the server you wish to connect to and so is insecure.\n");
|
|
printf(" Do not use this option in a production environment.\n");
|
|
#ifdef WITH_TLS_PSK
|
|
printf(" --psk : pre-shared-key in hexadecimal (no leading 0x) to enable TLS-PSK mode.\n");
|
|
printf(" --psk-identity : client identity string for TLS-PSK mode.\n");
|
|
#endif
|
|
#endif
|
|
printf("\nSee http://mosquitto.org/ for more information.\n\n");
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
char *id = NULL;
|
|
char *id_prefix = NULL;
|
|
int i;
|
|
char *host = "localhost";
|
|
int port = 1883;
|
|
char *bind_address = NULL;
|
|
int keepalive = 60;
|
|
bool clean_session = true;
|
|
bool debug = false;
|
|
struct mosquitto *mosq = NULL;
|
|
int rc;
|
|
char hostname[256];
|
|
char err[1024];
|
|
struct userdata ud;
|
|
int len;
|
|
|
|
char *will_payload = NULL;
|
|
long will_payloadlen = 0;
|
|
int will_qos = 0;
|
|
bool will_retain = false;
|
|
char *will_topic = NULL;
|
|
|
|
bool insecure = false;
|
|
char *cafile = NULL;
|
|
char *capath = NULL;
|
|
char *certfile = NULL;
|
|
char *keyfile = NULL;
|
|
char *tls_version = NULL;
|
|
|
|
char *psk = NULL;
|
|
char *psk_identity = NULL;
|
|
|
|
char *ciphers = NULL;
|
|
|
|
bool use_srv = false;
|
|
|
|
memset(&ud, 0, sizeof(struct userdata));
|
|
ud.eol = true;
|
|
|
|
for(i=1; i<argc; i++){
|
|
if(!strcmp(argv[i], "-p") || !strcmp(argv[i], "--port")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: -p argument given but no port specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
port = atoi(argv[i+1]);
|
|
if(port<1 || port>65535){
|
|
fprintf(stderr, "Error: Invalid port given: %d\n", port);
|
|
print_usage();
|
|
return 1;
|
|
}
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "-A")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: -A argument given but no address specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
bind_address = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "-c") || !strcmp(argv[i], "--disable-clean-session")){
|
|
clean_session = false;
|
|
}else if(!strcmp(argv[i], "--cafile")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: --cafile argument given but no file specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
cafile = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "--capath")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: --capath argument given but no directory specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
capath = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "--cert")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: --cert argument given but no file specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
certfile = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "--ciphers")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: --ciphers argument given but no ciphers specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
ciphers = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")){
|
|
debug = true;
|
|
}else if(!strcmp(argv[i], "--help")){
|
|
print_usage();
|
|
return 0;
|
|
}else if(!strcmp(argv[i], "-h") || !strcmp(argv[i], "--host")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: -h argument given but no host specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
host = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "--insecure")){
|
|
insecure = true;
|
|
}else if(!strcmp(argv[i], "-i") || !strcmp(argv[i], "--id")){
|
|
if(id_prefix){
|
|
fprintf(stderr, "Error: -i and -I argument cannot be used together.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: -i argument given but no id specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
id = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "-I") || !strcmp(argv[i], "--id-prefix")){
|
|
if(id){
|
|
fprintf(stderr, "Error: -i and -I argument cannot be used together.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: -I argument given but no id prefix specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
id_prefix = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "-k") || !strcmp(argv[i], "--keepalive")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: -k argument given but no keepalive specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
keepalive = atoi(argv[i+1]);
|
|
if(keepalive>65535){
|
|
fprintf(stderr, "Error: Invalid keepalive given: %d\n", keepalive);
|
|
print_usage();
|
|
return 1;
|
|
}
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "--key")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: --key argument given but no file specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
keyfile = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "-N")){
|
|
ud.eol = false;
|
|
}else if(!strcmp(argv[i], "--psk")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: --psk argument given but no key specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
psk = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "--psk-identity")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: --psk-identity argument given but no identity specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
psk_identity = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "-q") || !strcmp(argv[i], "--qos")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: -q argument given but no QoS specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
ud.topic_qos = atoi(argv[i+1]);
|
|
if(ud.topic_qos<0 || ud.topic_qos>2){
|
|
fprintf(stderr, "Error: Invalid QoS given: %d\n", ud.topic_qos);
|
|
print_usage();
|
|
return 1;
|
|
}
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "--quiet")){
|
|
ud.quiet = true;
|
|
}else if(!strcmp(argv[i], "-R")){
|
|
ud.no_retain = true;
|
|
}else if(!strcmp(argv[i], "-S")){
|
|
use_srv = true;
|
|
}else if(!strcmp(argv[i], "-t") || !strcmp(argv[i], "--topic")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: -t argument given but no topic specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
ud.topic_count++;
|
|
ud.topics = realloc(ud.topics, ud.topic_count*sizeof(char *));
|
|
ud.topics[ud.topic_count-1] = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "-T") || !strcmp(argv[i], "--filter-out")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: -T argument given but no topic filter specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
ud.filter_out_count++;
|
|
ud.filter_outs = realloc(ud.filter_outs, ud.filter_out_count*sizeof(char *));
|
|
ud.filter_outs[ud.filter_out_count-1] = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "--tls-version")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: --tls-version argument given but no version specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
tls_version = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "-u") || !strcmp(argv[i], "--username")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: -u argument given but no username specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
ud.username = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")){
|
|
ud.verbose = 1;
|
|
}else if(!strcmp(argv[i], "-P") || !strcmp(argv[i], "--pw")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: -P argument given but no password specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
ud.password = argv[i+1];
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "--will-payload")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: --will-payload argument given but no will payload specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
will_payload = argv[i+1];
|
|
will_payloadlen = strlen(will_payload);
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "--will-qos")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: --will-qos argument given but no will QoS specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
will_qos = atoi(argv[i+1]);
|
|
if(will_qos < 0 || will_qos > 2){
|
|
fprintf(stderr, "Error: Invalid will QoS %d.\n\n", will_qos);
|
|
return 1;
|
|
}
|
|
}
|
|
i++;
|
|
}else if(!strcmp(argv[i], "--will-retain")){
|
|
will_retain = true;
|
|
}else if(!strcmp(argv[i], "--will-topic")){
|
|
if(i==argc-1){
|
|
fprintf(stderr, "Error: --will-topic argument given but no will topic specified.\n\n");
|
|
print_usage();
|
|
return 1;
|
|
}else{
|
|
will_topic = argv[i+1];
|
|
}
|
|
i++;
|
|
}else{
|
|
fprintf(stderr, "Error: Unknown option '%s'.\n",argv[i]);
|
|
print_usage();
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
if(clean_session == false && (id_prefix || !id)){
|
|
if(!ud.quiet) fprintf(stderr, "Error: You must provide a client id if you are using the -c option.\n");
|
|
return 1;
|
|
}
|
|
|
|
if(ud.topic_count == 0){
|
|
fprintf(stderr, "Error: You must specify a topic to subscribe to.\n");
|
|
print_usage();
|
|
return 1;
|
|
}
|
|
if(will_payload && !will_topic){
|
|
fprintf(stderr, "Error: Will payload given, but no will topic given.\n");
|
|
print_usage();
|
|
return 1;
|
|
}
|
|
if(will_retain && !will_topic){
|
|
fprintf(stderr, "Error: Will retain given, but no will topic given.\n");
|
|
print_usage();
|
|
return 1;
|
|
}
|
|
if(ud.password && !ud.username){
|
|
if(!ud.quiet) fprintf(stderr, "Warning: Not using password since username not set.\n");
|
|
}
|
|
if((certfile && !keyfile) || (keyfile && !certfile)){
|
|
fprintf(stderr, "Error: Both certfile and keyfile must be provided if one of them is.\n");
|
|
print_usage();
|
|
return 1;
|
|
}
|
|
if((cafile || capath) && psk){
|
|
if(!ud.quiet) fprintf(stderr, "Error: Only one of --psk or --cafile/--capath may be used at once.\n");
|
|
return 1;
|
|
}
|
|
if(psk && !psk_identity){
|
|
if(!ud.quiet) fprintf(stderr, "Error: --psk-identity required if --psk used.\n");
|
|
return 1;
|
|
}
|
|
|
|
mosquitto_lib_init();
|
|
|
|
if(id_prefix){
|
|
id = malloc(strlen(id_prefix)+10);
|
|
if(!id){
|
|
if(!ud.quiet) fprintf(stderr, "Error: Out of memory.\n");
|
|
mosquitto_lib_cleanup();
|
|
return 1;
|
|
}
|
|
snprintf(id, strlen(id_prefix)+10, "%s%d", id_prefix, getpid());
|
|
}else if(!id){
|
|
hostname[0] = '\0';
|
|
gethostname(hostname, 256);
|
|
hostname[255] = '\0';
|
|
len = strlen("mosqsub/-") + 6 + strlen(hostname);
|
|
id = malloc(len);
|
|
if(!id){
|
|
if(!ud.quiet) fprintf(stderr, "Error: Out of memory.\n");
|
|
mosquitto_lib_cleanup();
|
|
return 1;
|
|
}
|
|
snprintf(id, len, "mosqsub/%d-%s", getpid(), hostname);
|
|
if(strlen(id) > MOSQ_MQTT_ID_MAX_LENGTH){
|
|
/* Enforce maximum client id length of 23 characters */
|
|
id[MOSQ_MQTT_ID_MAX_LENGTH] = '\0';
|
|
}
|
|
}
|
|
|
|
mosq = mosquitto_new(id, clean_session, &ud);
|
|
if(!mosq){
|
|
switch(errno){
|
|
case ENOMEM:
|
|
if(!ud.quiet) fprintf(stderr, "Error: Out of memory.\n");
|
|
break;
|
|
case EINVAL:
|
|
if(!ud.quiet) fprintf(stderr, "Error: Invalid id and/or clean_session.\n");
|
|
break;
|
|
}
|
|
mosquitto_lib_cleanup();
|
|
return 1;
|
|
}
|
|
if(debug){
|
|
mosquitto_log_callback_set(mosq, my_log_callback);
|
|
}
|
|
if(will_topic && mosquitto_will_set(mosq, will_topic, will_payloadlen, will_payload, will_qos, will_retain)){
|
|
if(!ud.quiet) fprintf(stderr, "Error: Problem setting will.\n");
|
|
mosquitto_lib_cleanup();
|
|
return 1;
|
|
}
|
|
if(ud.username && mosquitto_username_pw_set(mosq, ud.username, ud.password)){
|
|
if(!ud.quiet) fprintf(stderr, "Error: Problem setting username and password.\n");
|
|
mosquitto_lib_cleanup();
|
|
return 1;
|
|
}
|
|
if((cafile || capath) && mosquitto_tls_set(mosq, cafile, capath, certfile, keyfile, NULL)){
|
|
if(!ud.quiet) fprintf(stderr, "Error: Problem setting TLS options.\n");
|
|
mosquitto_lib_cleanup();
|
|
return 1;
|
|
}
|
|
if(insecure && mosquitto_tls_insecure_set(mosq, true)){
|
|
if(!ud.quiet) fprintf(stderr, "Error: Problem setting TLS insecure option.\n");
|
|
mosquitto_lib_cleanup();
|
|
return 1;
|
|
}
|
|
if(psk && mosquitto_tls_psk_set(mosq, psk, psk_identity, NULL)){
|
|
if(!ud.quiet) fprintf(stderr, "Error: Problem setting TLS-PSK options.\n");
|
|
mosquitto_lib_cleanup();
|
|
return 1;
|
|
}
|
|
if(tls_version && mosquitto_tls_opts_set(mosq, 1, tls_version, ciphers)){
|
|
if(!ud.quiet) fprintf(stderr, "Error: Problem setting TLS options.\n");
|
|
mosquitto_lib_cleanup();
|
|
return 1;
|
|
}
|
|
mosquitto_connect_callback_set(mosq, my_connect_callback);
|
|
mosquitto_message_callback_set(mosq, my_message_callback);
|
|
if(debug){
|
|
mosquitto_subscribe_callback_set(mosq, my_subscribe_callback);
|
|
}
|
|
|
|
if(use_srv){
|
|
rc = mosquitto_connect_srv(mosq, host, keepalive, bind_address);
|
|
}else{
|
|
rc = mosquitto_connect_bind(mosq, host, port, keepalive, bind_address);
|
|
}
|
|
if(rc){
|
|
if(!ud.quiet){
|
|
if(rc == MOSQ_ERR_ERRNO){
|
|
#ifndef WIN32
|
|
strerror_r(errno, err, 1024);
|
|
#else
|
|
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, errno, 0, (LPTSTR)&err, 1024, NULL);
|
|
#endif
|
|
fprintf(stderr, "Error: %s\n", err);
|
|
}else{
|
|
fprintf(stderr, "Unable to connect (%d).\n", rc);
|
|
}
|
|
}
|
|
mosquitto_lib_cleanup();
|
|
return rc;
|
|
}
|
|
|
|
rc = mosquitto_loop_forever(mosq, -1, 1);
|
|
|
|
mosquitto_destroy(mosq);
|
|
mosquitto_lib_cleanup();
|
|
|
|
if(rc){
|
|
fprintf(stderr, "Error: %s\n", mosquitto_strerror(rc));
|
|
}
|
|
return rc;
|
|
}
|
|
|