2014-05-07 22:27:00 +00:00
|
|
|
/*
|
2018-04-11 14:24:29 +00:00
|
|
|
Copyright (c) 2009-2018 Roger Light <roger@atchoo.org>
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2018-04-05 23:33:22 +00:00
|
|
|
/* For nanosleep */
|
|
|
|
#define _POSIX_C_SOURCE 200809L
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#ifndef WIN32
|
2018-04-05 23:33:22 +00:00
|
|
|
#include <time.h>
|
2014-05-07 22:27:00 +00:00
|
|
|
#else
|
|
|
|
#include <process.h>
|
|
|
|
#include <winsock2.h>
|
|
|
|
#define snprintf sprintf_s
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <mosquitto.h>
|
2014-05-24 22:04:42 +00:00
|
|
|
#include "client_shared.h"
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
#define STATUS_CONNECTING 0
|
|
|
|
#define STATUS_CONNACK_RECVD 1
|
|
|
|
#define STATUS_WAITING 2
|
2018-01-22 17:52:56 +00:00
|
|
|
#define STATUS_DISCONNECTING 3
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
/* Global variables for use in callbacks. See sub_client.c for an example of
|
|
|
|
* using a struct to hold variables for use in callbacks. */
|
|
|
|
static char *topic = NULL;
|
|
|
|
static char *message = NULL;
|
|
|
|
static long msglen = 0;
|
|
|
|
static int qos = 0;
|
|
|
|
static int retain = 0;
|
|
|
|
static int mode = MSGMODE_NONE;
|
|
|
|
static int status = STATUS_CONNECTING;
|
|
|
|
static int mid_sent = 0;
|
|
|
|
static int last_mid = -1;
|
|
|
|
static int last_mid_sent = -1;
|
|
|
|
static bool connected = true;
|
|
|
|
static char *username = NULL;
|
|
|
|
static char *password = NULL;
|
|
|
|
static bool disconnect_sent = false;
|
|
|
|
static bool quiet = false;
|
|
|
|
|
|
|
|
void my_connect_callback(struct mosquitto *mosq, void *obj, int result)
|
|
|
|
{
|
|
|
|
int rc = MOSQ_ERR_SUCCESS;
|
|
|
|
|
|
|
|
if(!result){
|
|
|
|
switch(mode){
|
|
|
|
case MSGMODE_CMD:
|
|
|
|
case MSGMODE_FILE:
|
|
|
|
case MSGMODE_STDIN_FILE:
|
|
|
|
rc = mosquitto_publish(mosq, &mid_sent, topic, msglen, message, qos, retain);
|
|
|
|
break;
|
|
|
|
case MSGMODE_NULL:
|
|
|
|
rc = mosquitto_publish(mosq, &mid_sent, topic, 0, NULL, qos, retain);
|
|
|
|
break;
|
|
|
|
case MSGMODE_STDIN_LINE:
|
|
|
|
status = STATUS_CONNACK_RECVD;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if(rc){
|
|
|
|
if(!quiet){
|
|
|
|
switch(rc){
|
|
|
|
case MOSQ_ERR_INVAL:
|
|
|
|
fprintf(stderr, "Error: Invalid input. Does your topic contain '+' or '#'?\n");
|
|
|
|
break;
|
|
|
|
case MOSQ_ERR_NOMEM:
|
|
|
|
fprintf(stderr, "Error: Out of memory when trying to publish message.\n");
|
|
|
|
break;
|
|
|
|
case MOSQ_ERR_NO_CONN:
|
|
|
|
fprintf(stderr, "Error: Client not connected when trying to publish.\n");
|
|
|
|
break;
|
|
|
|
case MOSQ_ERR_PROTOCOL:
|
|
|
|
fprintf(stderr, "Error: Protocol error when communicating with broker.\n");
|
|
|
|
break;
|
|
|
|
case MOSQ_ERR_PAYLOAD_SIZE:
|
|
|
|
fprintf(stderr, "Error: Message payload is too large.\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
mosquitto_disconnect(mosq);
|
|
|
|
}
|
|
|
|
}else{
|
|
|
|
if(result && !quiet){
|
|
|
|
fprintf(stderr, "%s\n", mosquitto_connack_string(result));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc)
|
|
|
|
{
|
|
|
|
connected = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void my_publish_callback(struct mosquitto *mosq, void *obj, int mid)
|
|
|
|
{
|
|
|
|
last_mid_sent = mid;
|
|
|
|
if(mode == MSGMODE_STDIN_LINE){
|
|
|
|
if(mid == last_mid){
|
|
|
|
mosquitto_disconnect(mosq);
|
|
|
|
disconnect_sent = true;
|
|
|
|
}
|
|
|
|
}else if(disconnect_sent == false){
|
|
|
|
mosquitto_disconnect(mosq);
|
|
|
|
disconnect_sent = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str)
|
|
|
|
{
|
|
|
|
printf("%s\n", str);
|
|
|
|
}
|
|
|
|
|
|
|
|
int load_stdin(void)
|
|
|
|
{
|
|
|
|
long pos = 0, rlen;
|
|
|
|
char buf[1024];
|
2015-06-01 03:04:31 +00:00
|
|
|
char *aux_message = NULL;
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
mode = MSGMODE_STDIN_FILE;
|
|
|
|
|
|
|
|
while(!feof(stdin)){
|
|
|
|
rlen = fread(buf, 1, 1024, stdin);
|
2015-06-01 03:04:31 +00:00
|
|
|
aux_message = realloc(message, pos+rlen);
|
|
|
|
if(!aux_message){
|
2014-05-07 22:27:00 +00:00
|
|
|
if(!quiet) fprintf(stderr, "Error: Out of memory.\n");
|
2015-06-01 03:04:31 +00:00
|
|
|
free(message);
|
2014-05-07 22:27:00 +00:00
|
|
|
return 1;
|
2015-06-01 03:04:31 +00:00
|
|
|
} else
|
|
|
|
{
|
|
|
|
message = aux_message;
|
2014-05-07 22:27:00 +00:00
|
|
|
}
|
|
|
|
memcpy(&(message[pos]), buf, rlen);
|
|
|
|
pos += rlen;
|
|
|
|
}
|
|
|
|
msglen = pos;
|
|
|
|
|
|
|
|
if(!msglen){
|
|
|
|
if(!quiet) fprintf(stderr, "Error: Zero length input.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int load_file(const char *filename)
|
|
|
|
{
|
|
|
|
long pos, rlen;
|
|
|
|
FILE *fptr = NULL;
|
|
|
|
|
|
|
|
fptr = fopen(filename, "rb");
|
|
|
|
if(!fptr){
|
|
|
|
if(!quiet) fprintf(stderr, "Error: Unable to open file \"%s\".\n", filename);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
mode = MSGMODE_FILE;
|
|
|
|
fseek(fptr, 0, SEEK_END);
|
|
|
|
msglen = ftell(fptr);
|
|
|
|
if(msglen > 268435455){
|
|
|
|
fclose(fptr);
|
|
|
|
if(!quiet) fprintf(stderr, "Error: File \"%s\" is too large (>268,435,455 bytes).\n", filename);
|
|
|
|
return 1;
|
|
|
|
}else if(msglen == 0){
|
|
|
|
fclose(fptr);
|
|
|
|
if(!quiet) fprintf(stderr, "Error: File \"%s\" is empty.\n", filename);
|
|
|
|
return 1;
|
|
|
|
}else if(msglen < 0){
|
|
|
|
fclose(fptr);
|
|
|
|
if(!quiet) fprintf(stderr, "Error: Unable to determine size of file \"%s\".\n", filename);
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
fseek(fptr, 0, SEEK_SET);
|
|
|
|
message = malloc(msglen);
|
|
|
|
if(!message){
|
|
|
|
fclose(fptr);
|
|
|
|
if(!quiet) fprintf(stderr, "Error: Out of memory.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
pos = 0;
|
|
|
|
while(pos < msglen){
|
|
|
|
rlen = fread(&(message[pos]), sizeof(char), msglen-pos, fptr);
|
|
|
|
pos += rlen;
|
|
|
|
}
|
|
|
|
fclose(fptr);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void print_usage(void)
|
|
|
|
{
|
|
|
|
int major, minor, revision;
|
|
|
|
|
|
|
|
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);
|
2016-02-27 07:41:50 +00:00
|
|
|
printf("Usage: mosquitto_pub {[-h host] [-p port] [-u username [-P password]] -t topic | -L URL}\n");
|
|
|
|
printf(" {-f file | -l | -n | -m message}\n");
|
2017-07-17 19:43:06 +00:00
|
|
|
printf(" [-c] [-k keepalive] [-q qos] [-r]\n");
|
2014-05-19 13:23:38 +00:00
|
|
|
#ifdef WITH_SRV
|
2014-05-07 22:27:00 +00:00
|
|
|
printf(" [-A bind_address] [-S]\n");
|
2014-05-19 13:23:38 +00:00
|
|
|
#else
|
|
|
|
printf(" [-A bind_address]\n");
|
|
|
|
#endif
|
2014-05-07 22:27:00 +00:00
|
|
|
printf(" [-i id] [-I id_prefix]\n");
|
|
|
|
printf(" [-d] [--quiet]\n");
|
|
|
|
printf(" [-M max_inflight]\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
|
2014-09-29 23:56:57 +00:00
|
|
|
#endif
|
|
|
|
#ifdef WITH_SOCKS
|
|
|
|
printf(" [--proxy socks-url]\n");
|
2014-05-07 22:27:00 +00:00
|
|
|
#endif
|
|
|
|
printf(" mosquitto_pub --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(" -d : enable debug messages.\n");
|
|
|
|
printf(" -f : send the contents of a file as the message.\n");
|
|
|
|
printf(" -h : mqtt host to connect to. Defaults to localhost.\n");
|
|
|
|
printf(" -i : id to use for this client. Defaults to mosquitto_pub_ 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");
|
2014-12-16 22:53:52 +00:00
|
|
|
printf(" -k : keep alive in seconds for this client. Defaults to 60.\n");
|
2016-02-27 07:41:50 +00:00
|
|
|
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");
|
2014-05-07 22:27:00 +00:00
|
|
|
printf(" -l : read messages from stdin, sending a separate message for each line.\n");
|
|
|
|
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");
|
2016-02-16 01:17:54 +00:00
|
|
|
printf(" -p : network port to connect to. Defaults to 1883 for plain MQTT and 8883 for MQTT over TLS.\n");
|
2018-03-15 11:25:18 +00:00
|
|
|
printf(" -P : provide a password\n");
|
2014-05-07 22:27:00 +00:00
|
|
|
printf(" -q : quality of service level to use for all messages. Defaults to 0.\n");
|
|
|
|
printf(" -r : message should be retained.\n");
|
|
|
|
printf(" -s : read message from stdin, sending the entire input as a message.\n");
|
2014-05-19 13:23:38 +00:00
|
|
|
#ifdef WITH_SRV
|
2014-05-07 22:27:00 +00:00
|
|
|
printf(" -S : use SRV lookups to determine which host to connect to.\n");
|
2014-05-19 13:23:38 +00:00
|
|
|
#endif
|
2014-05-07 22:27:00 +00:00
|
|
|
printf(" -t : mqtt topic to publish to.\n");
|
2018-03-15 11:25:18 +00:00
|
|
|
printf(" -u : provide a username\n");
|
2015-01-27 00:32:20 +00:00
|
|
|
printf(" -V : specify the version of the MQTT protocol to use when connecting.\n");
|
2017-08-09 22:59:08 +00:00
|
|
|
printf(" Can be mqttv31 or mqttv311. Defaults to mqttv311.\n");
|
2014-05-07 22:27:00 +00:00
|
|
|
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(" 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");
|
2014-09-29 23:56:57 +00:00
|
|
|
# ifdef WITH_TLS_PSK
|
2014-05-07 22:27:00 +00:00
|
|
|
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");
|
2014-09-29 23:56:57 +00:00
|
|
|
# endif
|
2014-05-07 22:27:00 +00:00
|
|
|
#endif
|
2014-09-29 23:56:57 +00:00
|
|
|
#ifdef WITH_SOCKS
|
|
|
|
printf(" --proxy : SOCKS5 proxy URL of the form:\n");
|
|
|
|
printf(" socks5h://[username[:password]@]hostname[:port]\n");
|
|
|
|
printf(" Only \"none\" and \"username\" authentication is supported.\n");
|
2014-05-07 22:27:00 +00:00
|
|
|
#endif
|
|
|
|
printf("\nSee http://mosquitto.org/ for more information.\n\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
|
|
{
|
2014-05-24 22:04:42 +00:00
|
|
|
struct mosq_config cfg;
|
2014-05-07 22:27:00 +00:00
|
|
|
struct mosquitto *mosq = NULL;
|
|
|
|
int rc;
|
|
|
|
int rc2;
|
2018-03-26 21:19:11 +00:00
|
|
|
char *buf, *buf2;
|
2015-10-11 21:55:54 +00:00
|
|
|
int buf_len = 1024;
|
|
|
|
int buf_len_actual;
|
|
|
|
int read_len;
|
|
|
|
int pos;
|
|
|
|
|
|
|
|
buf = malloc(buf_len);
|
|
|
|
if(!buf){
|
|
|
|
fprintf(stderr, "Error: Out of memory.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
2014-05-24 22:04:42 +00:00
|
|
|
|
2015-10-11 21:55:54 +00:00
|
|
|
memset(&cfg, 0, sizeof(struct mosq_config));
|
2014-09-10 15:10:53 +00:00
|
|
|
rc = client_config_load(&cfg, CLIENT_PUB, argc, argv);
|
|
|
|
if(rc){
|
2014-11-16 23:41:06 +00:00
|
|
|
client_config_cleanup(&cfg);
|
2014-09-10 15:10:53 +00:00
|
|
|
if(rc == 2){
|
|
|
|
/* --help */
|
|
|
|
print_usage();
|
|
|
|
}else{
|
|
|
|
fprintf(stderr, "\nUse 'mosquitto_pub --help' to see usage.\n");
|
|
|
|
}
|
2018-03-26 21:19:11 +00:00
|
|
|
free(buf);
|
2014-05-24 22:04:42 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
topic = cfg.topic;
|
|
|
|
message = cfg.message;
|
|
|
|
msglen = cfg.msglen;
|
|
|
|
qos = cfg.qos;
|
|
|
|
retain = cfg.retain;
|
|
|
|
mode = cfg.pub_mode;
|
|
|
|
username = cfg.username;
|
|
|
|
password = cfg.password;
|
|
|
|
quiet = cfg.quiet;
|
|
|
|
|
|
|
|
if(cfg.pub_mode == MSGMODE_STDIN_FILE){
|
|
|
|
if(load_stdin()){
|
|
|
|
fprintf(stderr, "Error loading input from stdin.\n");
|
2018-03-26 21:19:11 +00:00
|
|
|
free(buf);
|
2014-05-24 22:04:42 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}else if(cfg.file_input){
|
|
|
|
if(load_file(cfg.file_input)){
|
|
|
|
fprintf(stderr, "Error loading input file \"%s\".\n", cfg.file_input);
|
2018-03-26 21:19:11 +00:00
|
|
|
free(buf);
|
2014-05-07 22:27:00 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!topic || mode == MSGMODE_NONE){
|
|
|
|
fprintf(stderr, "Error: Both topic and message must be supplied.\n");
|
|
|
|
print_usage();
|
2018-03-26 21:19:11 +00:00
|
|
|
free(buf);
|
2014-05-07 22:27:00 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
mosquitto_lib_init();
|
|
|
|
|
2014-05-24 22:04:42 +00:00
|
|
|
if(client_id_generate(&cfg, "mosqpub")){
|
2018-03-26 21:19:11 +00:00
|
|
|
free(buf);
|
2014-05-24 22:04:42 +00:00
|
|
|
return 1;
|
2014-05-07 22:27:00 +00:00
|
|
|
}
|
|
|
|
|
2014-05-24 22:04:42 +00:00
|
|
|
mosq = mosquitto_new(cfg.id, true, NULL);
|
2014-05-07 22:27:00 +00:00
|
|
|
if(!mosq){
|
|
|
|
switch(errno){
|
|
|
|
case ENOMEM:
|
|
|
|
if(!quiet) fprintf(stderr, "Error: Out of memory.\n");
|
|
|
|
break;
|
|
|
|
case EINVAL:
|
|
|
|
if(!quiet) fprintf(stderr, "Error: Invalid id.\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
mosquitto_lib_cleanup();
|
2018-03-26 21:19:11 +00:00
|
|
|
free(buf);
|
2014-05-07 22:27:00 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2014-05-27 20:48:32 +00:00
|
|
|
if(cfg.debug){
|
2014-05-07 22:27:00 +00:00
|
|
|
mosquitto_log_callback_set(mosq, my_log_callback);
|
|
|
|
}
|
|
|
|
mosquitto_connect_callback_set(mosq, my_connect_callback);
|
|
|
|
mosquitto_disconnect_callback_set(mosq, my_disconnect_callback);
|
|
|
|
mosquitto_publish_callback_set(mosq, my_publish_callback);
|
|
|
|
|
2014-05-24 22:04:42 +00:00
|
|
|
if(client_opts_set(mosq, &cfg)){
|
2018-03-26 21:19:11 +00:00
|
|
|
free(buf);
|
2014-05-24 22:04:42 +00:00
|
|
|
return 1;
|
2014-05-07 22:27:00 +00:00
|
|
|
}
|
2014-05-24 22:04:42 +00:00
|
|
|
rc = client_connect(mosq, &cfg);
|
|
|
|
if(rc) return rc;
|
2014-05-07 22:27:00 +00:00
|
|
|
|
|
|
|
if(mode == MSGMODE_STDIN_LINE){
|
|
|
|
mosquitto_loop_start(mosq);
|
|
|
|
}
|
|
|
|
|
|
|
|
do{
|
|
|
|
if(mode == MSGMODE_STDIN_LINE){
|
|
|
|
if(status == STATUS_CONNACK_RECVD){
|
2015-10-11 21:55:54 +00:00
|
|
|
pos = 0;
|
|
|
|
read_len = buf_len;
|
|
|
|
while(fgets(&buf[pos], read_len, stdin)){
|
|
|
|
buf_len_actual = strlen(buf);
|
|
|
|
if(buf[buf_len_actual-1] == '\n'){
|
|
|
|
buf[buf_len_actual-1] = '\0';
|
2015-12-18 22:26:01 +00:00
|
|
|
rc2 = mosquitto_publish(mosq, &mid_sent, topic, buf_len_actual-1, buf, qos, retain);
|
2015-10-11 21:55:54 +00:00
|
|
|
if(rc2){
|
|
|
|
if(!quiet) fprintf(stderr, "Error: Publish returned %d, disconnecting.\n", rc2);
|
|
|
|
mosquitto_disconnect(mosq);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}else{
|
|
|
|
buf_len += 1024;
|
|
|
|
pos += 1023;
|
|
|
|
read_len = 1024;
|
2018-03-26 21:19:11 +00:00
|
|
|
buf2 = realloc(buf, buf_len);
|
|
|
|
if(!buf2){
|
|
|
|
free(buf);
|
2015-10-11 21:55:54 +00:00
|
|
|
fprintf(stderr, "Error: Out of memory.\n");
|
|
|
|
return 1;
|
|
|
|
}
|
2018-03-26 21:19:11 +00:00
|
|
|
buf = buf2;
|
2014-05-07 22:27:00 +00:00
|
|
|
}
|
2015-10-11 21:55:54 +00:00
|
|
|
}
|
|
|
|
if(feof(stdin)){
|
2018-01-22 17:52:56 +00:00
|
|
|
if(last_mid == -1){
|
|
|
|
/* Empty file */
|
|
|
|
mosquitto_disconnect(mosq);
|
|
|
|
disconnect_sent = true;
|
|
|
|
status = STATUS_DISCONNECTING;
|
|
|
|
}else{
|
|
|
|
last_mid = mid_sent;
|
|
|
|
status = STATUS_WAITING;
|
|
|
|
}
|
2014-05-07 22:27:00 +00:00
|
|
|
}
|
|
|
|
}else if(status == STATUS_WAITING){
|
|
|
|
if(last_mid_sent == last_mid && disconnect_sent == false){
|
|
|
|
mosquitto_disconnect(mosq);
|
|
|
|
disconnect_sent = true;
|
|
|
|
}
|
|
|
|
#ifdef WIN32
|
|
|
|
Sleep(100);
|
|
|
|
#else
|
2018-04-05 23:33:22 +00:00
|
|
|
struct timespec ts;
|
|
|
|
ts.tv_sec = 0;
|
|
|
|
ts.tv_nsec = 100000000;
|
|
|
|
nanosleep(&ts, NULL);
|
2014-05-07 22:27:00 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
rc = MOSQ_ERR_SUCCESS;
|
|
|
|
}else{
|
|
|
|
rc = mosquitto_loop(mosq, -1, 1);
|
|
|
|
}
|
|
|
|
}while(rc == MOSQ_ERR_SUCCESS && connected);
|
|
|
|
|
|
|
|
if(mode == MSGMODE_STDIN_LINE){
|
|
|
|
mosquitto_loop_stop(mosq, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(message && mode == MSGMODE_FILE){
|
|
|
|
free(message);
|
|
|
|
}
|
|
|
|
mosquitto_destroy(mosq);
|
|
|
|
mosquitto_lib_cleanup();
|
|
|
|
|
|
|
|
if(rc){
|
|
|
|
fprintf(stderr, "Error: %s\n", mosquitto_strerror(rc));
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|