diff --git a/ChangeLog.txt b/ChangeLog.txt index bf969ef5..8c9117f2 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,5 +1,8 @@ - Default TLS mode now accepts TLS v1.2, v1.1 and v1.0. +Clients: +- Both clients can now load default configuration options from a file. + 1.3.2 - 2014xxxx ================ diff --git a/client/client_shared.c b/client/client_shared.c index 10a8409b..81388ca5 100644 --- a/client/client_shared.c +++ b/client/client_shared.c @@ -31,6 +31,8 @@ Contributors: #include #include "client_shared.h" +static int client_config_line_proc(struct mosq_config *cfg, int pub_or_sub, int argc, char *argv[]); + void init_config(struct mosq_config *cfg) { memset(cfg, 0, sizeof(*cfg)); @@ -43,316 +45,86 @@ void init_config(struct mosq_config *cfg) int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char *argv[]) { - int i; + int rc; + FILE *fptr; + char line[1024]; + int count; +#ifndef WIN32 + char *env; + char *loc = NULL; + int len; + char *args[3]; +#endif + + args[0] = NULL; init_config(cfg); - for(i=1; iport = atoi(argv[i+1]); - if(cfg->port<1 || cfg->port>65535){ - fprintf(stderr, "Error: Invalid port given: %d\n", cfg->port); - 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"); - return 1; - }else{ - cfg->bind_address = argv[i+1]; - } - i++; - }else if(!strcmp(argv[i], "--cafile")){ - if(i==argc-1){ - fprintf(stderr, "Error: --cafile argument given but no file specified.\n\n"); - return 1; - }else{ - cfg->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"); - return 1; - }else{ - cfg->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"); - return 1; - }else{ - cfg->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"); - return 1; - }else{ - cfg->ciphers = argv[i+1]; - } - i++; - }else if(!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")){ - cfg->debug = true; - }else if(!strcmp(argv[i], "-f") || !strcmp(argv[i], "--file")){ - if(cfg->pub_mode != MSGMODE_NONE){ - fprintf(stderr, "Error: Only one type of message can be sent at once.\n\n"); - return 1; - }else if(i==argc-1){ - fprintf(stderr, "Error: -f argument given but no file specified.\n\n"); - return 1; - }else{ - cfg->pub_mode = MSGMODE_FILE; - cfg->file_input = argv[i+1]; - } - i++; - }else if(!strcmp(argv[i], "--help")){ - return 1; - }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"); - return 1; - }else{ - cfg->host = argv[i+1]; - } - i++; - }else if(!strcmp(argv[i], "--insecure")){ - cfg->insecure = true; - }else if(!strcmp(argv[i], "-i") || !strcmp(argv[i], "--id")){ - if(cfg->id_prefix){ - fprintf(stderr, "Error: -i and -I argument cannot be used together.\n\n"); - return 1; - } - if(i==argc-1){ - fprintf(stderr, "Error: -i argument given but no id specified.\n\n"); - return 1; - }else{ - cfg->id = argv[i+1]; - } - i++; - }else if(!strcmp(argv[i], "-I") || !strcmp(argv[i], "--id-prefix")){ - if(cfg->id){ - fprintf(stderr, "Error: -i and -I argument cannot be used together.\n\n"); - return 1; - } - if(i==argc-1){ - fprintf(stderr, "Error: -I argument given but no id prefix specified.\n\n"); - return 1; - }else{ - cfg->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"); - return 1; - }else{ - cfg->keepalive = atoi(argv[i+1]); - if(cfg->keepalive>65535){ - fprintf(stderr, "Error: Invalid keepalive given: %d\n", cfg->keepalive); - 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"); - return 1; - }else{ - cfg->keyfile = argv[i+1]; - } - i++; - }else if(!strcmp(argv[i], "-l") || !strcmp(argv[i], "--stdin-line")){ - if(cfg->pub_mode != MSGMODE_NONE){ - fprintf(stderr, "Error: Only one type of message can be sent at once.\n\n"); - return 1; - }else{ - cfg->pub_mode = MSGMODE_STDIN_LINE; - } - }else if(!strcmp(argv[i], "-m") || !strcmp(argv[i], "--message")){ - if(cfg->pub_mode != MSGMODE_NONE){ - fprintf(stderr, "Error: Only one type of message can be sent at once.\n\n"); - return 1; - }else if(i==argc-1){ - fprintf(stderr, "Error: -m argument given but no message specified.\n\n"); - return 1; - }else{ - cfg->message = argv[i+1]; - cfg->msglen = strlen(cfg->message); - cfg->pub_mode = MSGMODE_CMD; - } - i++; - }else if(!strcmp(argv[i], "-M")){ - if(i==argc-1){ - fprintf(stderr, "Error: -M argument given but max_inflight not specified.\n\n"); - return 1; - }else{ - cfg->max_inflight = atoi(argv[i+1]); - } - i++; - }else if(!strcmp(argv[i], "-n") || !strcmp(argv[i], "--null-message")){ - if(cfg->pub_mode != MSGMODE_NONE){ - fprintf(stderr, "Error: Only one type of message can be sent at once.\n\n"); - return 1; - }else{ - cfg->pub_mode = MSGMODE_NULL; - } - }else if(!strcmp(argv[i], "--psk")){ - if(i==argc-1){ - fprintf(stderr, "Error: --psk argument given but no key specified.\n\n"); - return 1; - }else{ - cfg->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"); - return 1; - }else{ - cfg->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"); - return 1; - }else{ - cfg->qos = atoi(argv[i+1]); - if(cfg->qos<0 || cfg->qos>2){ - fprintf(stderr, "Error: Invalid QoS given: %d\n", cfg->qos); - return 1; - } - } - i++; - }else if(!strcmp(argv[i], "--quiet")){ - cfg->quiet = true; - }else if(!strcmp(argv[i], "-r") || !strcmp(argv[i], "--retain")){ - cfg->retain = 1; - }else if(!strcmp(argv[i], "-s") || !strcmp(argv[i], "--stdin-file")){ - if(cfg->pub_mode != MSGMODE_NONE){ - fprintf(stderr, "Error: Only one type of message can be sent at once.\n\n"); - return 1; - }else{ - cfg->pub_mode = MSGMODE_STDIN_FILE; - } - }else if(!strcmp(argv[i], "-S")){ - cfg->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"); - return 1; - }else{ - if(pub_or_sub == CLIENT_PUB){ - cfg->topic = argv[i+1]; - }else{ - cfg->topic_count++; - cfg->topics = realloc(cfg->topics, cfg->topic_count*sizeof(char *)); - cfg->topics[cfg->topic_count-1] = argv[i+1]; - } - i++; - } - }else if(!strcmp(argv[i], "-T") || !strcmp(argv[i], "--filter-out")){ - if(pub_or_sub == CLIENT_PUB){ - goto unknown_option; - } - if(i==argc-1){ - fprintf(stderr, "Error: -T argument given but no topic filter specified.\n\n"); - return 1; - }else{ - cfg->filter_out_count++; - cfg->filter_outs = realloc(cfg->filter_outs, cfg->filter_out_count*sizeof(char *)); - cfg->filter_outs[cfg->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"); - return 1; - }else{ - cfg->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"); - return 1; - }else{ - cfg->username = argv[i+1]; - } - i++; - }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"); - return 1; - }else{ - cfg->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"); - return 1; - }else{ - cfg->will_payload = argv[i+1]; - cfg->will_payloadlen = strlen(cfg->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"); - return 1; - }else{ - cfg->will_qos = atoi(argv[i+1]); - if(cfg->will_qos < 0 || cfg->will_qos > 2){ - fprintf(stderr, "Error: Invalid will QoS %d.\n\n", cfg->will_qos); - return 1; - } - } - i++; - }else if(!strcmp(argv[i], "--will-retain")){ - cfg->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"); - return 1; - }else{ - cfg->will_topic = argv[i+1]; - } - i++; - }else if(!strcmp(argv[i], "-c") || !strcmp(argv[i], "--disable-clean-session")){ - if(pub_or_sub == CLIENT_PUB){ - goto unknown_option; - } - cfg->clean_session = false; - }else if(!strcmp(argv[i], "-N")){ - if(pub_or_sub == CLIENT_PUB){ - goto unknown_option; - } - cfg->eol = false; - }else if(!strcmp(argv[i], "-R")){ - if(pub_or_sub == CLIENT_PUB){ - goto unknown_option; - } - cfg->no_retain = true; - }else if(!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")){ - if(pub_or_sub == CLIENT_PUB){ - goto unknown_option; - } - cfg->verbose = 1; + /* Default config file */ +#ifndef WIN32 + env = getenv("XDG_CONFIG_HOME"); + if(env){ + len = strlen(env) + strlen("/mosquitto_pub") + 1; + loc = malloc(len); + if(pub_or_sub == CLIENT_PUB){ + snprintf(loc, len, "%s/mosquitto_pub", env); }else{ - goto unknown_option; + snprintf(loc, len, "%s/mosquitto_sub", env); + } + loc[len-1] = '\0'; + }else{ + env = getenv("HOME"); + if(env){ + len = strlen(env) + strlen("/.config/mosquitto_pub") + 1; + loc = malloc(len); + if(pub_or_sub == CLIENT_PUB){ + snprintf(loc, len, "%s/.config/mosquitto_pub", env); + }else{ + snprintf(loc, len, "%s/.config/mosquitto_sub", env); + } + loc[len-1] = '\0'; + }else{ + fprintf(stderr, "Warning: Unable to locate configuration directory, default config not loaded.\n"); } } + if(loc){ + fptr = fopen(loc, "rt"); + if(fptr){ + while(fgets(line, 1024, fptr)){ + while(line[strlen(line)-1] == 10 || line[strlen(line)-1] == 13){ + line[strlen(line)-1] = 0; + } + /* All offset by one "args" here, because real argc/argv has + * program name as the first entry. */ + args[1] = strtok(line, " "); + if(args[1]){ + args[2] = strtok(NULL, " "); + if(args[2]){ + count = 3; + }else{ + count = 2; + } + rc = client_config_line_proc(cfg, pub_or_sub, count, args); + if(rc){ + fclose(fptr); + free(loc); + return rc; + } + } + } + fclose(fptr); + } + free(loc); + } +#else +#warn FIXME - config file support +#endif + + /* Deal with real argc/argv */ + rc = client_config_line_proc(cfg, pub_or_sub, argc, argv); + if(rc) return rc; + if(cfg->will_payload && !cfg->will_topic){ fprintf(stderr, "Error: Will payload given, but no will topic given.\n"); return 1; @@ -391,6 +163,337 @@ int client_config_load(struct mosq_config *cfg, int pub_or_sub, int argc, char * if(!cfg->host){ cfg->host = "localhost"; } + return MOSQ_ERR_SUCCESS; +} + +/* 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[]) +{ + int i; + + for(i=1; iport = atoi(argv[i+1]); + if(cfg->port<1 || cfg->port>65535){ + fprintf(stderr, "Error: Invalid port given: %d\n", cfg->port); + 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"); + return 1; + }else{ + cfg->bind_address = strdup(argv[i+1]); + } + i++; + }else if(!strcmp(argv[i], "--cafile")){ + if(i==argc-1){ + fprintf(stderr, "Error: --cafile argument given but no file specified.\n\n"); + return 1; + }else{ + cfg->cafile = strdup(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"); + return 1; + }else{ + cfg->capath = strdup(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"); + return 1; + }else{ + cfg->certfile = strdup(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"); + return 1; + }else{ + cfg->ciphers = strdup(argv[i+1]); + } + i++; + }else if(!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")){ + cfg->debug = true; + }else if(!strcmp(argv[i], "-f") || !strcmp(argv[i], "--file")){ + if(pub_or_sub == CLIENT_SUB){ + goto unknown_option; + } + if(cfg->pub_mode != MSGMODE_NONE){ + fprintf(stderr, "Error: Only one type of message can be sent at once.\n\n"); + return 1; + }else if(i==argc-1){ + fprintf(stderr, "Error: -f argument given but no file specified.\n\n"); + return 1; + }else{ + cfg->pub_mode = MSGMODE_FILE; + cfg->file_input = strdup(argv[i+1]); + } + i++; + }else if(!strcmp(argv[i], "--help")){ + return 1; + }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"); + return 1; + }else{ + cfg->host = strdup(argv[i+1]); + } + i++; + }else if(!strcmp(argv[i], "--insecure")){ + cfg->insecure = true; + }else if(!strcmp(argv[i], "-i") || !strcmp(argv[i], "--id")){ + if(cfg->id_prefix){ + fprintf(stderr, "Error: -i and -I argument cannot be used together.\n\n"); + return 1; + } + if(i==argc-1){ + fprintf(stderr, "Error: -i argument given but no id specified.\n\n"); + return 1; + }else{ + cfg->id = strdup(argv[i+1]); + } + i++; + }else if(!strcmp(argv[i], "-I") || !strcmp(argv[i], "--id-prefix")){ + if(cfg->id){ + fprintf(stderr, "Error: -i and -I argument cannot be used together.\n\n"); + return 1; + } + if(i==argc-1){ + fprintf(stderr, "Error: -I argument given but no id prefix specified.\n\n"); + return 1; + }else{ + cfg->id_prefix = strdup(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"); + return 1; + }else{ + cfg->keepalive = atoi(argv[i+1]); + if(cfg->keepalive>65535){ + fprintf(stderr, "Error: Invalid keepalive given: %d\n", cfg->keepalive); + 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"); + return 1; + }else{ + cfg->keyfile = strdup(argv[i+1]); + } + i++; + }else if(!strcmp(argv[i], "-l") || !strcmp(argv[i], "--stdin-line")){ + if(pub_or_sub == CLIENT_SUB){ + goto unknown_option; + } + if(cfg->pub_mode != MSGMODE_NONE){ + fprintf(stderr, "Error: Only one type of message can be sent at once.\n\n"); + return 1; + }else{ + cfg->pub_mode = MSGMODE_STDIN_LINE; + } + }else if(!strcmp(argv[i], "-m") || !strcmp(argv[i], "--message")){ + if(pub_or_sub == CLIENT_SUB){ + goto unknown_option; + } + if(cfg->pub_mode != MSGMODE_NONE){ + fprintf(stderr, "Error: Only one type of message can be sent at once.\n\n"); + return 1; + }else if(i==argc-1){ + fprintf(stderr, "Error: -m argument given but no message specified.\n\n"); + return 1; + }else{ + cfg->message = strdup(argv[i+1]); + cfg->msglen = strlen(cfg->message); + cfg->pub_mode = MSGMODE_CMD; + } + i++; + }else if(!strcmp(argv[i], "-M")){ + if(i==argc-1){ + fprintf(stderr, "Error: -M argument given but max_inflight not specified.\n\n"); + return 1; + }else{ + cfg->max_inflight = atoi(argv[i+1]); + } + i++; + }else if(!strcmp(argv[i], "-n") || !strcmp(argv[i], "--null-message")){ + if(pub_or_sub == CLIENT_SUB){ + goto unknown_option; + } + if(cfg->pub_mode != MSGMODE_NONE){ + fprintf(stderr, "Error: Only one type of message can be sent at once.\n\n"); + return 1; + }else{ + cfg->pub_mode = MSGMODE_NULL; + } + }else if(!strcmp(argv[i], "--psk")){ + if(i==argc-1){ + fprintf(stderr, "Error: --psk argument given but no key specified.\n\n"); + return 1; + }else{ + cfg->psk = strdup(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"); + return 1; + }else{ + cfg->psk_identity = strdup(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"); + return 1; + }else{ + cfg->qos = atoi(argv[i+1]); + if(cfg->qos<0 || cfg->qos>2){ + fprintf(stderr, "Error: Invalid QoS given: %d\n", cfg->qos); + return 1; + } + } + i++; + }else if(!strcmp(argv[i], "--quiet")){ + cfg->quiet = true; + }else if(!strcmp(argv[i], "-r") || !strcmp(argv[i], "--retain")){ + if(pub_or_sub == CLIENT_SUB){ + goto unknown_option; + } + cfg->retain = 1; + }else if(!strcmp(argv[i], "-s") || !strcmp(argv[i], "--stdin-file")){ + if(pub_or_sub == CLIENT_SUB){ + goto unknown_option; + } + if(cfg->pub_mode != MSGMODE_NONE){ + fprintf(stderr, "Error: Only one type of message can be sent at once.\n\n"); + return 1; + }else{ + cfg->pub_mode = MSGMODE_STDIN_FILE; + } + }else if(!strcmp(argv[i], "-S")){ + cfg->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"); + return 1; + }else{ + if(pub_or_sub == CLIENT_PUB){ + cfg->topic = strdup(argv[i+1]); + }else{ + cfg->topic_count++; + cfg->topics = realloc(cfg->topics, cfg->topic_count*sizeof(char *)); + cfg->topics[cfg->topic_count-1] = strdup(argv[i+1]); + } + i++; + } + }else if(!strcmp(argv[i], "-T") || !strcmp(argv[i], "--filter-out")){ + if(pub_or_sub == CLIENT_PUB){ + goto unknown_option; + } + if(i==argc-1){ + fprintf(stderr, "Error: -T argument given but no topic filter specified.\n\n"); + return 1; + }else{ + cfg->filter_out_count++; + cfg->filter_outs = realloc(cfg->filter_outs, cfg->filter_out_count*sizeof(char *)); + cfg->filter_outs[cfg->filter_out_count-1] = strdup(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"); + return 1; + }else{ + cfg->tls_version = strdup(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"); + return 1; + }else{ + cfg->username = strdup(argv[i+1]); + } + i++; + }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"); + return 1; + }else{ + cfg->password = strdup(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"); + return 1; + }else{ + cfg->will_payload = strdup(argv[i+1]); + cfg->will_payloadlen = strlen(cfg->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"); + return 1; + }else{ + cfg->will_qos = atoi(argv[i+1]); + if(cfg->will_qos < 0 || cfg->will_qos > 2){ + fprintf(stderr, "Error: Invalid will QoS %d.\n\n", cfg->will_qos); + return 1; + } + } + i++; + }else if(!strcmp(argv[i], "--will-retain")){ + cfg->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"); + return 1; + }else{ + cfg->will_topic = strdup(argv[i+1]); + } + i++; + }else if(!strcmp(argv[i], "-c") || !strcmp(argv[i], "--disable-clean-session")){ + if(pub_or_sub == CLIENT_PUB){ + goto unknown_option; + } + cfg->clean_session = false; + }else if(!strcmp(argv[i], "-N")){ + if(pub_or_sub == CLIENT_PUB){ + goto unknown_option; + } + cfg->eol = false; + }else if(!strcmp(argv[i], "-R")){ + if(pub_or_sub == CLIENT_PUB){ + goto unknown_option; + } + cfg->no_retain = true; + }else if(!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose")){ + if(pub_or_sub == CLIENT_PUB){ + goto unknown_option; + } + cfg->verbose = 1; + }else{ + goto unknown_option; + } + } return MOSQ_ERR_SUCCESS; diff --git a/man/mosquitto_pub.1.xml b/man/mosquitto_pub.1.xml index 1ab932d1..73dd6b42 100644 --- a/man/mosquitto_pub.1.xml +++ b/man/mosquitto_pub.1.xml @@ -80,6 +80,16 @@ Options + The options below may be given on the command line, but may also + be placed in a config file located at + or + with one pair of + + per line. The values in the config file will be used as defaults + and can be overridden by using the command line. The exceptions to + this are the message type options, of which only one can be + specified. Note also that currently some options cannot be negated, + e.g. . @@ -403,6 +413,19 @@ + + Files + + + $XDG_CONFIG_HOME/mosquitto_pub + $HOME/.config/mosquitto_pub + + Configuration file for default options. + + + + + Bugs mosquitto_pub bug information can be found at http://launchpad.net/mosquitto diff --git a/man/mosquitto_sub.1.xml b/man/mosquitto_sub.1.xml index 07bfb6a2..e729b4c5 100644 --- a/man/mosquitto_sub.1.xml +++ b/man/mosquitto_sub.1.xml @@ -78,6 +78,17 @@ Options + The options below may be given on the command line, but may also + be placed in a config file located at + or + with one pair of + + per line. The values in the config file will be used as defaults + and can be overridden by using the command line. The exceptions to + this are and , which if + given in the config file will not be overridden. Note also that + currently some options cannot be negated, e.g. + . @@ -432,6 +443,19 @@ + + Files + + + $XDG_CONFIG_HOME/mosquitto_sub + $HOME/.config/mosquitto_sub + + Configuration file for default options. + + + + + Bugs mosquitto_sub bug information can be found at